当我们对数据进行修改的时候,到底是先删缓存还是先写数据库?
一、如果先删缓存,在写数据库:高并发下,当A线程删除了缓存,还没有来得及写数据库,B线程来读取数据,发现缓存为空,就到DB中,那就会读取脏数据(旧值),读完之后,B还会把旧值写入到缓存中(此时A已经将新的值写入到缓存中),这样缓存中的值就会被脏数据覆盖
解决方案:1.先操作缓存,但不要删除缓存。将缓存修改为一个特殊值(-999).客户端读取数据,发现是默认值,就休眠一会,再查redis。特殊值对业务有侵入,休眠时间可能会对此重复,影响性能 2.延时双删。先删除缓存,然后写数据库,休眠一会,再删除缓存。(避免在A写数据库之前,B读取DB数据,写到缓存中,这样缓存和数据库数据就不一致了)。?问题:如果数据写操作频繁,同样还会有脏数据的问题 "并发高可以,写操作不要太频繁"
二、先写数据库,在删缓存:如果数据库写完之后,缓存失败了,数据就会不一致
解决方案:1.给缓存设置一个过期时间 问题:过期时间内,缓存数据不会更新 2.引入MQ,保证原子性。原理:发一个指令给MQ,起两个消费者分别操作reids和DB,如果操作redis失败,MQ会有一个重试机制,再次操作redis 3.将热点数据设置为永不过期,但是在value当中写入一个逻辑上的过期时间,另起一个后台进程,扫描这些key,对于逻辑上的过期缓存,进行删除