1. 什么是缓存更新策略
缓存更新策略是Redis的为了节省内存而设计出来的一种东西,主要是因为内存数据宝贵,当我们向redis插入数据过多,或导致内存中缓存的数据太多,所以redis会对部分数据进行更新,或者把它叫为淘汰更合适。
常见的缓存更新策略有以下三种
| 内存淘汰 | 超时剔除 | 主动更新 |
---|
说明 | 内存淘汰是Redis内部的一种淘汰机制,当内存不足的时候自动淘汰部分数据。这种机制不需要自己维护,被淘汰的数据在下次查询的时候更新缓存。 | 给缓存数据添加TT了时间,到期后Redis自动删除缓存数据。被淘汰的数据在下次查询时候更新缓存 | 通过业务逻辑代码,在修改数据库的数据的同时,更新缓存 | 一致性 | 差 | 一般 | 好 | 维护成本 | 无 | 低 | 高 |
2. 解决数据库与缓存数据不一致
缓存的数据来源于数据库的数据,但是数据库的数据可能会经常发生改变,而缓存的数据没有及时同步数据库中的数据,就会导致数据库中的数据与缓存的数据不一致
要想解决这种问题,有以下几种解决方案
- 在对数据库的数据进行更新之后,同时更新缓存中的数据,这种方案称为双写方案
- 另开一个服务,由服务维护统一性,调用者调用该服务,无需关心缓存一致性问题
- 另开一个线程,调用者只需要操作缓存,然后由其他线程异步将缓存中的数据持久化到数据库中,保持一致性
综合考虑,第一种方案比较好,既不用另开服务,又不用另开线程,节约了资源
使用双写方案的话,也会出现下面的问题:
- 是删除缓存还是更新缓存?
- 先操作缓存还是先操作数据库?
对于第一个问题,可以做出以下分析。
首先,对于更新缓存,可能会出现无效更新,从而浪费资源。也就是说A线程将数据A改成了数据B,接着也更新了缓存中的数据,修改完之后A觉得不满意,将数据A再次改成C,再次更新缓存的数据。
对于这种情况,有效的更新应该是数据A->C,中间的过程是无效的,无效的更新无疑是会增加redis的写压力。
接着,对于删除缓存,当要更新数据库数据的时候,更完之后将缓存中的数据删除,当下次需要查询这些数据的时候,缓存肯定没有命中,这时候查询数据库,再将数据缓存到数据库中。
综上所述,删除缓存比更新缓存更好。
而对于第二个问题,可以作出以下分析。
首先,说说先删缓存再操作数据库,线程A删除缓存,这时候线程B过来发现缓存没有命中,于是查数据库,这时候线程A还没完成更新操作,那么线程B拿到的就是旧数据,并将旧数据缓存到redis中,因此会导致后面的线程拿到的都是旧数据,更新无效。
接着,假如先操作数据库再删缓存呢,假如这时候线程A进来,Redis缓存的数据刚好过期,那么线程A查询缓存未命中,那么就需要查询数据库拿到数据V0,这时候线程B进来更新数据库数据成V1,接着删缓存,这时候线程A将查到的数据V0写进缓存,同样导致后面的数据拿到的是旧数据,更新无效。
综上所述,应该先操作数据库再操作缓存。这是因为缓存的操作比数据库的更新要快,因为缓存是基于内存的,线程A完成写入缓存操作的时候,线程B可能都还没修改完数据库的数据,因此出现上面那种极端情况的概率比较低。
引用:黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目
|