缓存策略

思考题
Cache Aside 模式如何产生脏数据?


首先 Cache Aside 这种模式和 Read/Write Through 模式的读取操作一样,都是先尝试读缓存,如果命中直接返回;未命中的话读数据库,然后更新缓存。
写操作不是更新缓存,而是把缓存中的数据删掉
那怎么出现脏数据?
假设有下面两个线程对 key 分别进行读写操作
读线程 t1
写线程 t2
按照下面的流程进行操作
1. t1 读缓存未命中,然后从数据库中读到 value1
2. t2 更新 key 为 value2,并尝试删缓存(此时缓存中并没有)
3. t1 把从 db 中读到的 value1写回缓存

这时 db 中 key 的 value 为新数据 value2,缓存中为旧数据 value1,产生了不一致。
这种情况只发生在读线程从 bd 读到旧数据往 cache 中写前,有写线程更新了 db,然后读线程把老数据写回 cache


Read/Write Through 发生脏数据的情况
第一种情况是并发读写
对 key 进行读写的两个线程
读线程 t1
写线程 t2

按照如下时间顺序操作
1.t1 尝试读缓存但未命中,然后去 db 中读取到了数据 value1,但还未更新缓存兄弟的数据
2. t2 更新数据库 value2,更新成功后常识读取缓存,未命中,所以更新缓存为 value2
3.t1 线程继续把之前从 db 中读到的旧数据 value1 写回缓存
这样 db 中是新数据,但缓存中是旧数据

第二种情况是并发写
这种情况是db 中产生了 ABA 问题
比如有两个写线程 t1,t2,分别按下面的先后顺序操作
1.t1 尝试把 key 更新为 value1,但响应丢失
2.t2 尝试把 key 更新为 value2,还未响应结果
3.t1 发生重试操作
4.t2 响应成功
5.t1 响应成功
本来写应该按先后顺序的,t2后到,数据库和缓存中应该是 value2,但因为 t1 发生了重试,导致数据库和缓存中是 value1了,产生了ABA问题,解决办法是在更新时加上 version 版本号判断

所以没啥万能的方法,需要根据业务场景来制定方法

你可能感兴趣的:(架构)