下面有几种常见的方案,可以根据具体的业务场景进行选择。
1. UUID
UUID指的是在一台机器上生成的数字,它保证了同一时间和空间内的所有机器都是唯一的。UUID由以下部分组成:
当前日期和时间。时钟序列。全球唯一的IEEE机器识别码(如网卡的MAC地址等。).
在Java中,使用UUID非常方便。
UUID uuid=uuid . randomuuid();
UUID有以下优势:
易于使用,易于实现。非常高的性能。缺点:
没有顺序,单调增加无法保证。太长,总长32位,无论是存储还是传输都有明显的缺点。
2. SnowFlake 雪花算法
Twitter的雪花是一个优秀的ID生成方案,实现相对简单。8字节是一个长字节,等于64位。核心代码是41位毫秒时间和10位机器标识毫秒序列,12位。https://github.com/twitter-archive/snowflake
雪花的优点如下:
它比UUID短,一般是9-17位数。生成的ID是一个数字,可以单调递增。由于分布式环境中各个服务器的时钟无法统一,只能由单台机器单调递增,而不能全局递增。性能出色,吞吐量达几十万TPS。雪花的结构如下(各部分用-:隔开)
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
第一位未使用,接下来的41位是毫秒时间(41位的长度可以使用69年),然后是5位的DataCenterID和5位的worker ID(10位的长度最多可以支持部署1024个节点),最后12位是以毫秒为单位进行计数(12位计数序列号可以支持每个节点每毫秒生成4096个ID序列号)。
总共只有64位,这是一个Long类型。(转换为字符串后的最大长度为19)
总的来说,雪花生成的ID是按递增时间排序的,整个分布式系统中不存在ID冲突(用DataCenterID和WorkerID区分),效率高。经过测试,雪花每秒可以生成26万个id。
由以下雪花算法生成的二进制和长类型的唯一标识。
《SnowFlake-Java版雪花算法》的实现方案和演示,可以查看边肖的另一篇文章。
3. Ticket Server
票务服务器是Flickr采用的分布式ID生成方案,由MySQL自生长ID实现。其设计思想是利用数据库中自动增量的特性和MySQL特有的REPLACE INTO命令,通过使用多个MySQL来实现高扩展性和高可用性。
例如,两个MySQL服务器实例是分开配置的。
节点配置:
auto _ increment _ increment=2;
auto _ increment _ offset=1;
第二个节点配置:
auto _ increment _ increment=2;
auto _ increment _ offset=2;
以上配置最好放在配置文件中,否则MySQL服务器重启时设置会丢失。
然后,在两个库中创建表,比如票据,设置ENGINE=MyISAM,以及表级锁,这样可以保证所有REPLACE INTO的原子性。不断替换为增加标识,这样表中只有一条记录。
替换为票据(存根)值(' a ')
在同一个连接中,自增id值是通过最后一个插入ID获得的。
票据服务器的优势:
对于数据量不是特别大的应用场景,长度是最小的。如果已经应用了基于MySQL的自增ID,那么迁移非常容易,并且与这个方案兼容。这个方案没有绝对的顺序,只有近似的顺序,在MySQL实例的状态下可以快速运行。
00-1010在高并发、大数据量的情况下,建议采用性能突出的雪花方案。
对于不太大,需要兼容老业务的场景,可以采用Ticket Server方案,两台MySQL物理机轻松达到数万TPS,响应时间为毫秒级。