看到有道题,问 常见的缓存更新策略,当时很懵,不知道啥叫缓存更新策略,只知道自己的项目的缓存更新策略,不知道这叫什么模式,也不知道还有什么其他模式,现记录下来。
常见的缓存更新策略有三种:
cache aside
一般用的都是这种方式
流程:查询时:如果命中缓存,返回缓存结果,如果未命中缓存,则查数据库,同时更新缓存
修改时:直接修改数据库,并设置缓存失效
分析:
1. 这种方式会不会造成数据不一致或者脏数据的问题?
会,但是可能性很低。
出现问题的步骤是:一个读请求过来,没有查到缓存,然后去查数据库,读到a=1,但还没有更新缓存,这时另一个写请求过来,更改了要查的内容,a=2,并删除了缓存,然后
读请求才更新缓存,把缓存内容更新为1,这是导致了数据不一致。但是这种情况一般会比较少,因为读请求一般都要比写请求快很多,不太可能读请求先来,但是还没读完,后来的写请求已经写完了并删除了缓存。(我的想法:如果缓存更新条件比较复杂,需要很长时间的处理才能更新,是不是也有可能出现这种情况呢?)
2. 为什么更新完删除缓存,而不是更新缓存?
1. 数据库并发写请求,有可能造成脏数据。请求1和2都是写请求,更新同一个数据。请求1先完成,请求2后完成,这时数据库的结果是请求2的结果。但请求1更新缓存的操作如果晚于请求2,那缓存就会被更新省请求1的执行结果
2. 在缓存更新比较复杂的情况下,如果更新的缓存不是热点数据,更新的意义就不大,不如放到请求时更新
read/write through
流程:查询时: 当缓存失效的时候,由缓存服务自己更新缓存。与cache aside相比,缓存失效后,cache aside需要有查询请求的时候才更新,read through是自己更新
更新时:如果没有命中缓存,则直接更新数据库,如果命中了缓存,则直接更新缓存,再由缓存更新数据库
优点是对于应用来说,可以认为后端只有一个单一的存储。缺点是数据写入速度较慢(同时需要写入缓存和存储)
writebehind caching
流程: 更新时只更新缓存,根据一定的策略把缓存的数据刷到数据库。
优点是数据的I/O操作快,缺点是复杂,数据不是强一致性的,数据可能丢失