分布式锁

Redis

最简单的我们使用redis.setNX(key, value, timeout),但是存在超时没有执行完的问题,然后线程2加锁,最后在finally中线程1删除key,之后就该锁就消失了,线程3此时又能成功加锁。
弥补措施之一:value设置当前线程id或uuid,在删除前判断是否是自己的设置的值,如果不是不许删除key。此操作是非原子,需要用lua脚本操作。
但无法解决超时问题,不设置超时有存在线程崩溃无法释放锁的问题。

Redission

使用redission即可解决,可以自动续期,使用如下:

  1. RLock lock = redisson.getLock("className");
  2. lock.lock();
  3. try {
  4. // do sth.
  5. } finally {
  6. lock.unlock();
  7. }

分布式id【1】

UUID

数据库自增id

优点:实现简单,ID单调自增,数值类型查询速度快
缺点:DB单点存在宕机风险,无法扛住高并发场景

数据库双主模式集群模式

可以分段自增,或者2台机器,一台自增奇数一台偶数

  1. MySQL_1 配置:
  2. set @@auto_increment_offset = 1; -- 起始值
  3. set @@auto_increment_increment = 2; -- 步长
  4. MySQL_2 配置:
  5. set @@auto_increment_offset = 2; -- 起始值
  6. set @@auto_increment_increment = 2; -- 步长

优点:解决DB单点问题
缺点:不利于后续扩容,而且实际上单个数据库自身压力还是大,依旧无法满足高并发场景。

数据库的号段模式

从数据库批量的获取自增ID,每次从数据库取出一个号段范围,例如 (1,1000] 代表1000个ID,具体的业务服务将本号段,生成1~1000的自增ID并加载到内存。

  1. CREATE TABLE id_generator (
  2. `id` int(10) NOT NULL,
  3. `max_id` bigint(20) NOT NULL COMMENT '当前最大id',
  4. `step` int(20) NOT NULL COMMENT '号段的步长',
  5. `biz_type` int(20) NOT NULL COMMENT '业务类型',
  6. `version` int(20) NOT NULL COMMENT '版本号',
  7. PRIMARY KEY (`id`)
  8. )

等这批号段ID用完,再次向数据库申请新号段,对max_id字段做一次update操作(采用版本号 version乐观锁方式更新),update max_id= max_id + step,update成功则说明新号段获取成功,新的号段范围是(max_id ,max_id +step]。

基于Redis模式

利用redis的incr命令实现ID的原子性自增

  1. 127.0.0.1:6379> set seq_id 1 // 初始化自增ID为1
  2. OK
  3. 127.0.0.1:6379> incr seq_id // 增加1,并返回递增后的数值
  4. (integer) 2

基于雪花算法(Snowflake)模式

使用一个 64 bit 的 long 型的数字作为全局唯一 id
image.png
第一个部分是 1 个 bit:0,这个是无意义的。因为二进制里第一个 bit 位如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。
第二个部分是 41 个 bit:表示的是时间戳。单位是毫秒。41 bit 可以表示的数字多达 2^41 - 1,也就是可以标识 2 ^ 41 - 1 个毫秒值,换算成年就是表示69年的时间。
第三个部分是 5 个 bit:表示的是机房 id
第四个部分是 5 个 bit:表示的是机器 id。每个机房里可以代表 2 ^ 5 个机器(32 台机器),也可以根据自己公司的实际情况确定。
第五个部分是 12 个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号。12 bit 可以代表的最大正整数是 2 ^ 12 - 1 = 4096,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的 4096 个不同的 id。

总结:就是用一个 64 bit 的数字中各个 bit 位来设置不同的标志位,区分每一个 id。

参考

【1】9 种分布式 ID 生成方式,总有一款适合你!:https://mp.weixin.qq.com/s?src=11&timestamp=1634202299&ver=3373&signature=pTpl5NJUVpXIcBAkv*VZPwqk5m8OCyDMRDiSwVFQZDfe0mKROl-Azmx86TfRoXEQpWGmHV-x9HwhS3PXCEDXk-i7qpEmiaX7UqSHLav6CKsIE4noAuwTosjLogCp14hd&new=1