012 Redis 的并发竞争问题是什么?如何解决这个问题(分布式锁)?了解 Redis 事务的 CAS 方案吗(WATCH)?

读读Redis的官网,学第一手的资料:Redid官方文档地址

 Redis中国-文档网址:Redis中国-文档地址

或者看看书《Redis 深度历险: 核心原理和应用实践》


1、Redis 的并发竞争问题是什么?

看到这个标题,有人可能会有疑问了,redis不是单线程的吗,怎么还会有并发竞争问题?

其实是这样的,redis并发竞争是多个客户端并发写一个key,本来应该是先到的请求先写key,但可能由于网络环境差异,先发起的请求后到了,导致value最终被后发起的请求修改,最终数据错乱了。或者是多个客户端同时获取一个key,修改值后再写回去,只要顺序错了,数据纠错了。

图1 redis并发问题

现象:

客户端1修改库存为999,客户端2修改库存为998;客户端3修改库存为997。

我们期望的更新库存顺序树set inventory 1000 -> 999 -> 998 -> 997,但由于网络环境差异,影响了更新库存请求达到顺序。可能变成set inventory 1000 -> 999 -> 997 -> 998。期望的库存最终是997,但实际是998,导致数据最终出错。

2、解决方案:

解决这种问题的方案也很简单,就是用分布式锁。

当然了如果你系统缓存并发量很低,你的业务场景中不会出现并发竞争问题,就不要用分布式锁。

分布式锁是一个很重的解决方案,锁的本质是使并发的请求串行化执行,会大大的降低系统性能和吞吐量,所以在生成环境中,能不用就不用。

2.1 分布式锁常用的解决方案有两种:

1)基于redis,可以使用redisson框架使用;

2)基于zookeeper,可以使用curator框架使用;

两种解决方案怎么选型后面会专门讲解,这里就不细说了。

图2 基于分布式锁解决缓存并发更新问题

写入缓存的时候,同时把更新时间写到缓存里,同时每次要写缓存之前,先判断一下当前这个库存的时间戳是否比缓存里的时间戳要新。如果是的话,那么可以写,否则,就不能用旧的数据覆盖新的数据。

比如当前更新缓存库存时间是:10:00:02,现在三个客户端发起更新缓存,它们执行请求的时间分别是:

客户端1:10:00:01

客户端2:10:00:03

客户端3:10:00:04

客户端1的时间 < 缓存更新时间,所以就不更新,客户端2和客户端端3的时间大于10:00:02,可以更新。

假如客户端3先更新,缓存时间就变成了:10:00:04,客户端2再来更新,由于它的时间10:00:03 < 10:00:04,就是用旧数据覆盖新数据,是不被允许了,所以就不执行更新。

这样就不会有数据错了的问题了。

3、Redis事务的CAS方案

看官网哈

Transactions
How transactions work in Redis

Redis Transactions allow the execution of a group of commands in a single step, 
they are centered around the commands MULTI, EXEC, DISCARD and WATCH. 
Redis Transactions make two important guarantees:

    All the commands in a transaction are serialized and executed sequentially. 
A request sent by another client will never be served in the middle of the execution of 
a Redis Transaction. This guarantees that the commands are executed as 
a single isolated operation.

    The EXEC command triggers the execution of all the commands in the transaction,
 so if a client loses the connection to the server in the context of a transaction 
before calling the EXEC command none of the operations are performed, 
instead if the EXEC command is called, all the operations are performed. 
When using the append-only file Redis makes sure to use a single write(2) syscall to 
write the transaction on disk. However if the Redis server crashes or is killed by 
the system administrator in some hard way it is possible that only a partial number of 
operations are registered. Redis will detect this condition at restart, 
and will exit with an error. Using the redis-check-aof tool it is possible to 
fix the append only file that will remove the partial transaction so that 
the server can start again.

Starting with version 2.2, Redis allows for an extra guarantee to the above two, 
in the form of optimistic locking in a way very similar to a check-and-set (CAS) operation.
 This is documented later on this page.

再看看官网中下面的表述:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值