分布式ID和分布式锁

发布于:2025-05-16 ⋅ 阅读:(17) ⋅ 点赞:(0)

分布式ID和分布式锁

一、分布式ID

特点:

  1. 全局唯一
  2. 自增
  3. 高可用
  4. 高性能

在分布式/分库分表的情况下,需要保证id的自增性和唯一性,所以需要使用分布式ID
实现方式有UUID、雪花算法、Leaf算法

1.1 UUID

长度128位,以32位长度的16进制外加4位连接符的字符串表示(共36位)
例如:123e4567-e89b-12d3-a456-426614174000
优点:

  • 简单
  • 性能不错
  • 本地生成,没有网络消耗

缺点:

  • 可读性差
  • 存储成本高
  • 信息不安全,基于mac地址,容易被攻击
  • 非单调递增,容易出现页分裂问题(本质就是B+树分裂重组)

1.2 雪花算法

长度64位,以16位十六进制表示

从左至右依次使用的位数:
1(不使用)+41(时间戳)+10(工作机器id)+12(序列号)

优点:

  • 只有64位,节省了存储空间
  • 本地生成
  • 单调递增(但是不连续),页分裂概率很低

缺点:

  • 依赖于时间戳,如果系统时钟发生回拨,可能产生重复的id

1.3 基于Mysql的ID生成

基于mysql实现,将自增id存在某个数据表中,每次插入数据都需要获取并修改一下这个自增id

优点:

  • 实现简单
  • 自增且连续

缺点:

  • 基于mysql实现,并发度不高且负载不高

1.4 基于redis的ID生成

基于redis实现,将自增id存在redis中并使用incr命令修改,原理和mysql类似

优点:

  • 实现简单
  • 自增连续
  • 基于redis实现,负载更高

缺点:

  • 要考虑id的持久化
  • 如果最大id丢失,很难重新找回

1.5 leaf算法

leaf-segment

在数据库中存储id片段,每次向mysql中请求id片段,例如当前max-id=1000,偏移大小为100,所以每次请求就会请求1001~1100的id到内存中,然后更新数据库,不需要每次请求id都需要访问数据库。
但是如果这些id没有被完全使用,后续将不会再使用。例如:如果上述请求到的1001~1100id,用了几个之后,将内存清除(重启程序),那么下次获取id只能重新请求mysql获取新的id,之前的未使用的id将会浪费。

leaf-snowflake

基于雪花算法的改进,主要是改进了由于时间回拨的重复问题。判断当前时间戳是否小于上一次请求的时间戳,如果小于,则看时间的差值是否在5ms内,如果在5ms内,则等待两倍的时间差的时间后再使用雪花算法获取id,如果大于则报错。

二、分布式锁

实现原理:使用一些公共组件模拟锁的获取
redis、mysql的分布式锁的原理都是在其内部加上一条数据,表示上锁,如果添加成功就表示成功获取锁,失败就是没有获取到锁,释放锁就是删除数据。

  • 轮询获取锁:mysql、redis
  • 监听删除事件(监听锁(数据)删除的事件)锁:etcd、zookeeper

2.1 基于mysql的分布式锁

缺点:

  1. 数据库是单点的,可用性不高
  2. 操作磁盘缓慢
  3. 无法设置过期时间,容易产生死锁

2.2 基于redis的分布式锁

set key value nx ex 过期时间
看门狗机制
红锁

2.3 基于etcd的分布式锁

ETCD介绍:

Lease机制:

etcd 可以为存储的 key-value 对设置租约,当租约到期,key-value 将失效并被删除,同时也支持续约,通过客户端可以在租约到期之前进行续约, 来避免 key-value 对过期失效。

Revision机制:

每个key带有一个Revision属性值,etcd每进行一次事务对应的全局Revision值都会+1,因此每个key对应的Revision属性值都是全局唯一的,通过比较Revision的大小就可以知道进行写操作的顺序。

prefix机制:

可以根据前缀获得该前缀目录下所有的key及其对应的属性值

watch机制:

当被 监听的 key 或范围发生变化,客户端将收到通知

实现:
Lease机制设置锁的过期时间,存入数据,获取revision,判断获取的revision号是否是足校的,如果不是最小的,就监听小于revision的最大revision数据的删除事件

2.4 zookeeper分布式锁

持久节点

持久顺序节点

临时节点

临时顺序节点

实现:

基于临时顺序节点,创建一个临时顺序节点,检查自身是否是最小的节点,如果不是就监听前一个节点的删除事件,当前一个节点删除的时候就会收到通知。

性能 mysql < zookeeper/etcd < redis
可靠性 mysql < redis < zookeeper/etcd

Redisson的Watch Dog机制

  1. 如果用户指定过期时间,就不会有看门狗机制

  2. 如果用户没有指定,则会有看门狗机制,但是如果线程拿到锁之后,一直执行(假设无限时间),则锁永远不会过期

  3. 看门狗设置续期阙值不能太小,太小会由于网络延迟导致续期时锁已经被删除。


网站公告

今日签到

点亮在社区的每一天
去签到