All Projects → simonalong → Butterfly

simonalong / Butterfly

Licence: Apache-2.0 License
分布式ID生成器框架:超高性能的发号器框架。通过引入多种新的方案,彻底解决雪花算法的时间回拨等问题,并将雪花算法原生QPS提高最少十几~二十倍

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Butterfly

tsid-creator
A Java library for generating Time Sortable Identifiers (TSID).
Stars: ✭ 16 (-85.59%)
Mutual labels:  snowflake, unique-id, snowflake-twitter, snowflake-java
ulid-creator
A Java library for generating Universally Unique Lexicographically Sortable Identifiers (ULID)
Stars: ✭ 38 (-65.77%)
Mutual labels:  uuid, unique-id, uuid-generator
friendly-id
Java Friendly Id for UUID
Stars: ✭ 173 (+55.86%)
Mutual labels:  uuid, unique-id, unique-identifier
sno
Compact, sortable and fast unique IDs with embedded metadata.
Stars: ✭ 77 (-30.63%)
Mutual labels:  uuid, snowflake, unique-id
Snowflake
java edition of [Twitter Snowflake](https://github.com/twitter/snowflake), a network service for generating unique ID numbers at high scale with some simple guarantees.
Stars: ✭ 114 (+2.7%)
Mutual labels:  uuid, snowflake
fastuuid
FastUUID is a library which provides CPython bindings to Rust's UUID library
Stars: ✭ 83 (-25.23%)
Mutual labels:  uuid, uuid-generator
Ksuid
K-Sortable Globally Unique IDs
Stars: ✭ 3,202 (+2784.68%)
Mutual labels:  uuid, unique-id
python-ulid
ULID implementation for Python
Stars: ✭ 177 (+59.46%)
Mutual labels:  uuid, unique-id
uuidgen-el
UUID generation implemented in elisp.
Stars: ✭ 44 (-60.36%)
Mutual labels:  uuid, uuid-generator
react-native-uuid-generator
UUID generator for React Native utilizing native iOS and Android UUID classes
Stars: ✭ 88 (-20.72%)
Mutual labels:  uuid, uuid-generator
fuuid
Functional UUIDs for Python.
Stars: ✭ 145 (+30.63%)
Mutual labels:  uuid, unique-id
IdGenerator
💎迄今为止最全面的分布式主键ID生成器。 💎优化的雪花算法(SnowFlake)——雪花漂移算法,在缩短ID长度的同时,具备极高瞬时并发处理能力(50W/0.1s)。 💎原生支持 C#/Java/Go/Rust/C/SQL 等多语言,且提供 PHP 扩展及 Python、Node.js、Ruby 多线程安全调用动态库(FFI)。💎支持容器环境自动扩容(自动注册 WorkerId ),单机或分布式唯一IdGenerator。💎顶尖优化,超强效能。
Stars: ✭ 548 (+393.69%)
Mutual labels:  snowflake, unique-id
uuid-generator-plugin
An IntelliJ Idea plugin to generate UUID (Universally Unique Identifier), ULID (Universally Unique Lexicographically Sortable Identifier) and CUID (Collision Resistant Unique Identifier)
Stars: ✭ 30 (-72.97%)
Mutual labels:  uuid, uuid-generator
php-uuid
RFC 4122 compliant UUID generator and parser for PHP.
Stars: ✭ 13 (-88.29%)
Mutual labels:  uuid, uuid-generator
order-id
Unique order id generator
Stars: ✭ 46 (-58.56%)
Mutual labels:  unique-id, unique-identifier
uuid-mongodb
📇 Generates and parses MongoDB BSON UUIDs
Stars: ✭ 94 (-15.32%)
Mutual labels:  uuid
godot-uuid
Unique identifier generation v4 for Godot Engine
Stars: ✭ 96 (-13.51%)
Mutual labels:  uuid
typecho-theme-leaf
一款简洁又大气的typecho主题。演示站点
Stars: ✭ 62 (-44.14%)
Mutual labels:  leaf
astro
Astro allows rapid and clean development of {Extract, Load, Transform} workflows using Python and SQL, powered by Apache Airflow.
Stars: ✭ 79 (-28.83%)
Mutual labels:  snowflake
sfquickstarts
Follow along with our tutorials to get you up and running with the Snowflake Data Cloud.
Stars: ✭ 83 (-25.23%)
Mutual labels:  snowflake

Butterfly 简介

Butterfly(蝴蝶)是一个超高性能的发号器框架。框架通过引入多种新的方案不仅解决了雪花算法存在的所有问题,而且还能够提供比雪花算法更高的性能。在单机版QPS理论值为51.2(w/s)这种情况下,新的方案在一些机器上可达 1200(w/s) 甚至更高。 起名Butterfly是用世界上没有完全相同的蝴蝶翅膀来表示该算法的唯一性。

雪花算法是twitter提出的分布式id生成器方案,但是有三个问题,其中前两个问题在业内很常见:

  • 时间回拨问题
  • 机器id的分配和回收问题
  • 机器id的上限问题

其中业内针对前两个问题都有个自己的解决方式,但是都不是很完美,或者说没有完全解决。我们这里从新的思路出发,通过改造雪花算法以及其他相关方式彻底解决了以上的三个问题。
该方案算是对雪花算法比较完美的一种实现方式。方案请见方案介绍

使用场景说明

在发号器内,业内常用的是有这么几种

  1. 单机雪花:性能高,但是有时间回拨问题
  2. 单buffer + db:性能还可以,但是有buffer切换的延迟,一般都是用双buffer
  3. 双buffer + db:性能不错,不同业务根据对应的buffer调整,需要人工接入,存在定制化,不过一般业内都是用这个

对于一般的业务场景,以上业内都是可以满足,所以一般情况下使用业内的就可以,但是对于一些并发需要非常高的情况,方案3的调整需要人工自己调整,方案1有雪花问题,这个时候才可以考虑使用改进版雪花

新的方案

对于以上三个问题,我们这里简述下我们的方案。

  1. 时间回拨问题
    这里采用新的方案:大概思路是:时间戳采用的是“历史时间”,每次请求只增序列值,序列值增满,然后“历史时间”增1,序列值归0,其中"历史时间"的初始值是应用启动时候的当前时间。
  2. 机器id分配和回收
    这里机器id分配和回收具体有两种方案:zookeeper和db。理论上分配方案zk是通过哈希和扩容机器,而db是通过查找机制。回收方案,zk采用的是永久节点,节点中存储下次过期时间,客户端定时上报(设置心跳),db是添加过期时间字段,查找时候判断过期字段。
  3. 机器id上限
    这个采用将改造版雪花+zookeeper分配id方案作为服务端的节点,客户端采用双Buffer+异步获取提高性能,服务端采用每次请求时间戳增1。

特性

  1. 全局唯一

  2. 无时间回拨问题

  3. 超高性能

  4. 生成的id跟无法反解析时间

  5. 非严格的整体自增

适用场景:

  1. 超高并发情况(单机百万千万这种)
  2. 对时间不敏感,只要求唯一性
  3. 不要求完全自增

框架指标

全局唯一:最基本的要求,目前是对一个业务而言是唯一性
超高性能:纯内存化操作,性能特别高。采用时间预留,解决时钟回拨问题,同时可以使得qps达到更高,理论上最高可到 51.2w/s ~ more(不同的机器上限不同,自己的笔记本可达 1200(w/s))
趋势递增:整体递增,对用Mysql这种用b+树作为索引的结构可以提高性能
信息安全:自增位放在高位,id不是完全连续的,防止外部恶意的数据爬取
易用性:开发接入非常简单

快速入门

对于使用根据机器id的分配方式不同,这里有三种方式:

  • (单机版)zookeeper分配workerId
  • (单机版)db分配workerId
  • (分布式版)distribute分配workerId

目前已发布到maven中央仓库

zookeeper分配workerId

<dependency>
  <groupId>com.github.simonalong</groupId>
  <artifactId>butterfly-zookeeper-allocator</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);
}

db分配workerId

<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);
}

分布式模式

分布式模式客户端一个,但是对应的服务端(代码很简单可以也自己写服务端)这边有两个:

  • dubbo方式的:服务端采用的是butterfly-allocator-zk方式获取workerId和time字段,然后将对应字段给客户端
  • restful方式的:服务端采用的是butterfly-allocator-db方式获取workerId和time字段,然后将对应字段给客户端
<dependency>
  <groupId>com.github.simonalong</groupId>
  <artifactId>butterfly-allocator-distribute</artifactId>
  <!--替换为具体版本号-->
  <version>${last.version.release}</version>
</dependency>

使用示例 - dubbo方式获取

首先启动服务端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);
}

使用示例 - restful方式获取

首先启动服务端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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].