redis-保证和数据库的一致性

如何保证redis和数据库的一致性?

cache Aside pattern

读取的时候,先从缓存读,读不到就读数据库,然后取出数据之后写入到缓存;
更新的时候,先删除缓存,再更新数据库。

为啥不是更新缓存?
如果缓存的计算逻辑比较复杂(比如要关联表计算什么的),而且写的频率大于读的频率,那么更新缓存就不是很划算啦。

为什么要先删除缓存,在更新数据库?
如果先更新数据库,再删除缓存,那么如果删除失败了,就会导致缓存里是旧数据,数据库里是新数据。
如果删了缓存,更新数据库失败了,那么也无非是多更新一次缓存。

读写并发导致的数据库缓存双写不一致的问题。

如果在删除缓存之后,读缓存和写数据库发生并发,而缓存被更新成了旧的值,也会导致数据不一致问题。
低并发的情况,很少会出现这种情况;
但是高并发以后,这个问题就很常见了。
redis-保证和数据库的一致性

如何解决上述问题?

先写后读,利用队列进行串行处理请求。

压请求的时候,可以做去重操作。轮询一下,如果有读请求可以拿到值了,那么直接就访问缓存就可以。也要设置一个超时时间,如果超过了这个时间,就去读旧值了。
redis-保证和数据库的一致性
该方案的导致的问题:
1、读请求会堵塞。
在压读请求到队列中的时候,首先判断队列当前有没有写请求,如果没有,就证明该数据也不存在在数据库里,直接返回就好。
如果内存队列里有写操作,hang一会,如果超时了,就返回旧的数据吧。
2、读请求并发量过高。
写个循环,如果一旦缓存更新了,所有的读请求都不再压在队列里,直接请求缓存。
3、确保对同一份数据,读写可以路由到同一个机器上。