持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
我有个朋友最近面试被问到缓存一致性问题,只会背先删除缓存再更新数据再删除缓存,那可不行,这道题起码得吹个十多分钟。
啥是缓存,缓存就是因为磁盘速度太慢了中间加一层更快的东东,目的是更快的进行数据的读取,既然加了缓存那么读请求就全部走缓存。至于写的话一般有三种方案,先更新缓存再异步落盘、缓存和磁盘双写、先更新磁盘再更新缓存。
先更新缓存再异步落盘
这个方案只要数据更新到缓存就算更新成功之后再异步将缓存和不断落盘,就是写入缓存后自己想办法刷到磁盘,这个方案性能更高,而且不要求,因为读写都是在缓存中,但是当没完全从缓存同步落盘时宕机那么就会数据丢失,像数据库产品,操作系统的page cash缓存就喜欢用这个方案,因为这个方案可以获取很高的性能收益,缺点就是没落盘宕机导致数据丢失,那么想办法解决掉,比如像MySQL就通过redo日志保存缓存种修改的位置后先将redo日志顺序写快速落盘,牺牲一点性能来进一步保证数据的不丢失。
缓存和磁盘双写
即数据同时成功写入缓存和落盘成功才算成功,操作系统页缓存每次修改都进行刷新等,既然是同时那么更新操作的落盘和写缓存必须是原子的否则多线程会出现脏数据问题,但是插入操作就不会只是会出现顺序如果不关心顺序那么可以不用理会。这个方案不会有数据丢失问题,但是每次都写磁盘,严重影响写的速度。
脏数据问题举例子
正常时这样的
1、线程1将缓存里的数据改成A
2、线程1将磁盘里的数据改成A
现在缓存和磁盘里的数据都是A
但是当多个线程并发时就出现
1、线程1将缓存里的数据改成A
2、线程2将缓存里的数据改成B
3、线程2将磁盘里的数据改成B
4、线程1将磁盘里的数据改成A
这时候缓存里的数据时B,磁盘的数据时A,就有问题了
先更新磁盘再更新缓存
就是先保证数据已经落盘就算成功,也就是写入磁盘后自己想办法更新缓存。这种方案就是写在磁盘读在缓存,读写分离。业务开发中最常用的就是这个方案,保证数据落盘后,读取到缓存加快读的速度,但是这个方案会存在一定的延迟问题。根据CAP理论一定会存在延迟问题的,只是要通过一些手段去牺牲可用性来消除一些延迟,做权衡达到业务需求即可。
何为CAP理论?
C是一致性指的是所有节点的数据是一致的,在所有节点中读取的数据都是正确的。
P是分区容错性指的是部署多个节点在不同的子网中 ,并且节点之间断开联系的情况下也能提供服务。
A是可用性指的是任何事物都能得到响应结果不会出现超时错误等响应,重点在用户访问的体验上,不管什么情况请求了就必须返回。
一个系统不可能CAP同时满足的,需要在CAP中做取舍
应用
一般业务中使用的都是第三种方式,以redis作为MySQL缓存举例子,一般都要保证数据成功写入MySQL再考虑缓存的事情。而且对缓存的同步更新一般是删除缓存而不是更新缓存,因为更新后有可能缓存不命中了,白白占用内存。
那么业务中时是先更新数据库后更新缓存的,由上述可以,这种方案不可能强一致的,那么一般通过哪些手段去处理数据不一致问题达到最终一致性的呢?
-
更新数据库后再去删除缓存。更新成功后再进行缓存的刷新,这种方案在更新完数据库后没有删除缓存过程中数据会不一致。这是最原始的方案会出现上述脏数据问题。
-
定时去更新缓存。一般更新频率低的数据,而且可以接受一定时间的不一致问题可以使用该方法,包括设置缓存的过期时间之后读取不到缓存时再去数据库读取到缓存中或者定时任务去刷新缓存等。这种方案没刷新之前数据被更新会导致缓存和数据库在一个定时周期内不一致性。
-
先删除缓存再更新数据库再删除缓存。第一次删除缓存后马上一个读请求,读到缓存还在更新的前面而且在第二次删除之后写入缓存,也会存在不一致问题,不过因为一般读比写快所以会在第二次删除之前写入就不成问题,所以一般难于出现。
-
延迟双删。即先删除缓存再更新数据库,然后延迟一定的时候保证在删除之后的读请求完成后再次删除缓存。不过延迟时间的把握比较难,太短就没效果,太长影响性能和不一致的时间过长。
总结
引入缓存后对于数据的更新有多种方案,要么更新缓存然后异步更新落盘保证缓存得到更新,操作系统的页缓存、MySQL缓存等就是使用这个方法,这种方法会导致没落盘宕机数据丢失问题,要么同时落盘和写缓存两个都保证更新,操作系统页缓存也可以设置这个模式,因为更新操作落盘和写缓存必须是原子的否则多线程会出现不一致问题但是插入操作不会,要么先落盘再异步更新缓存保证落盘,但会存在缓存更新延迟问题。 因为业务做缓存一般选用第三种方案,因为需要保证落库而且为了简单业务中一般通过更新数据库后再去删除缓存、定时去更新缓存、先删除缓存再更新数据库再删除缓存、延迟双删等手段进行数据同步到缓存。不同的手段最终一致性的延迟大小不同,并且通过该方案去更新缓存多线程环境下会有缓存数据不一致问题,这些条件发生不一致的概率也不同,需要根据业务去做权衡选择。