Redis缓存和数据库一致性
先更新数据库然后删除缓存,如果删除缓存失败,会导致数据库中是新数据,缓存中是旧数据,数据就出现了不一致。一般解决方案有两个:
先删除缓存,然后更新数据库。即使数据库更新失败,数据库中还是旧数据,缓存是空的。读的时候缓存没有,就去读数据库中的旧数据,然后更新到缓存。
延时双删,先更新数据库,再删除缓存,5s之后再执行一次删除操作。
public void set(key, value) {
putToDb(key, value);
deleteFromRedis(key);
// ... a few seconds later
deleteFromRedis(key);
}
有一个请求过来对数据进行变更操作,先删除缓存,然后修改数据库,数据库数据没修改完之前又过来一个请求,去读缓存,发现缓存空了,然后查询数据库,查到了修改前的旧数据,放到了缓存中,然后第一个请求完成了对数据库的修改,此时就造成数据库和缓存中的数据不一样的情况。
分析:数据并发进行读写的时候才可能出现这种问题,如果并发量很低,特别是读并发,每天访问量就1万次,很少的情况下会出现这种不一致的场景。如果每天是上亿的流量,每秒并发读是几万,每秒只要有数据更新的请求,就可能会出现数据库+缓存不一致的情况。
解决方案:更新数据的时候根据数据的唯一标识,将缓存更新的请求发送到一个jvm内存队列中,然后同步等待缓存更新完成。一个数据变更的操作,先删除缓存,然后再去更新数据库,但是还没完成更新