mysql id生成方式_几种生成唯一ID的方式

fe0f9075845faaa726ed93f803e6e25b.png几种生成唯一ID的方式

唯一ID在系统中是常用的,生成唯一ID的方式也有很多,各有各的优点,也有各自的缺点。

现在介绍几种常用的,系统时间,数据库方式,UUID,分布式(SnowFlake,Leaf,UID-generator,Redis,zk)等。

1、在单机程序中,可以利用系统时间来生成ID,这种方式理论上可以每秒最多1千个,如果是单体web系统集群部署方式,可以为每台机器加个标识。在并发比较低的情况下还是可以使用的。

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSSS");

String id = "ORD" + sdf.format(System.currentTimeMillis());

2、数据库方式,数据库方式比较简单,比如Oracle的序列,Mysql中的AUTO_INCREMENT等,这样可以生成唯一的ID,性能和稳定性依赖于数据库,如果数据库挂了,生成ID的服务就用不了了。在分布式的高并发系统中生成ID的服务需要支持高并发,高性能,此时可能就需要多台机器来支持,每台机器设置不同的初始值,且步长和机器数相等。比如有两台机器。设置步长step为2,Server1的初始值为1(1,3,5,7,9,11…)、Server2的初始值为2(2,4,6,8,10…),示意图如下:

74bf43b8943f5006bf6525c768c628c4.png数据库多台机器生成ID示意图

3、UUID方式,UUID 的十六个八位字节被表示为 32个十六进制数字,以连字号分隔的五组来显示,形式为 8-4-4-4-12,总共有 36个字符(即三十二个英数字母和四个连字号),java.util.UUID类可以生成uuid。

UUID uuid = UUID.randomUUID();

//da6feb86-f911-49e0-bb48-4051068fb810

UUID的优点就是简单唯一,但是缺点也明显,就是无序和长度较长,占用空间;如果用做MySQL的主键,数据会按照主键进行排序,由于UUID的无序性,插入数据存在性能问题。

4、Redis可以用来在分布式环境中生成唯一ID,ID可以做到递增。优点就是支持高并发下获取ID,缺点就是依赖Redis,稳定性依赖Redis。

5、ZK生成唯一ID,可以通过顺序节点和版本号来生产唯一的ID。

6、Snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。把64-bit分别划分成多段,分开来标识序列号,工作机器和时间戳等

b435940d89c8951b57b5c10a71c34ae0.pngSnowflake

1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是041位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截) 得到的值),这里的开始时间截,一般是我们的id生成器开始使用的时间。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 6910位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId。12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号。理论上snowflake方案的QPS约为409.6w/s。雪花算法的优点就是基本有序性和高性能,缺点就是时钟回拨,会产生重复的ID。

7、Leaf算法,leaf算计就是在一定程度上解决了数据库和雪花算法的问题。

第一种Leaf-segment方案,在使用数据库的方案上,做了如下改变: -1)原方案每次获取ID都得读写一次数据库,造成数据库压力大。改为利用proxy server批量获取,每次获取一个segment(step决定大小)号段的值。用完之后再去数据库获取新的号段,可以大大地减轻数据库的压力。 2)各个业务不同的发号需求用biz_tag字段来区分,每个biz-tag的ID获取相互隔离,互不影响。如果以后有性能需求需要对数据库扩容,不需要上述描述的复杂的扩容操作,只需要对biz_tag分库分表就行。通过双buffer做了优化,DB取号段的过程能够做到无阻塞,不需要在DB取号段的时候阻塞请求线程,即当号段消费到某个点时就异步的把下一个号段加载到内存中。而不需要等到号段用尽的时候才去更新号段。Leaf-snowflake方案完全沿用snowflake方案的bit位设计,通过写zk来校验时钟是否回拨,解决时钟回拨问题,

67fc8c98d4990269e8cec514dcaf46ae.png解决时钟回退的问题

8、UID-generator是百度的开源ID生成算法。UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境下实例自动重启、漂移等场景。 在实现上, UidGenerator通过借用未来时间来解决sequence天然存在的并发限制; 采用RingBuffer来缓存已生成的UID, 并行化UID的生产和消费, 同时对CacheLine补齐,避免了由RingBuffer带来的硬件级「伪共享」问题. 最终单机QPS可达600万。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值