Redis做为目前互联网标配的技术中间件,在缓存数据库(K-V)占有市场率一直雄霸榜首。不管是传统项目重构,还是现在流行的分布式微服务架构,它都有广泛应用。
物联网系统????
传统项目网优系统重构????
而且自从Redis 6.*版本正式发布,里面包含多项重大功能更新使其性能又进一步大幅度提升。更加巩固了它在缓存数据库的“一哥”地位。
它在架构中最基本的用法,是分担数据压力,提升并发量与用户感知度。
比如:通过以下的架构,将部分非事务的操作、高频展示信息、静态信息等存放在Redis(用户基本信息、权限信息、区域信息、库存等)。
用户请求数据时,会先从Redis获取,如果Redis有,就直接返回,如果Redis没有,再从数据库里获取,并缓存一份至Redis,下次用户再请求时,就不用访问数据库,节省宝贵的数据库资源,并提升用户的感知度(什么操作和硬盘打交道多了,肯定快不起来)。
这时,大厂高频面试题来了,数据是从数据库复制到Redis中的,查询的时候一切安好,如果此时数据发生了变化,如何保证两者的数据一致性?请结合你的项目经验进行阐述。
问题我详细地描述一下:数据在Redis和MySQL都存储了一份,那你在更新数据时,怎么保证两边的数据一致?先更新数据库,再更新Redis?如下图所示:
-
步骤1:线程1更新MySQL,库存=100
-
步骤2:线程1更新Redis,库存=100
-
步骤3:线程2更新MySQL,库存=90
-
步骤4:线程2更新MySQL,库存=90
有并发线程1和2,他们两都需要更新库存,如果此时命令执行顺序按照预期行为走了,好像没什么问题。
但是,如果在远程调用过程中,网络出了问题(抖动、超时、阻塞等)呢?如下图所示:
-
步骤1:线程1更新MySQL,库存=100
-
步骤2:线程2更新MySQL,库存=90
-
步骤3:线程2更新Redis,库存=90
-
步骤4:线程1更新MySQL,库存=100
发现问题所在了吧,数据不符合基本逻辑了,这时候在Redis获取的数据是错的,和数据库的信息不一致(数据库中是90,而Redis中是100)。
当操作序列没有严格按照请求的先后顺序执行时,会引发并发安全问题。
没错,这就是在架构使用Redis必须考虑的数据一致性解决方案,你有思路么?以下方案你能回答出几种?
-
懒加载;
-
延迟双删;
-
操作队列,使用锁;
-
设置超时时间;
-
引入其他中间件,Canal。
如果我告诉上面的方案,都行!我想继续和你聊聊你的实际应用场景是什么?你还有思路么?
Redis作为现在互联网企业的标配技术栈,在使用它给我们带来便利的同时,它还会给我们带来很多问题,数据一致性只是其中一个,除此之外,以下问题你又有考虑到么?
-
缓存击穿、缓存穿透、缓存雪崩你如何解决?
-
数据倾斜,冷热数据分离怎么考虑?
-
内存淘汰你如何考虑?
-
分布式锁的高可用方案你如何考量?
-
Redis的性能优化你如何实现?
-
epoll底层实现细节
-
Redis 6.*新版本特性
等等,这里就不一一例举了。
上面的问题听过没见过,一知半解,又或者不知道如何和实战结合?没关系。为了让大家搞明白Redis在大厂的实战场景以及它的底层实现细节(面试极爱问)。