以下三种读写策略都是Redis主动更新缓存的策略,即更新数据库时就更新缓存,除了主动更新,还有内存淘汰、超时剔除两种。
内存淘汰:不用自己维护,利用Redis的内存淘汰机制,当内存不足时自动淘汰部分数据。下次查询时更新缓存。
优点:不需要人为操作
缺点:一致性差
超时剔除:给缓存数据添加TTL时间,到期后自动删除缓存。下次查询时更新缓存。
优点:编写代码较为简单,只需要设置TTL即可
缺点:一致性一般,取决于TTL长短
由此可知主动更新策略的优点是一致性好,但是编写代码比较复杂。
Cache Aside Pattern
最常用的读写策略,因为后面两种都不好用。但是我看JavaGuide和黑马的对这个策略的描述不太一样,所以我会两个都贴上。
黑马:对数据库进行更新的同时,也需要对Redis缓存进行更新,并且两个更新的操作都需要开发人员编写代码完成。
JavaGuide:服务端需要同时维系 db 和 cache,并且是以 db 的结果为准。
Cache Aside Pattern写操作:
更新数据库的内容
删除Redis缓存
为什么删除不更新?
可能存在一直更新不读的情况,不需要读Redis缓存。
为什么先更新后删除?
必须先更新数据库,再删除,虽然都可能存在线程安全性问题,但是因为对Redis操作效率高,所以如果先删除发送安全性问题概率大。
Cache Aside Pattern读操作:
读Redis缓存,如果命中则直接返回
不命中访问数据库,若数据库存在,则将数据放到Redis缓存,并返回对应数据
Read/Write Through Pattern
黑马:缓存与数据库整合为一个服务由服务来维护一致性。调用者调用该服务,无需关心缓存一致性问题。
JavaGuide:服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 db,从而减轻了应用程序的职责。
优点:
缺点:没有一款较好的工具可以将Redis缓存主动写入数据库。
Write Behind Pattern
黑马:调用者只操作缓存,由其它线程异步的将缓存数据持久化到数据库,保证最终一致。
JavaGuide:Read/Write Through 是同步更新 cache 和 db,而 Write Behind 则是只更新缓存,不直接更新 db,而是改为异步批量的方式来更新 db。
好处:效率高,可以将多次更新合并为一次更新
缺点:一致性差,维护成本高。