分布式ID生成器框架:超高性能的发号器框架。通过引入多种新的方案,彻底解决雪花算法的时间回拨等问题,并将雪花算法原生QPS提高最少十几~二十倍
Butterfly(蝴蝶)是一个超高性能的发号器框架。框架通过引入多种新的方案不仅解决了雪花算法存在的所有问题,而且还能够提供比雪花算法更高的性能。在单机版QPS理论值为51.2(w/s)这种情况下,新的方案在一些机器上可达 1200(w/s) 甚至更高。
起名Butterfly是用世界上没有完全相同的蝴蝶翅膀来表示该算法的唯一性。
雪花算法是twitter提出的分布式id生成器方案,但是有三个问题,其中前两个问题在业内很常见:
其中业内针对前两个问题都有个自己的解决方式,但是都不是很完美,或者说没有完全解决。我们这里从新的思路出发,通过改造雪花算法以及其他相关方式彻底解决了以上的三个问题。
该方案算是对雪花算法比较完美的一种实现方式。方案请见方案介绍
在发号器内,业内常用的是有这么几种
对于一般的业务场景,以上业内都是可以满足,所以一般情况下使用业内的就可以,但是对于一些并发需要非常高的情况,方案3的调整需要人工自己调整,方案1有雪花问题,这个时候才可以考虑使用改进版雪花
该方案其实更多的是对雪花本身问题的一种技术探索,进而引入了一些新的方案,新方案就带来了一些新的特性,有些朋友会直接拿过来放到生产环境中使用,有些可能不合适;因此强烈建议使用这个的朋友一定要将原理弄清楚再看下自己的业务是否适合使用;否则的话建议使用业内的成熟方案
对于以上三个问题,我们这里简述下我们的方案。
全局唯一
无时间回拨问题
超高性能
生成的id跟无法反解析时间
非严格的整体自增
适用场景:
全局唯一:最基本的要求,目前是对一个业务而言是唯一性
超高性能:纯内存化操作,性能特别高。采用时间预留,解决时钟回拨问题,同时可以使得qps达到更高,理论上最高可到 51.2w/s ~ more(不同的机器上限不同,自己的笔记本可达 1200(w/s))
趋势递增:整体递增,对用Mysql这种用b+树作为索引的结构可以提高性能
信息安全:自增位放在高位,id不是完全连续的,防止外部恶意的数据爬取
易用性:开发接入非常简单
对于使用根据机器id的分配方式不同,这里有三种方式:
目前已发布到maven中央仓库
<dependency>
<groupId>com.github.simonalong</groupId>
<artifactId>butterfly-allocator-zookeeper</artifactId>
<!--替换为具体版本号-->
<version>${last.version.release}</version>
</dependency>
@Test
public void test(){
ZkButterflyConfig config = new ZkButterflyConfig();
config.setHost("localhost:2181");
ButterflyIdGenerator generator = ButterflyIdGenerator.getInstance(config);
// 设置起始时间,如果不设置,则默认从2020年2月22日开始
generator.setStartTime(2020, 5, 1, 0, 0, 0);
// 添加业务空间,如果业务空间不存在,则会注册
generator.addNamespaces("test1", "test2");
Long uuid = generator.getUUid("test1");
System.out.println(uuid);
}
<dependency>
<groupId>com.github.simonalong</groupId>
<artifactId>butterfly-allocator-db</artifactId>
<!--替换为具体版本号-->
<version>${last.version.release}</version>
</dependency>
在对应的公共库中创建表
CREATE TABLE `butterfly_uuid_generator` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`namespace` varchar(128) DEFAULT '' COMMENT '命名空间',
`work_id` int(16) COMMENT '工作id',
`last_expire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '下次失效时间',
`uid` varchar(128) DEFAULT '0' COMMENT '本次启动唯一id',
`ip` varchar(20) NOT NULL DEFAULT '0' COMMENT 'ip',
`process_id` varchar(128) NOT NULL DEFAULT '0' COMMENT '进程id',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_name_work` (`namespace`,`work_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='发号器表';
编写db方式的测试
@Test
public void test(){
DbButterflyConfig config = new DbButterflyConfig();
config.setUrl("jdbc:mysql://127.0.0.1:3306/neo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&&allowPublicKeyRetrieval=true");
config.setUserName("neo_test");
config.setPassword("neo@Test123");
ButterflyIdGenerator generator = ButterflyIdGenerator.getInstance(config);
// 设置起始时间,如果不设置,则默认从2020年2月22日开始
generator.setStartTime(2020, 5, 1, 0, 0, 0);
// 添加业务空间,如果业务空间不存在,则会注册
generator.addNamespaces("test1", "test2");
Long uuid = generator.getUUid("test1");
System.out.println(uuid);
}
分布式模式客户端一个,但是对应的服务端(代码很简单可以也自己写服务端)这边有两个:
<dependency>
<groupId>com.github.simonalong</groupId>
<artifactId>butterfly-allocator-distribute</artifactId>
<!--替换为具体版本号-->
<version>${last.version.release}</version>
</dependency>
首先启动服务端butterfly-server模块,然后客户端这边使用如下即可
@Test
public void test(){
DistributeDubboButterflyConfig config = new DistributeDubboButterflyConfig();
config.setZkHoseAndPort("localhost:2181");
ButterflyIdGenerator generator = ButterflyIdGenerator.getInstance(config);
// 设置起始时间,如果不设置,则默认从2020年2月22日开始
generator.setStartTime(2020, 5, 1, 0, 0, 0);
// 添加业务空间,如果业务空间不存在,则会注册
generator.addNamespaces("test1", "test2");
Long uuid = generator.getUUid("test1");
System.out.println(uuid);
}
首先启动服务端butterfly-server模块,然后客户端这边使用如下即可
@Test
public void test(){
DistributeRestfulButterflyConfig config = new DistributeRestfulButterflyConfig();
config.setHostAndPort("localhost:8800");
ButterflyIdGenerator generator = ButterflyIdGenerator.getInstance(config);
// 设置起始时间,如果不设置,则默认从2020年2月22日开始
generator.setStartTime(2020, 5, 1, 0, 0, 0);
// 添加业务空间,如果业务空间不存在,则会注册
generator.addNamespaces("test1", "test2");
Long uuid = generator.getUUid("test1");
System.out.println(uuid);
}
对于详细内容介绍,请见文档Butterfly说明文档
最近有一些朋友咨询,就先建了个小群,有需要的可以加 wx:zhoumo187108