1、强一致性
如果要保证redis和数据库强一致性,那就要加锁。主要就是读写锁,读的时候不加锁,写的时候加锁。可以用redisson实现的读写锁。如果有一个线程在重新建立redis缓存,那么查询都阻塞。这样每次跟新数据,redis都会更新成最新的。
2、最终一致性
这个性能高,只要保证最后是一致的就行。通常的解决办法是通过中间件,比如mq,更新了就丢mq一条数据,然后消费数据更新redis。这样在极短的时间里会查询到旧数据,但是没有锁。
3、延迟双删,来保证一致性。并不靠谱
先删除缓存,再删除数据库。删除缓存后,还没来及的更新数据库,另一个线程来查询,又更新成了数据库旧数据,所以会出现脏数据。redis没更新。
先更新数据库,再删除缓存。一个线程查询缓存没有,准备更新缓存,已经查完数据库了,旧内容,但是还没请求redis。这个时候另一个线程要更新数据库,删缓存。执行完后第一个线程更新的redis还是老数据。
所以在这里,引入了双删,不管是先删缓存还是数据库,都要在执行完后。过一段时间再删除一次redis。这样保证真的获取到更新的数据。这个延迟时间不好控制,反正我是不会用了。