redis缓存同步小伎俩

redis做缓存分为被动和主动两种,今天要说的是被动+主动结合的一个小伎俩。

主动+被动结合,有2种常见做法:

  • set流派
    • 查询时,先查redis,不命中再查mysql,将结果set到redis里缓存TTL时间
    • 更新时,先更新mysql,再set到redis里缓存TTL时间
  • delete流派
    • 查询流程同上
    • 更新时,先更新mysql,再去redis里做delete删除掉缓存

set流派适合应付读热点的场景,不希望因为delete造成缓存穿透,影响到性能。

delete流派比较平庸,没有太密集的热点读压力,偏向于海量冷数据的被动缓存,删除的性价比更高。

小伎俩

今天的小伎俩与set流派有关,主要指出一个并发竞争的case。

考虑如下的时序:

  • 查询:redis miss,于是查询了mysql得到数据A。
  • 更新:mysql数据修改为B,同时set到Redis中。
  • 查询:通过set 命令将A更新到redis中。

结局:缓存里cache了一份老数据A。

对于缓存一致性要求高的业务是无法接受这种竞争的,即便没有很高的缓存一致性要求,一般业务也不希望这种事情出现。

解决方法,查询时使用setnx命令(set if not exist)取代set,同理可以用hsetnx取代hset,不同数据结构均有对应方法。

 

 

发表评论

电子邮件地址不会被公开。