首页 > 其他分享 >分布式ID生成方案

分布式ID生成方案

时间:2022-12-19 14:14:16浏览次数:32  
标签:雪花 生成 算法 ID id 分布式

分布式ID生成方案

      朱门酒肉臭,路有冻死骨。

简介

对于单体项目,主键 ID 常用主键自动的方式进行设置。但是在分布式系统中,分库分表之后就不行了,如果还采用简单数据库主键ID自增的方式,就会出现同一ID在不同数据库的情况。常见分布式ID生成方案:UUID、号段模式、Redis 实现、雪花算法(SnowFlake)、滴滴 TinyID、百度 Uidgenerator、美团 Leaf等。

1、UUID

UUID(Universally Unique Identifier)长度是128bit位(16字节),换算为16进制数值(每4位代表一个数值)就是有32个16进制数值组成,中间使用4个-进行分隔,按照8-4-4-4-12的顺序进行分隔。加上中间的横杆,UUID有36个字符。比如:55d8cd15-7943-4849-89a8-ce7e7ce0b1d0。

优点

  • 性能优异,本地生成ID,不需要进行远程调用。

缺点

  • UUID 的无序性,无法保证趋势递增。
  • UUID 过长,不易存储,往往用字符串表示,作为主键建立索引查询效率低。

2、号段模式

实现思路是从数据库获取一个号段范围,比如 [1,1000],然后生成 1 到 1000 的自增 ID 加载到内存中,直到 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 '版本号 类似MVCC',
7   PRIMARY KEY (`id`)
8 )

再次获取号段范围,更改最大值。

update id_generator set max_id = #{max_id+step}, version = version + 1 where version = # {version} and biz_type = XXX
  • 优点:方案成熟、社区使用热度高如百度 Uidgenerator,美团 Leaf;
  • 缺点:分布式ID生成依赖于数据库。

3、Redis 实现

由于 Redis 单线程的特点,可以保证 ID 的唯一性和有序性。可以使用 INCR 和 INCRBY 这样的自增原子命令实现Redis 分布式 ID 。

优点:Redis基于缓存性能搞,而且可以保证唯一性和有序性;

缺点:系统需要引入 Redis 组件,增大系统维护成本和复杂度。并发请求量上来后,就需要集群,并且需要分布式锁保证只有一个Client拿到锁生成ID。

4、雪花算法(SnowFlake)

雪花算法(Snowflake)是由 Twitter 开源的分布式 ID 生成算法,结构上:符号位+时间戳+工作进程位+序列号位,一个64bit的整数(8字节),正好为一个long类型数据,所以 Java 程序中一般使用 Long 类型存储。

  • 1bit sign:第一位占用 1 bit,始终是 0,是一个符号位,不使用;
  • 41bit timestamp:第 2 位开始的 41 位是时间戳。41-bit 位可表示 241 个数,每个数代表毫秒,那么雪花算法可用的时间年限是 (241)/(1000606024365)=69 年的时间,即从1970年开始,雪花算法能用到2039年;
  • 10bit workerId:10-bit 位可表示机器数,即 2^10 = 1024 台机器。通常不会部署这么多台机器;
  • 12bit sequence:12-bit 位是自增序列,表示每个机房的每个机器每毫秒可以产生2^12-1(4095)个不同的ID序号。

可以自己实现雪花算法,也可以使用一些封装好的比如hutool。

1 <dependency>
2     <groupId>cn.hutool</groupId>
3     <artifactId>hutool-core</artifactId>
4     <version>5.1.2</version>
5 </dependency>
6 
7 // 传入机器id和数据中心id,数据范围为:0~31
8 Snowflake snowflake = IdUtil.createSnowflake(1L, 1L);
9 System.out.println(snowflake.nextId()); 

优点

  • 雪花算法是目前解决分布式唯一ID的一种很好的解决方案,也是目前市面上使用较多的一种方案。
  • 雪花算法生成的 ID 是趋势递增,不依赖数据库等第三方系统。
  • 生成 ID 的效率非常高,稳定性好,可以根据自身业务特性分配 bit 位,比较灵活。

缺点

  • 雪花算法强依赖于机器时钟。如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。如果恰巧回退前生成过一些 ID,而时间回退后,生成的 ID 就有可能重复。

5、百度 Uidgenerator

