MySQL 作为 DB ,Redis 作为缓存,两个系统会存在一致性问题,最近想到一个方案, 大家说说这种方案有什么优缺点?
写过程:
- 先抢锁( lua 搞):redis.setnx(lock_key)
1.1 失败则自旋直至抢到成功
1.2 成功,根据更新数据库所需时间设置过期时间,然后进入 2 - 更新数据库:db.update()
- redis.set(data_key)
- redis.del(lock_key)
读过程(根据业务下面 3 选 1 ):
- 能接受旧数据的业务,则直接读缓存,redis.get(data_key)。
- 要求读到最新数据的业务,则先读 redis.get(lock_key ),如果为空则 redis.get(data_key)返回;不为空则直接读数据库,然后再 redis.setnx(data_key),也就是如果这里存在 data_key 则不设置缓存了。
- 上面 2 的过程 redis.get(lock_key)和 redis.get(data_key)之间可能存在其他的写过程,且刚好执行到 2 ,这时候仍可能读到旧数据。所以,这里可以同样先抢锁,redis.setnx(lock_key),抢到锁再 redis.get(data_key),为空则回源数据库然后再设到 redis 。