知识库
并发编程
  • 分类
  • 标签
  • 归档
友情连接

luoliang

吾生也有涯,知也无涯
并发编程
  • 分类
  • 标签
  • 归档
友情连接
  • openfeign拦截器
  • 基于redis的分布式
    • 分布式锁的关键点
    • 基于Redis的实现方案
      • 互斥性
      • 防死锁
      • 加锁解锁同一个线程
      • 锁的续期问题
      • 优点
      • 缺点
    • 参考
  • 服务发现之nacos
  • 负载均衡
  • 微服务
weiluoliang
2023-11-13
目录

基于redis的分布式

# 分布式锁的关键点

  1. 互斥性: 任何时间内都只有一个线程获取锁
  2. 防死锁: 假如程序崩溃了没有是否锁,要有另外一种方式去释放锁
  3. 加锁和解锁必须是同一个线程
  4. 锁的续期问题

# 基于Redis的实现方案

# 互斥性

  1. 实现方式一 : Redis 的 set NX 方式,key不存在设置成功,key存在则设置失败,通过这种方式可以保证同一时间只要一个线程能设置成功。

  2. 实现方式二:lua脚本的方式时间

# 如果key不存在,还没有客户端加锁
if ((redis.call('exists', KEYS[1]) == 0) 
        # 或者 hashKey(自己的clientId) 存在 , 说明自己获取锁 
        or (redis.call('hexists', KEYS[1], ARGV[2]) == 1)) then 
    # 通过 hincrby 的方式加锁, 如果是重入,则在原来的基础上+1    
    redis.call('hincrby', KEYS[1], ARGV[2], 1); 
    # 添加过期时间
    redis.call('pexpire', KEYS[1], ARGV[1]); 
    return nil; 
end;
# ttl获取剩余的过期时间
return redis.call('pttl', KEYS[1]);
1
2
3
4
5
6
7
8
9
10
11
12

# 防死锁

对lock_key 设置过期时间,Redisson设置的默认时间是 30s .

# 加锁解锁同一个线程

redis中保存了 客户端线程,所以在解锁的时候可以去判断是否是自己加锁,只有时自己加锁才能去释放,避免误操作去释放锁

# 锁的续期问题

在实际的开发过程中,你很难去判断应该加锁多长时间,比如说你预估30s,在当时可能这个时间是OK的,但是后面你加了新的业务逻辑,需要更长的时间,而你很有可能忘记了修改这个时间,那么这个超时时间就有问题了。 我们可以通过加个监听器去给锁增加时长,当key准备过期的时候,自动延长,这样就不会出现时间不够的情况,这也是Redisson目前时间的方案。

# 优点

  1. 与Zookeeper对比,性能比较高
  2. 通过Redisson的Watch Dog机制解决了锁的续约问题
  3. 锁可重入
  4. 锁申请等待资源,使用redis的消息订阅机制解决无效申请问题,减少了资源消耗

# 缺点

最大的缺点是: 如果使用Redis集群模式,当在master节点完成了加锁,此时master会同步给slave,假如此时master节点挂了,会导致锁信息丢失, slave切换成了master,其他线程就可以进来加锁,现象就是有多个线程同时获取锁,打破了互斥性

# 参考

Redisson 实现分布式锁原理分析 (opens new window)

上次更新: 2023/11/14, 14:12:09
openfeign拦截器
服务发现之nacos

← openfeign拦截器 服务发现之nacos→

最近更新
01
Linux常用命令
09-04
02
SpringBoot启动脚本
08-31
03
安装监控grafana
08-30
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式