分布式ID和分布式锁

分布式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. 看门狗设置续期阙值不能太小,太小会由于网络延迟导致续期时锁已经被删除。

相关推荐
愤怒的苹果ext2 小时前
MySQL Shell备份恢复数据库
数据库·mysql·备份恢复·mysqlsh
小白勇闯网安圈4 小时前
String、Hash、List、Set 四大数据结构与通用命令
redis
超兔一体云5 小时前
MySQL索引优化实战——从慢查询到索引调优
后端·mysql
2601_962074815 小时前
大数据-264 实时数仓 - Canal MySQL的binlog研究 存储目录 变动信息 配置MySQL
大数据·数据库·mysql
2601_962071176 小时前
八. Spring Boot2 整合连接 Redis(超详细剖析)
spring boot·redis·后端
2601_962073816 小时前
大数据-240 离线数仓 - 广告业务 测试 ADS层数据加载 DataX数据导出到 MySQL
大数据·数据库·mysql
程序员夏洛8 小时前
Redis 数据过期后的删除策略是什么?
数据库·redis·缓存
鱼鳞_8 小时前
热门八股-Redis
数据库·redis·缓存
这个DBA有点耶8 小时前
SQL:2023新特性详解:JSON_TABLE、GREATEST/LEAST、QUALIFY 到底怎么用?
数据库·sql·mysql
小王C语言8 小时前
MySQL 用户管理:创建用户、给用户授权
数据库·mysql