Redis 乐观锁(CAS)

导读

乐观锁介绍:

watch指令在redis事物中提供了CAS的行为。为了检测被watch的keys在是否有多个clients同时改变引起冲突,这些keys将会被监控。如果至少有一个被监控的key在执行exec命令前被修改,整个事物将会回滚,不执行任何动作,从而保证原子性操作,并且执行exec会得到null的回复。

乐观锁工作机制:

watch 命令会监视给定的每一个key,当exec时如果监视的任一个key自从调用watch后发生过变化,则整个事务会回滚,不执行任何动作。注意watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。当然exec,discard,unwatch命令,及客户端连接关闭都会清除连接中的所有监视。还有,如果watch一个不稳定(有生命周期)的key并且此key自然过期,exec仍然会执行事务队列的指令。

示例

在这里插入图片描述

原理

  • WATCH监控:每个Redis数据库都保存着一个watched_keys字典来保存被监控的健,字典值是一个链表,链表中记录了所有监视相应键的客户端

在这里插入图片描述

  • 监控机制触发:所有对数据库进行修改的命令,如SET、LPUSH、SADD、ZREM、DEL、FLUSHDB等,在执行之后都会调用multi.c/touchWatchKey函数对watched_keys字典进行检查,查看是否有客户端正在监视刚刚被命令修改过的key,有的话touchWatchKey函数会将监视的客户端的REDIS_DIRTY_CAS标识打开,表示该客户端事物安全性已经被破坏。
  • 判断事物是否安全 :当服务器接收到一个客户端发来的EXEC命令时,服务器将会根据这个客户端是否打开REDIS_DIRTY_CAS标识来决定是否执行事物
    -在这里插入图片描述

总结

  • 事务提供了一种将多个命令打包,然后一次性有序(FIFO)执行的机制
  • 事务执行过程不会被中断
  • 带WATCH命令的事务会将客户端和被监视的键在数据库watched_keys字典中进行关联,当键被修改程序会将所有监视键的客户端REDIS_DIRTY_CAS标识打开
  • 在客户端提交EXEC命令时,会检查REDIS_DIRTY_CAS标识,标识打开事物将不会被执行
  • Redis事务具有ACID的特性(当服务器运行在AOF模式下,并且appendfsync选项值为always时才具有持久性
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis的悲观锁和乐观锁是用于保证并发操作的一种机制。悲观锁适用于强一致性要求高、读并发比较低的场景,而乐观锁适用于读多写少、并发冲突较少的场景。 悲观锁是通过在操作前加锁的方式实现的,它假设在整个操作过程中会有其他并发操作对数据进行修改,因此在操作前会将数据进行加锁,确保在当前操作完成之前其他操作无法修改该数据。这种机制保证了操作的原子性和一致性,但效率相对较低。 乐观锁是通过在操作时判断数据版本号或使用CAS(Compare and Swap)操作来实现的。它假设在整个操作过程中不会有其他并发操作对数据进行修改,因此不进行加锁操作,而是在操作完成后检查数据是否被修改。如果数据没有被修改,则操作成功;如果数据被修改,则需要进行重试或回滚操作。乐观锁的特点是不阻塞其他操作,适合于读多写少的场景。 总而言之,悲观锁适用于强一致性要求高、并发冲突较多的场景,通过加锁来保证操作的原子性和一致性;乐观锁适用于读多写少、并发冲突较少的场景,通过版本号或CAS操作来实现并发控制 。 悲观锁比较适合强一致性的场景,但效率比较低,特别是读的并发低。乐观锁则适用于读多写少,并发冲突少的场景。 Redis的watch机制实现乐观锁。 像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适,之所以用悲观锁就是因为两个用户更新同一条数据的概率高,也就是冲突比较严重的情况下,所以才用悲观锁。 两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值