缓存一致性问题(Cache Coherency)
引言
现在越来越多的系统都会用到缓存,只要使用缓存就可能涉及到缓存数据与数据库数据之间双写双存储,只要双写就会遇到数据一致性的问题,除非只有一个数据库服务器,数据一致性问题也就不存在了。
缓存的作用
1. 临时存储,用于提高数据查询速度。
比如CPU的L1高速缓存和L2高速缓存,缓存主要是为CPU和内存提供一个高速的数据缓存区域。CPU读取数据的百顺序是:先在缓存中寻找,找到后就直接进行读取,如果未能找到,才从主内存中进行读取。
2. 降低系统反应时间,提高并发能力。
数据一致性的问题的原因
主要是由于两次操作时间不同步导致的数据一致性问题。比如Mysql主从复制到时候,master数据在同步slave给数据到过程中会有数据不一致的时刻。
如何保证缓存与数据库双写一致性
一. 缓存与数据库读写模式(Cache aside pattern)
分两种情况,读数据和写数据(更新)
1. 读数据:读数据时候先读取缓存,如果缓存没有(miss hit)就读取数据库,然后在从数据库中取出数据并添加到缓存中,最后在返回数据给客户端。
2. 更新数据: 先更新数据库数据在删除缓存(也有人认为先删除缓存在更新数据库)。
那么为什么在更新数据库同时在删除缓存呢?
这里主要考虑几个点:
1)缓存懒加载。
有些缓存出来的数据是应用在比较复杂的场景中,这些缓存存在的时候,不是简单的从数据库取出数据,比如更新了数据表中某个字段的值,有一条缓存数据值是这个字段的值与另外多个表中字段的值进行计算后的结果,当每次该字段被更新的时候都要与其他表多个字段去运算然后得到这个缓存数据,所以这样场景下更新缓存的代价很高。
所以要不要实时更新缓存视具体情况来定,比如这个字段一分钟内修改60次,那么跟该字段相关缓存也跟着要计算60次,但是该缓存一分钟内只被访问1次,当缓存真正被访问的时候在进行计算,这一分钟内缓存只计算了一次,开销就大幅减少。就里其实也涉及到懒加载(Lazy)的一个思想,所以说如果不是热点缓存数据只有在它需要的时候在重新进行计算。
2)高并发访问缓存