ID生成スキームの概要

分散ID生成方式

  • UUID
  • データベースの自己増分
  • 数値セグメントモード
  • Redisの実装
  • スノーフレークアルゴリズム (SnowFlake)
  • 百度ウイドジェネレーター
  • 美団の葉
  • Didi TinyID

この記事ではIDを自動インクリメントできるLeafとTinyIDに焦点を当てます。

数値セグメントモード

このモードは分散 ID を生成する方法でもあり、[1,1000] などの数値範囲をデータベースから取得し、1 から 1000 までの自動インクリメント ID を生成し、メモリにロードするというアイデアです。構造は次のとおりです。

CREATE TABLE id_generator (
  id int(10) NOT NULL,
  max_id bigint(20) NOT NULL COMMENT '当前最大id',
  step int(20) NOT NULL COMMENT '号段的布长',
  biz_type int(20) NOT NULL COMMENT '业务类型',
  version int(20) NOT NULL COMMENT '版本号',
  PRIMARY KEY (`id`)


biz_type: さまざまなビジネス タイプ
max_id: 現在の最大 ID
step: 代表的な番号セグメントのステップ サイズversion: バージョン番号は、MVCC と同様に、楽観的ロック
として理解でき、 ID が使用されるのを待ってから、次へ進みます。データベースから取得して最大値を変更します

update id_generator set max_id = #{max_id+step}、version = version + 1 ここで、version = # {version} および biz_type = XXX

長所: Baidu Uidgenerator、 Meituan Leafなど、比較的成熟したソリューションがある
短所: データベースの実装に依存する

美団の葉

Leaf では、ID を生成する 2 つの方法、番号セグメント モード (リーフ セグメント) とスノーフレーク モード (リーフ スノーフレーク) を提供します。両方のメソッドを同時に有効にすることも、有効にするメソッドを指定することもできます。デフォルトでは、2 つのメソッドが無効になります。

gitの場所

GitHub - Meituan-Dianping/Leaf: 分散 ID 生成サービス

紹介文書

https://github.com/Meituan-Dianping/Leaf/blob/master/README_CN.md

データテーブルの作成

CREATE DATABASE leaf
CREATE TABLE `leaf_alloc` (
  `biz_tag` varchar(128)  NOT NULL DEFAULT '',
  `max_id` bigint(20) NOT NULL DEFAULT '1',
  `step` int(11) NOT NULL,
  `description` varchar(256)  DEFAULT NULL,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`biz_tag`)
) ENGINE=InnoDB;

insert into leaf_alloc(biz_tag, max_id, step, description) values('leaf-segment-test', 1, 2000, 'Test leaf Segment Mode Get Id')

アイテムを入手

git clone [email protected]:Meituan-Dianping/Leaf.git

mysqlドライバーをアップグレードする

接続が mysql1.8 以降の場合は、mysql ドライバーをそれぞれアップグレードする必要があります

Leaf/poe.xml以及 leaf_core/poe.xml

# Leaf/poe.xml
<mybatis-spring.version>1.2.5</mybatis-spring.version>

#leaf_core/poe.xml
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
      <version>8.0.25</version>
 </dependency>

設定変更

ナンバーセグメントモードの構成は以下のとおりです。

リーフサーバー/リソース/リーフ.プロパティ

leaf.name=com.sankuai.leaf.opensource.test
leaf.segment.enable=true
leaf.jdbc.url=jdbc:mysql://127.0.0.1:3306/leaf?useSSL=false
leaf.jdbc.username=root
leaf.jdbc.password=123456

leaf.snowflake.enable=false
#leaf.snowflake.zk.address=
#leaf.snowflake.port=

パック

cd リーフ
mvn クリーン インストール -DskipTests

走る

cd リーフサーバー
#mvn メソッド
mvn spring-boot:run
#script メソッド
shdeploy/run.sh 

テスト

#segmentcurl
http://localhost:8080/api/segment/get/leaf-segment-test
#snowflakecurl
http://localhost:8080/api/snowflake/get/test
モニタリングページ
番号セグメントモード: http://ローカルホスト:8080/キャッシュ

#biz_type を追加すると、10 秒後に有効になることに注意してください

Didi TinyID

ギットハブの場所

GitHub - リクエスト/リクエスト: ID ジェネレーターの識別

 紹介文書

ホーム · ウィキペディア · GitHub

アイテムを入手

git clone https://github.com/didi/tinyid.git

データテーブルの作成

tinyid-server/db.sql

