Redis做为目前互联网标配的技术中间件,在缓存数据库(K-V)占有市场率一直雄霸榜首。不管是传统项目重构,还是现在流行的分布式微服务架构,它都有广泛应用。

物联网系统????

​Redis的各种“坑”,你知道多少?_java

传统项目网优系统重构????

​Redis的各种“坑”,你知道多少?_java_02

而且自从Redis 6.*版本正式发布,里面包含多项重大功能更新使其性能又进一步大幅度提升。更加巩固了它在缓存数据库的“一哥”地位。

​Redis的各种“坑”,你知道多少?_redis_03

它在架构中最基本的用法,是分担数据压力,提升并发量与用户感知度。

比如:通过以下的架构,将部分非事务的操作、高频展示信息、静态信息等存放在Redis(用户基本信息、权限信息、区域信息、库存等)。

​Redis的各种“坑”,你知道多少?_java_04

用户请求数据时,会先从Redis获取,如果Redis有,就直接返回,如果Redis没有,再从数据库里获取,并缓存一份至Redis,下次用户再请求时,就不用访问数据库,节省宝贵的数据库资源,并提升用户的感知度(什么操作和硬盘打交道多了,肯定快不起来)。

这时,大厂高频面试题来了,数据是从数据库复制到Redis中的,查询的时候一切安好,如果此时数据发生了变化,如何保证两者的数据一致性?请结合你的项目经验进行阐述。

问题我详细地描述一下:数据在Redis和MySQL都存储了一份,那你在更新数据时,怎么保证两边的数据一致?先更新数据库,再更新Redis?如下图所示:

​Redis的各种“坑”,你知道多少?_redis_05

  • 步骤1:线程1更新MySQL,库存=100

  • 步骤2:线程1更新Redis,库存=100

  • 步骤3:线程2更新MySQL,库存=90

  • 步骤4:线程2更新MySQL,库存=90

有并发线程1和2,他们两都需要更新库存,如果此时命令执行顺序按照预期行为走了,好像没什么问题。

但是,如果在远程调用过程中,网络出了问题(抖动、超时、阻塞等)呢?如下图所示:

​Redis的各种“坑”,你知道多少?_数据库_06

  • 步骤1:线程1更新MySQL,库存=100

  • 步骤2:线程2更新MySQL,库存=90

  • 步骤3:线程2更新Redis,库存=90

  • 步骤4:线程1更新MySQL,库存=100

发现问题所在了吧,数据不符合基本逻辑了,这时候在Redis获取的数据是错的,和数据库的信息不一致(数据库中是90,而Redis中是100)。

当操作序列没有严格按照请求的先后顺序执行时,会引发并发安全问题。

没错,这就是在架构使用Redis必须考虑的数据一致性解决方案,你有思路么?以下方案你能回答出几种?

  1. 懒加载;

  2. 延迟双删;

  3. 操作队列,使用锁;

  4. 设置超时时间;

  5. 引入其他中间件,Canal。

如果我告诉上面的方案,都行!我想继续和你聊聊你的实际应用场景是什么?你还有思路么?

Redis作为现在互联网企业的标配技术栈,在使用它给我们带来便利的同时,它还会给我们带来很多问题,数据一致性只是其中一个,除此之外,以下问题你又有考虑到么?

  • 缓存击穿、缓存穿透、缓存雪崩你如何解决?

  • 数据倾斜,冷热数据分离怎么考虑?

  • 内存淘汰你如何考虑?

  • 分布式锁的高可用方案你如何考量?

  • Redis的性能优化你如何实现?

  • epoll底层实现细节

  • Redis 6.*新版本特性

    等等,这里就不一一例举了。

上面的问题听过没见过,一知半解,又或者不知道如何和实战结合?没关系。为了让大家搞明白Redis在大厂的实战场景以及它的底层实现细节(面试极爱问)。