百度 UidGenerator 是百度开源基于 Java 语言实现的唯一 ID 生成器,是在雪花算法 Snowflake 的基础上做了一些改进。如:

  • 通过消费未来时间克服了雪花算法的并发限制。UidGenerator提前生成ID并缓存在RingBuffer中。 压测结果显示,单个实例的QPS能超过600万。雪花算法中sequence (13 bits):每秒下的并发序列,13 bits 可支持每秒 8192 个并发。
  • 支持自定义 workerId 位数和初始化策略,从而适用于 docker 等虚拟化环境下实例自动重启、漂移等场景。

6、美团 Leaf

目前主流的分布式ID生成方式大致都是基于数据库号段模式和雪花算法(snowflake),而美团(Leaf)刚好同时兼具了这两种方式,用户可以同时开启两种方式,也可以指定开启某种方式,能够根据不同业务场景灵活切换。

7、滴滴 Tinyid

Tinyid 是滴滴用 Java 开发的一款分布式 id 生成系统,基于数据库号段算法实现,Tinyid 扩展了 leaf-segment 算法,支持了多db(master),同时提供了 java-client(sdk) 使 id 生成本地化,获得了更好的性能与可用性。Tinyid 在滴滴客服部门使用,均通过 tinyid-client 方式接入,每天生成亿级别的 id。

使用注意事项

  • http 方式访问时,性能取决于 http server 的能力,网络传输速度。
  • java-client 方式访问时,id为本地生成,号段长度(step)越长,qps越大,如果将号段设置足够大,则qps可达1000w+。只要server有一台存活,则理论上可用,server全挂,因为client有缓存,也可以继续使用一段时间。
  • Tinyid 依赖db,当db不可用时,因为server有缓存,所以还可以使用一段时间,如果配置了多个db,则只要有1个db存活,则服务可用。
  • Tinyid 不适用场景:类似订单 id 的业务(因为生成的id大部分是连续的,容易被扫库、或者测算出订单量)

 

 

 

 

朱门酒肉臭

路有冻死骨

 

 

 

 

标签:雪花,生成,算法,ID,id,分布式
From: https://www.cnblogs.com/taojietaoge/p/16991831.html

相关文章

  • php 滑动图片验证生成
    1.话不多说,直接干货,喜欢的希望大家一键三连<?phpnamespaceApp\Model;classVerifyImage{//浮层坐标数组protected$tailoringArray=[];//浮层......
  • Android微信智能心跳方案
    前言:在13年11月中旬时,因为基础组件组人手紧张,Leo安排我和春哥去广州轮岗支援。刚到广州的时候,Ray让我和春哥对Line和WhatsApp的心跳机制进行分析。我和春哥抓包测试了差不多......
  • OAuth 2 Developers Guide
    IntroductionThisistheuserguideforthesupportfor ​​OAuth2.0​​​.ForOAuth1.0,everythingisdifferent,so ​​seeitsuserguide​​.Thisusergu......
  • Android Studio使用Mob实现短信验证功能遇到的问题解决
    一、Mob短信验证​​全球领先的数据智能科技平台-MobTech袤博解决​​进行注册登入 登入成功后,点击开发者服务中的短信验证,进入开发者平台填好信息创建成功后显示下图,可以......
  • IDEA中编译报错【java: 程序包lombok不存在】
    一、lombok问题没有正确引入lombok检查是否在pom中引入lombok依赖<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>......
  • 【服务器数据恢复】NTFS文件系统服务器raid5数据恢复案例
    服务器数据恢复环境:一台使用NTFS文件系统的服务器;7块硬盘组成了一组raid5磁盘阵列。服务器故障&初检:raid5磁盘阵列磁盘故障离线导致服务器瘫痪。用户在处理掉线磁盘时只......
  • 定制.NET 6.0的Middleware中间件
    在本文中,我们将学习中间件,以及如何使用它进一步定制应用程序。我们将快速学习中间件的基础知识,然后探讨如何使用它做的一些特殊事情。本文涵盖的主题包括:中间件简介编......
  • 基于消息队列实现分布式事务
    注意:本文把消息队列与购物车系统看作同一个事务目标:掌握消息队列的事务场景:订单系统产生订单,购物车系统减购物车中的商品。实现思路:订单系统在消息队列上开启一个事务......
  • spring boot踩坑日记——idea找不到配置文件
    报错:  原因springboot启动时找不到配置文件可以看出配置文件图标显示不对: 解决:标注配置文件......
  • XCode 日志打印总是提示 iOS [framework] CUICatalog: Invalid asset name supplied:
    Xcode控制台打印:[framework]CUICatalog:Invalidassetnamesupplied:'(null)'不知道是哪里的图片不存在或者传入的图片名为nil了,项目大了就是大海捞针,不知道哪里找?按......