大家好,我是讯享网,很高兴认识大家。
ID的独特设计在我们的系统开发中非常重要。几乎所有的系统设计都离不开ID码,比如电商订单号、快递单号等。好的ID编码设计可以提高数据存储和检索的效率,方便分布式系统的部署。
常用分布式ID算法常用的分布式ID算法
在此,我们对几种常用的ID编码方法进行了梳理和比较,以供参考。相关算法对应不同编程语言的实现,网上可以找到很多例子。
雪花算法
雪花,twitter中分布式项目使用的ID生成算法,目前比较受开发者欢迎,下面简单介绍一下。
雪花ID的64位二进制结构如下:
Snowflake的64位二进制结构雪花的64位二进制结构
第一段的第1位未使用,始终固定为0。第二段41位是毫秒时间(41位的长度可以用69年)。第三段的10位是worker ID(10位的长度最多可以支持1024个节点的部署)。第四段,12位,是毫秒内的计数(12位的计数序列号支持每个节点每毫秒产生4096个ID序列号)。
在商业中,我们可以将64位二进制转换为十进制长整数。因为是按时间生成的,所以有序,数据检索性能高。
示例ID: 27206497290486784
优势:
1.它不依赖于系统或数据库。
2.性能好,稳定性高。
缺点:
1.时钟回调:它强烈依赖于机器时间。如果机器上的时钟被修改和回调,也可能导致主键重复。
2.手动配置:WorkerId(机器Id)在需要部署时手动配置,WorkerId不能重复,在项目部署时需要特别注意。
UUID / GUID
UUID(通用唯一标识符)通用识别码,GUID(全球唯一标识符)全球唯一标识符。UUID是一个标准,GUID是UUID的实现之一。UUID编码结构如下:
UUID格式结构UUID格式结构
1~8位采用系统时间,精确到毫秒级,保证时间的唯一性。9~16位采用底层IP地址,在服务器集群中是唯一的。通过使用当前对象的HashCode值,7 ~ 24位在内部对象上是唯一的。25~32位是调用方法的随机数,在一个对象内以毫秒为单位是唯一的。示例ID:652 b83c 2-e18b-41d 4-a266-55 f63d 12 df 0
优势:
降低全局节点的压力,使得主键生成速度较快。跨服务器合并数据方便。
缺点:
UUID占用16个字符,空间占用较多。不是递增的有序数字,数据写入IO随机性大,因此检索效率会有所降低。
Redis自增
当使用数据库生成ID的性能不够时,可以尝试使用Redis生成ID。这主要取决于Redis是单线程的,所以也可以用来生成全局唯一的ID。这可以通过使用Redis的原子操作INCR和INCRBY来实现。
优势:
依赖于数据库,灵活方便,且性能优于数据库。数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点:
如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。需要编码和配置的工作量比较大。
数据库的主键自增
易于实现,一种常见的ID生成方法,通过数据库本身主键的自增量功能实现。
优势:
INT和BIGINT类型占用空间较小。主键自动增长,IO写入连续性好。数字类型查询速度优于字符串。
缺点:
并发性能不高,受限于数据库性能。分库分表,需要改造,复杂。自增有规律,会导致数据泄露。
其他分布式ID
1.Didi TinyID
Github地址:GitHub-Didi/Tinyid:id Generator id Generator分布式ID生成系统,一个易用、高性能、高可用的ID生成系统
2.百度UidGenerator
Github地址:github-Baidu/uid-generator:uniqueid生成器
3.美团叶子
Github地址:github-美团-大众点评/leaf:分布式id生成服务
4.数据库集群模式
利用数据库集群的模式,扩展数据库自增ID。
5.基于数据库的数字分段模式。
从数据库中批量获取自增ID,每次从数据库中取出一个号段范围,例如[11000]代表1000个ID,一旦这个号段ID用完,具体的业务服务将从数据库中申请一个新的号段。
总结
上述解决方案通常用于分布式全局唯一ID。ID编码方式的选择需要根据数据存储的大小空、数据检索的效率、系统是否易于移植等要求来进行。每种编码方式都不是完美的,需要我们根据自己的实际业务情况进行动态选择和调整。
本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://51itzy.com/8542.html