CREATE TABLE `tiny_id_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '业务类型,唯一',
  `begin_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '开始id,仅记录初始值,无其他含义。初始化时begin_id和max_id应相同',
  `max_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '当前最大id',
  `step` int(11) DEFAULT '0' COMMENT '步长',
  `delta` int(11) NOT NULL DEFAULT '1' COMMENT '每次id增量',
  `remainder` int(11) NOT NULL DEFAULT '0' COMMENT '余数',
  `create_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新时间',
  `version` bigint(20) NOT NULL DEFAULT '0' COMMENT '版本号',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_biz_type` (`biz_type`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'id信息表';

CREATE TABLE `tiny_id_token` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `token` varchar(255) NOT NULL DEFAULT '' COMMENT 'token',
  `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '此token可访问的业务类型标识',
  `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
  `create_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'token信息表';

INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
VALUES
	(1, 'test', 1, 1, 100000, 1, 0, '2018-07-21 23:52:58', '2018-07-22 23:19:27', 1);

INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
VALUES
	(2, 'test_odd', 1, 1, 100000, 2, 1, '2018-07-21 23:52:58', '2018-07-23 00:39:24', 3);


INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
VALUES
	(1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48');

INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
VALUES
	(2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48');

設定変更

cd tinyid-server/src/main/resources/offline
vi application.properties

server.port=9999
server.context-path=/tinyid

batch.size.max=100000

#datasource.tinyid.names=primary
#如果希望数据库能够高可用,可以设置多个不同节点,两个节点上的数据保持一致。
#注意添加配置的时候,多个节点都要添加
datasource.tinyid.names=primary,secondary
datasource.tinyid.type=org.apache.tomcat.jdbc.pool.DataSource

datasource.tinyid.primary.driver-class-name=com.mysql.jdbc.Driver
datasource.tinyid.primary.url=jdbc:mysql://localhost:3306/db1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
datasource.tinyid.primary.username=root
datasource.tinyid.primary.password=123456
#datasource.tinyid.primary.testOnBorrow=false
#datasource.tinyid.primary.maxActive=10

datasource.tinyid.secondary.driver-class-name=com.mysql.jdbc.Driver
datasource.tinyid.secondary.url=jdbc:mysql://localhost:3306/db2?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
datasource.tinyid.secondary.username=root
datasource.tinyid.secondary.password=123456
datasource.tinyid.secondary.testOnBorrow=false
datasource.tinyid.secondary.maxActive=10


パック

cd 小さなID

mvn クリーン インストール -DskipTests

#または

cd tinyid-server/
sh build.sh オフライン

走る

cd tinyid-server/
#sh build.sh オフライン
java -jar 出力/tinyid-server-xxx.jar

テスト

nextId:
curl 'http://localhost:9999/tinyid/id/nextId?bizType=test&token=0f673adf80504e2eaa552f5d791b644c'
response:{"data":[2],"code":200,"message":""}

nextId Simple:
curl 'http://localhost:9999/tinyid/id/nextIdSimple?bizType=test&token=0f673adf80504e2eaa552f5d791b644c'
response: 3

with batchSize:
curl 'http://localhost:9999/tinyid/id/nextIdSimple?bizType=test&token=0f673adf80504e2eaa552f5d791b644c&batchSize=10'
response: 4,5,6,7,8,9,10,11,12,13

Get nextId like 1,3,5,7,9...
bizType=test_odd : delta is 2 and remainder is 1
curl 'http://localhost:9999/tinyid/id/nextIdSimple?bizType=test_odd&batchSize=10&token=0f673adf80504e2eaa552f5d791b644c'
response: 3,5,7,9,11,13,15,17,19,21

 

クライアントの使用

クライアントのパッケージ化

cd 小さなID

mvn クリーン インストール -DskipTests

#tinyid-client\target\ tinyid-client-0.1.0-SNAPSHOT.jarが使用できるクライアントです

クライアントプロフィール

tinyid_client.properties

tinyid_client.properties をリソースの下に置きます

tinyid.server=localhost:9999
tinyid.token=0f673adf80504e2eaa552f5d791b644c

使用

public class ClientTest {
    @Test
    public void testNextId() {
        for (int i = 0; i < 100000; i++) {
            Long id = TinyId.nextId("test_odd");
            System.out.println("current id is: " + id);
        }
    }
}

注: プログラムを再起動するたびに、ID を使い果たしたかどうかに関係なく、ID によってステップが追加されます。プログラムが頻繁に再起動される場合は、ステップを大きく設定しすぎないでください。ただし、ステップを小さくしすぎないでください。小さくしすぎると、データベースとの対話が頻繁になりすぎます。

ソース:

8つの分散ID生成スキームのまとめ 

Je suppose que tu aimes

Origine blog.csdn.net/csdncjh/article/details/132112737
conseillé
Classement