在庞大复杂的分布式系统中,通常需要对海量数据进行唯一标识,随着数据日渐增长,对数据分库分表以后需要有一个唯一 ID 来标识一条数据,而数据库的自增 ID 显然不能满足需求,此时就需要有一个能够生成全局唯一 ID 的系统,需要满足以下条件:
上述的 2 和 3 点需求是互斥的,无法使用同一个方案满足。
以 MySQL 为例,利用给字段设置 auto_increment_increment
和 auto_increment_offset
来实现 ID 自增。每次业务可以使用下列 SQL 进行读写得到 ID:
begin;
REPLACE INTO Tickets64 (stub) VALUES (‘a‘);
SELECT LAST_INSERT_ID();
commit;
Snowflake
(雪花算法)是由 Twitter
发布的分布式 ID 生成算法,它能够保证不同进程主键的不重复性,以及相同进程主键的有序性。它是通过时间位实现单调递增,且各个服务器如果都做了时间同步,那么生成的 ID 可以认为是总体有序的。
Leaf
最早期需求是各个业务线的订单 ID 生成需求。在美团早期,有的业务直接通过数据库自增的方式生成 ID,有的业务通过 Redis 缓存来生成 ID,也有的业务直接用 UUID 这种方式来生成 ID。以上的方式各自有各自的问题,因此决定实现一套分布式 ID 生成服务来满足需求。
Leaf-segment
数据库方案,在使用数据库的方案上,做了以下改变:
优点:
缺点:
该方案完全沿用 snowflake
方案设计。对于 workerID
的分配,当服务器集群数量较小的情况下,完全可以手动配置。服务规模较大时,动手配置成本太高,所以使用 Zookeeper
持久顺序节点的特性自动对 snowflake
节点配置。
启动步骤如下:
Leaf-snowflake
服务,连接 Zookeeper
,在 leaf_forever
父节点下检查自己是否已经注册过。workerID
,启动服务。workerID
号。$ git clone https://github.com/antoniopeng/leaf.git
$ cd leaf
$ mvn clean install -DskipTests
$ cd leaf-docker
$ chmod +x build.sh
$ ./build.sh
$ docker-compose up -d
生成地址:http://localhost:8080/api/snowflake/get/test
$ curl http://localhost:8080/api/snowflake/get/test
文章作者:彭超
本文首发于个人博客:https://antoniopeng.com/2020/07/22/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%20ID%20%E7%94%9F%E6%88%90%E6%96%B9%E6%A1%88%E4%B9%8B%E7%BE%8E%E5%9B%A2%20Leaf/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 彭超 | Blog!
原文:https://blog.51cto.com/14791564/2515604