如果在高并发修改的场景,会存在redis和MySQL数据不同步的问题。
比如,修改某个商品的价格,
第一种情况:
可以先把缓存删掉,然后修改MySQL商品价格。然鹅,MySQL商品价格还没来得及修改,另外一个读商品的请求过来了,redis没读到,就会读MySQL的老数据,并加载到redis。过了一会,第一个请求把MySQL的商品价格修改成功了,就会导致两边数据不一致的情况。
第二种情况:
先修改MySQL商品价格,再删缓存,MySQL价格修改了,缓存删除失败了,就会导致不一致的情况。
解决方案:
- 延时双删:delete key -> update MySql -> thread.sleep(1s) -> delete key
- 设置过期时间 -> update MySql -> delete key
- binlog同步到redis
- 加分布式锁
- 事务框架处理
对方案1的理解:
请求1先删除key,另外一个读请求,2进来了,发现没有缓存,就去从MySQL获取老数据,并加载到redis,这时请求1把MySQL更新了,然后再次删除缓存。为什么还要加个延时呢,因为存在这样一种情况,请求2去加载缓存之前,请求1已经删除了缓存,所以要等待至少完成一次读的时间,同时也得考虑redis和数据库主从同步(读从从库读)的耗时,一般几百ms,等待这两个时间之和再完成key的delete。
对方案2的理解:
这个就好说了,先把这个k