数日前、私のWeChatパブリックアカウントのフォロワーが、最近の面接について不満を述べるメッセージを残しました。「Si兄さん、私は新年を迎える前に会社で少し不当な扱いを受けたと感じて衝動的に仕事を辞めました。今、流行は深刻で、まだ2か月以上仕事が見つかっていません。ビデオ面接を何度か受けましたが、何も起こりませんでした。多くの面接官は、質問をした後、他の解決策があるかどうか尋ねます。ただ働いてバグを解決すれば十分ではないですか?いくつの方法を知る必要があるのですか?」 おそらく面接官は応募者の回答に満足せず、自分が最善だと考える解決策を聞きたかったのでしょう。それは理解できます。同じバグに対して、1 行のコードで問題を解決できる人と 10 行のコードで問題を解決できる人では、どちらを選びますか?当たり前のこと!したがって、問題を複数の角度から見る必要があり、それぞれの方法には長所と短所があります。 1. 分散 ID を使用する理由 分散 ID の具体的な実装について説明する前に、分散 ID を使用する理由を簡単に分析してみましょう。分散 ID はどのような特性を満たす必要がありますか? 1. 分散IDとは何ですか? MySQL データベースを例に挙げます。 ビジネスデータの量が多くない場合は、単一のデータベースと単一のテーブルで既存のビジネスを完全にサポートできます。データが大きい場合は、MySQL マスター/スレーブ同期読み取り/書き込み分離でも処理できます。 ただし、データが増え続けると、マスターとスレーブの同期では対応できなくなり、データベースを異なるデータベースとテーブルに分割する必要があります。ただし、分割後は、データを識別するために一意の ID が必要になります。データベースの自己増分 ID は明らかに要求を満たすことができません。注文やクーポンなどの特別なものも、一意の ID で識別する必要があります。このとき、グローバルにユニークな ID を生成できるシステムが非常に必要になります。このグローバルに一意な ID は分散 ID と呼ばれます。 2. では、分散 ID はどのような条件を満たす必要がありますか? - グローバルに一意: IDはグローバルに一意である必要があります。これは基本的な要件です。
- 高パフォーマンス: 高可用性と低レイテンシ。 ID の生成と応答は高速である必要があります。そうでないと、ビジネスのボトルネックになります。
- 高可用性: 100% の可用性は誤解を招く恐れがありますが、可能な限り 100% の可用性に近づける必要があります。
- 容易なアクセス: すぐに使用できる設計の原則に従い、システムの設計と実装を可能な限りシンプルに保つ
- 増加傾向: 増加傾向にあるのが最適です。この要件は特定のビジネス シナリオによって異なり、通常は厳密に必須ではありません。
2. 分散 ID を生成する方法は何ですか? 今日は主に次の 9 つの分散 ID ジェネレーター方式とその長所と短所を分析します。 - 言語
- データベース自動増分ID
- データベースマルチマスターモード
- 数値セグメントモード
- レディス
- スノーフレーク
- 制作:Didi(TinyID)
- Baidu (ユーザーIDジェネレーター)
- 美団(葉)
それで、それらはどのように達成されるのでしょうか?それぞれの利点と欠点は何でしょうか?下を見てみよう 写真はインターネットから 上記の写真はインターネットから引用したものです。著作権侵害があった場合は削除いたしますのでご連絡ください。 1. UUIDに基づく Java の世界では、ユニークな ID を取得したい場合、まず思い浮かぶのは UUID かもしれません。何と言っても、グローバルにユニークであるという特徴があります。では、UUID は分散 ID として使用できるのでしょうか?答えは「はい」ですが、お勧めできません。 - パブリック静的voidメイン(String[] args) {
- 文字列uuid = UUID .randomUUID().toString().replaceAll("-","");
- System.out.println(uuid);
- }
UUID の生成は 1 行のコードで簡単に実行でき、出力結果は c2b8c2b9e46c47e3b30dca3b0d447718 になりますが、UUID は実際のビジネス ニーズには適していません。注文番号 UUID のような文字列は意味がなく、注文に関連する有用な情報は含まれていません。データベースがビジネス主キー ID として使用するには、長すぎるだけでなく、文字列でもあります。ストレージパフォーマンスが低く、クエリに時間がかかります。そのため、分散IDとして使用することは推奨されません。 アドバンテージ: - 生成は十分に単純で、ローカル生成はネットワークを消費せず、ユニークである
欠点: - 順序付けされていない文字列、トレンドの自動増加機能なし
- 具体的なビジネス上の意味はない
- 文字列が長すぎる場合 (16 バイト、128 ビット、または 36 ビット)、保存およびクエリ時に MySQL のパフォーマンスが大幅に低下します。 MySQL では、主キーはできる限り短くすることを公式に推奨しています。データベースの主キーである UUID の乱れにより、データの場所が頻繁に変更され、パフォーマンスに重大な影響を及ぼします。
2. データベースに基づいてIDを自動増加 データベースに基づく auto_increment ID は、分散 ID として完全に機能できます。特定の実装では、ID を生成するために別の MySQL インスタンスが必要です。テーブル構造は次のとおりです。 - データベース `SEQ_ID` を作成します。
- テーブルSEQID.SEQUENCE_IDを作成します(
- id bigint(20) unsigned NOT NULL auto_increment,
- 値 char(10) NOT NULL デフォルト ''
- 主キー (id)、
- )エンジン= MyISAM ;
- SEQUENCE_ID(値) VALUES('values') に挿入します。
ID が必要な場合は、テーブルにレコードを挿入して主キー ID を返します。しかし、この方法には致命的な欠点があります。アクセス数が急増すると、MySQL 自体がシステムのボトルネックになります。分散サービスを実装するためにこれを使用することは比較的リスクが高いため、お勧めできません。 アドバンテージ: - シンプルな実装、単調に増加するID、数値型の高速クエリ速度
欠点: - DBの単一ポイントではダウンタイムのリスクがあり、高同時実行シナリオを処理できません。
3. データベースクラスタモードに基づく 前述のように、シングルポイントデータベース方式は推奨されないため、上記の方式に高可用性の最適化をいくつか加え、マスタースレーブモードのクラスターに変更しましょう。マスターノードに障害が発生して使用できなくなることが心配な場合は、デュアルマスターモードのクラスターを作成できます。つまり、2 つの MySQL インスタンスが独立して自動増分 ID を生成できます。 しかし、問題が起こります。 2 つの MySQL インスタンスの自動増分 ID はどちらも 1 から始まります。重複した ID が生成された場合はどうすればよいでしょうか? 解決策: 開始値と増分ステップサイズを設定する MySQL_1 の設定: - @@ auto_increment_offset = 1 を設定します。 -- 開始値
- @@ auto_increment_increment = 2を設定します。 -- 歩幅
MySQL_2 の設定: - @@ auto_increment_offset = 2を設定します。 -- 開始値
- @@ auto_increment_increment = 2を設定します。 -- 歩幅
2 つの MySQL インスタンスの自動インクリメント ID は次のとおりです。 1、3、5、7、9 2、4、6、8、10 クラスターのパフォーマンスが依然として高い同時実行性に耐えられない場合はどうなるでしょうか? MySQL を拡張してノードを追加する必要がありますが、これはかなり面倒な作業です。 ここに画像の説明を挿入 上図からわかるように、水平方向に拡張されたデータベース クラスターは、データベースへの一点集中の問題を解決するのに役立ちます。同時に、ID 生成機能では、マシンの数に応じて自動増分ステップ サイズが設定されます。 3 番目の MySQL インスタンスを追加するには、最初の MySQL インスタンスと 2 番目の MySQL インスタンスの開始値とステップ サイズを手動で変更し、3 番目のマシンの開始 ID 生成位置を既存の最大自動増分 ID の位置から離れた位置に設定する必要があります。ただし、これは、最初の MySQL インスタンスと 2 番目の MySQL インスタンスの ID が 3 番目の MySQL インスタンスの開始 ID 値に達する前に実行する必要があります。そうしないと、自動増分 ID が重複し、必要に応じて変更するためにマシンをシャットダウンする必要がある場合があります。 アドバンテージ: 欠点: - これはその後の容量拡張には役立ちません。実際、単一のデータベース自体は依然として大きな負荷がかかっており、高同時実行シナリオに対応できません。
4. データベースベースの数値セグメントモード 番号セグメントモードは、現在の分散 ID ジェネレータの主流の実装方法の 1 つです。番号セグメント モードは、データベースから自動増分 ID をバッチで取得することとして理解できます。数値セグメントの範囲がデータベースから取り出されるたびに、たとえば [1,1000] は 1000 個の ID を表します。特定のビジネス サービスは、この数値セグメントを使用して 1 から 1000 までの自動増分 ID を生成し、メモリにロードします。テーブル構造は次のとおりです。 - id_generatorテーブルを作成します(
- id int(10) NULLではない、
- max_id bigint(20) NOT NULL COMMENT '現在の最大ID',
- step int(20) NOT NULL COMMENT 'セグメントの長さ',
- biz_type int(20) NOT NULL COMMENT 'ビジネスタイプ',
- バージョン int(20) NOT NULL COMMENT 'バージョン番号',
- 主キー (`id`)
- )
biz_type: さまざまなビジネスタイプを表します max_id: 現在利用可能な最大ID ステップ: 数値セグメントの長さを表します バージョン: 同時実行中にデータの正確性を保証するために、毎回バージョンを更新する楽観的ロックです。 id | ビジネスタイプ | 最大ID | ステップ | バージョン |
---|
1 | 101 | 1000 | 2000 | 0 |
この一連の数値セグメント ID が使い果たされたら、データベースから新しい数値セグメントを再度申請し、max_id フィールドに対して更新操作を実行し、max_id = max_id + step を更新します。更新が成功した場合、新しい数値セグメントが正常に取得され、新しい数値セグメントの範囲が (max_id、max_id +step] であることを意味します。 - id_generator を更新し、 max_idを #{max_id+step}、 versionをversion + 1 に設定し、 versionを # {version}、 biz_typeをXXXに設定します。
複数の業務端末が同時に稼働する可能性があるため、バージョン番号は楽観的ロックを使用して更新されます。この分散 ID 生成方法は、データベースに強く依存せず、データベースに頻繁にアクセスせず、データベースにかかる負荷が大幅に軽減されます。 5. Redisモードに基づく Redis でもこれを実現できます。原理は、redis の incr コマンドを使用して ID のアトミックな自己増分を実現することです。 - 127.0.0.1:6379 > set seq_id 1 // 自動増分IDを1に初期化する
- わかりました
- 127.0.0.1:6379 > incr seq_id // 1ずつ増加し、増加した値を返す
- (整数) 2
Redis を使用する際に注意すべき点の 1 つは、Redis の永続性の問題を考慮する必要があることです。 RedisにはRDBとAOFの2つの永続モードがあります。 - RDB は永続性を保つために定期的にスナップショットを取得します。番号が継続的に増加しても、Redis がそれを時間内に保持せず、Redis がハングアップした場合、Redis を再起動すると ID が繰り返されます。
- AOF は各書き込みコマンドを永続化するため、Redis がクラッシュしても ID が重複することはありません。ただし、incr コマンドの特殊性により、Redis を再起動してデータを回復するには時間がかかりすぎます。
6. スノーフレークベースのモデル Snowflake は、Twitter の内部分散プロジェクトで使用される ID 生成アルゴリズムです。オープンソース化されてからは国内大手企業からも高い評価を受けています。このアルゴリズムの影響を受けて、大手企業は独自の特徴を持つ分散型発電機を次々と開発してきました。 ここに画像の説明を挿入 上記の写真はインターネットから引用したものです。著作権侵害があった場合は削除いたしますのでご連絡ください。 Snowflake は Long 型の ID を生成します。 Long 型は 8 バイトを占め、各バイトは 8 ビットを占めるため、Long 型は 64 ビットを占めることになります。 Snowflake ID 構造は、正の数字 (1 ビット) + タイムスタンプ (41 ビット) + マシン ID (5 ビット) + データ センター (5 ビット) + 自動増分値 (12 ビット) の合計 64 ビットの Long 型で構成されます。 - 最初のビット (1 ビット): Java の long の最上位ビットは符号ビットであり、正または負を表します。正の数は 0、負の数は 1 です。通常、生成される ID は正の数なので、デフォルト値は 0 です。
- タイムスタンプ部分(41ビット):ミリ秒レベルの時間。現在のタイムスタンプを保存することはお勧めしません。代わりに、(現在のタイムスタンプ - 固定開始タイムスタンプ) の差を使用して、生成される ID が小さい値から開始されるようにします。 41 ビットのタイムスタンプは 69 年間使用できます、(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69 年。
- 作業マシン ID (10 ビット): workId とも呼ばれ、コンピューター ルームまたはマシン番号の組み合わせで柔軟に構成できます。
- シリアル番号部分(12ビット)、自己増分サポートにより、同じノードが同じミリ秒内に4096個のIDを生成することをサポートします。
このアルゴリズムのロジックによれば、このアルゴリズムを Java 言語で実装し、ツール メソッドにカプセル化するだけで済みます。その後、各ビジネス アプリケーションはこのツール メソッドを直接使用して分散 ID を取得できます。分散 ID を取得するために別のアプリケーションを構築することなく、各ビジネス アプリケーションが独自の作業マシン ID を持つことを確認するだけで済みます。 Snowflake アルゴリズム実装の Java バージョン: - /**
- * TwitterのSnowFlakeアルゴリズムはSnowFlakeアルゴリズムを使用して整数を生成し、それを62進数に変換して短縮URLにします。
- *
- * https://github.com/beyondfengyu/SnowFlake
- */
- パブリッククラスSnowFlakeShortUrl {
- /**
- * 開始タイムスタンプ
- */
- プライベート最終静的long START_TIMESTAMP = 1480166465631L ;
- /**
- * 各部分が占めるビット数
- */
- プライベート最終静的ロングSEQUENCE_BIT = 12 ; //シーケンス番号が占めるビット数
- プライベート最終静的ロングMACHINE_BIT = 5 ; //マシンIDで使用されるビット数
- プライベート最終静的long DATA_CENTER_BIT = 5 ; //データセンターが占有するビット数
- /**
- * 各パーツの最大値
- */
- プライベートファイナルスタティックロングMAX_SEQUENCE = -1L ^ (-1L < < シーケンスビット);
- プライベートファイナルスタティックロングMAX_MACHINE_NUM = -1L ^ (-1L < < マシンビット);
- プライベートファイナルスタティックロングMAX_DATA_CENTER_NUM = -1L ^ (-1L < < データセンタービット);
- /**
- * 各パーツの左への変位
- */
- プライベート最終静的 long MACHINE_LEFT = SEQUENCE_BIT ;
- プライベート最終静的ロングDATA_CENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
- プライベート最終静的ロングTIMESTAMP_LEFT = DATA_CENTER_LEFT + DATA_CENTER_BIT;
- プライベート長いデータセンターID; //データセンター
- プライベートロングマシンID; //マシンID
- プライベートロングシーケンス= 0L ; //シリアルナンバー
- プライベートロングlastTimeStamp = -1L; //最後のタイムスタンプ
- プライベートlong getNextMill() {
- ロングミル= getNewTimeStamp ();
- while (ミル< = lastTimeStamp) {
- ミル= getNewTimeStamp ();
- }
- リターンミル;
- }
- プライベートlong getNewTimeStamp() {
- System.currentTimeMillis() を返します。
- }
- /**
- * 指定されたデータセンターIDとマシンIDに基づいて指定されたシリアル番号を生成します
- *
- * @param dataCenterId データセンターID
- * @param machineId マシンID
- */
- パブリックSnowFlakeShortUrl(longデータセンターId、longマシンId) {
- if (データセンターID > MAX_DATA_CENTER_NUM || データセンターID < 0 ) {
- 新しい IllegalArgumentException をスローします ("DtaCenterId は MAX_DATA_CENTER_NUM より大きくしたり 0 より小さくすることはできません!");
- }
- if (マシンID > MAX_MACHINE_NUM || マシンID < 0 ) {
- throw new IllegalArgumentException("MachineId は MAX_MACHINE_NUM より大きく、または 0 より小さくすることはできません!");
- }
- this.dataCenterId = データセンターId;
- this.machineId = マシンID;
- }
- /**
- * 次のIDを生成する
- *
- * @戻る
- */
- パブリック同期された長いnextId(){
- long currTimeStamp = getNewTimeStamp ();
- if (currTimeStamp < 最終タイムスタンプ) {
- throw new RuntimeException("時計が逆方向に動きました。ID の生成を拒否します");
- }
- (カレントタイムスタンプ== ラストタイムスタンプ)の場合{
- //同じミリ秒で、シリアル番号が自動的に増加します
- シーケンス= (シーケンス + 1) & MAX_SEQUENCE;
- //同じミリ秒内のシーケンスの数が最大値に達しました
- if (シーケンス== 0L ) {
- currTimeStamp = getNextMill ();
- }
- } それ以外 {
- //異なるミリ秒では、シーケンス番号は0に設定されます
- シーケンス= 0L ;
- }
- 最後のタイムスタンプ= currTimeStamp ;
- 戻り値 (currTimeStamp - START_TIMESTAMP) < < TIMESTAMP_LEFT //タイムスタンプ部分
- |データセンターID < < DATA_CENTER_LEFT //データセンター部分
- |マシンID < < MACHINE_LEFT //マシン識別部分
- |順序; //シーケンス番号部分
- }
- パブリック静的voidメイン(String[] args) {
- SnowFlakeShortUrl snowFlake =新しいSnowFlakeShortUrl(2, 3);
- (int i = 0 ; i < (1 < < 4 ); i++) {
- //10進数
- System.out.println(snowFlake.nextId());
- }
- }
- }
7. Baidu (uidジェネレーター) uid-generator は Baidu Technology Department によって開発されました。プロジェクトのGitHubアドレスはhttps://github.com/baidu/uid-generatorです。 uid ジェネレーターは、Snowflake アルゴリズムに基づいて実装されています。オリジナルの Snowflake アルゴリズムとの違いは、uid ジェネレーターがカスタム タイムスタンプ、作業マシン ID、シリアル番号などの各部分の桁数をサポートし、ユーザー定義の workId 生成戦略を採用していることです。 uid ジェネレーターはデータベースと組み合わせて使用する必要があり、新しい WORKER_NODE テーブルを追加する必要があります。アプリケーションが起動すると、データがデータベース テーブルに挿入されます。挿入が成功すると、返される自動増分 ID は、ホストとポートで構成されるマシンの workId データになります。 uid-generator ID 構成構造の場合: workId は 22 ビット、time は 28 ビット、serialization は 13 ビットを占めます。本来のスノーフレークとは異なる点にご注意ください。時間の単位はミリ秒ではなく秒です。 workId も異なり、同じアプリケーションでも再起動するたびに workId が使用されます。 参考文献 https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md 8. 美団(葉) LeafはMeituanによって開発されました。githubアドレス: https://github.com/Meituan-Dianping/Leaf Leaf は、切り替え可能な数値セグメント モードとスノーフレーク アルゴリズム モードの両方をサポートしています。 数値セグメントモード まずソースコードhttps://github.com/Meituan-Dianping/Leafをインポートし、テーブルleaf_allocを作成します。 - `leaf_alloc` が存在する場合はテーブルを削除します。
- テーブル `leaf_alloc` を作成します (
- `biz_tag` varchar(128) NOT NULL DEFAULT '' COMMENT 'ビジネスキー',
- `max_id` bigint(20) NOT NULL DEFAULT '1' COMMENT '現在割り当てられている最大ID',
- `step` int(11) NOT NULL COMMENT '初期ステップサイズ。これは動的調整の最小ステップサイズでもあります',
- `description` varchar(256) DEFAULT NULL COMMENT 'ビジネスキーの説明',
- `update_time` タイムスタンプ NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'データベースメンテナンス更新時間',
- 主キー (`biz_tag`)
- )エンジン= InnoDB ;
次に、プロジェクトでセグメント モードを有効にし、対応するデータベース情報を構成し、スノーフレーク モードを無効にします。 - リーフ.名前= com.sankuai.leaf.opensource.test
- leaf.segment.enable = true
- leaf.jdbc.url =jdbc:mysql://localhost:3306/leaf_test? useUnicode = true & characterEncoding = utf8 & characterSetResults = utf8
- leaf.jdbc.username =ルート
- leaf.jdbc.password =ルート
- leaf.snowflake.enable = false
- # leaf.snowflake.zk.address =
- # leaf.snowflake.port =
leaf-server モジュールの LeafServerApplication プロジェクトを起動すると実行されます。 セグメントモードで分散自動インクリメント ID を取得するためのテスト URL: http://localhost:8080/api/segment/get/leaf-segment-test 監視番号セグメントモード: http://localhost:8080/cache スノーフレークモード Leaf のスノーフレーク モードは ZooKeeper に依存します。主に workId の生成において、オリジナルのスノーフレーク アルゴリズムと異なります。 Leaf の workId は、ZooKeeper の連続 ID に基づいて生成されます。各アプリケーションが Leaf-snowflake を使用する場合、起動時に Zookeeper で連続 ID が生成されます。これは、1 つの連続ノードに対応する 1 台のマシン、つまり 1 つの workId に相当します。 - leaf.snowflake.enable = true
- leaf.snowflake.zk.address = 127.0.0.1
- leaf.snowflake.port = 2181
スノーフレークモードで分散自動増分 ID を取得するためのテスト URL: http://localhost:8080/api/snowflake/get/test 9. ディディ(ティニッド) Tinyid は Didi によって開発されました。Github アドレス: https://github.com/didi/tinyid。 Tinyid は、Leaf とまったく同じセグメント モードの原理に基づいています。各サービスはセグメント(1000,2000]、(2000,3000]、(3000,4000])を取得します。 ここに画像の説明を挿入 Tinyid は、http と tinyid-client の 2 つのアクセス方法を提供します。 HTTP アクセス (1)Tinyidソースコードをインポートする: git クローン https://github.com/didi/tinyid.git (2)データテーブルを作成する: - テーブル `tiny_id_info` を作成します (
- `id` bigint(20) unsigned 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) デフォルト '0' コメント 'ステップ長',
- `delta` int(11) NOT NULL DEFAULT '1' COMMENT '各IDの増分',
- `remainder` int(11) NOT NULL デフォルト '0' コメント 'remainder',
- `create_time` タイムスタンプ NOT NULL デフォルト '2010-01-01 00:00:00' コメント '作成時間',
- `update_time` タイムスタンプ NOT NULL デフォルト '2010-01-01 00:00:00' コメント '更新時間',
- `version` bigint(20) NOT NULL DEFAULT '0' COMMENT 'バージョン番号',
- 主キー (`id`)、
- ユニークキー `uniq_biz_type` (`biz_type`)
- )エンジン= InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT 'id information 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 'このトークンがアクセスできるビジネスタイプ識別子',
- `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '備考',
- `create_time` タイムスタンプ NOT NULL デフォルト '2010-01-01 00:00:00' コメント '作成時間',
- `update_time` タイムスタンプ NOT NULL デフォルト '2010-01-01 00:00:00' コメント '更新時間',
- 主キー (`id`)
- )エンジン= InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT 'トークン情報テーブル';
- `tiny_id_info` に INSERT INTO (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
- 価値観
- (1, 'テスト', 1, 1, 100000, 1, 0, '2018-07-21 23:52:58', '2018-07-22 23:19:27', 1);
- `tiny_id_info` に INSERT INTO (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
- 価値観
- (2, 'test_odd', 1, 1, 100000, 2, 1, '2018-07-21 23:52:58', '2018-07-23 00:39:24', 3);
- `tiny_id_token` に INSERT します (`id`、`token`、`biz_type`、`remark`、`create_time`、`update_time`)
- 価値観
- (1, '0f673adf80504e2eaa552f5d791b644c', 'テスト', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48');
- `tiny_id_token` に INSERT します (`id`、`token`、`biz_type`、`remark`、`create_time`、`update_time`)
- 価値観
- (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48');
(3)データベースを構成する: - datasource.tinyid.names =プライマリ
- datasource.tinyid.primary.driver-class-name = com .mysql.jdbc.Driver
- datasource.tinyid.primary.url = jdbc :mysql://ip:port/databaseName? autoReconnect = true & useUnicode = true & characterEncoding = UTF -8
- datasource.tinyid.primary.username =ルート
- データソース.tinyid.プライマリ.パスワード= 123456
(4) tinyid-serverを起動してテストする - 分散自動インクリメント ID を取得します: http://localhost:9999/tinyid/id/nextIdSimple? bizType =テスト&トークン= 0f673adf80504e2eaa552f5d791b644c '
- 結果: 3 件
- 分散自動増分 ID をバッチで取得します。
- http://localhost:9999/tinyid/id/nextIdSimple? bizType =テスト&トークン= 0f673adf80504e2eaa552f5d791b644c &バッチサイズ= 10 '
- 結果を返します: 4,5,6,7,8,9,10,11,12,13
Javaクライアントアクセス HTTPメソッドの(2)と(3)の操作を繰り返します。 依存関係の導入 - <依存関係>
- <グループ ID > com.xiaoju.uemc.tinyid </グループ ID >
- <artifactId> tinyid -クライアント</artifactId>
- <バージョン> ${tinyid.version} </バージョン>
- </依存関係>
設定ファイル - tinyid.server =ローカルホスト:9999
- tinyid.トークン= 0f673adf80504e2eaa552f5d791b644c
test と tinyid.token は、データベース テーブルに事前に挿入されたデータです。 test は特定のビジネス タイプであり、tinyid.token はアクセス可能なビジネス タイプを示します。 - // 単一の分散自動増分IDを取得する
- ロングID = TinyId 。次のId( " テスト " );
- // オンデマンドで分散バッチ自動増分 ID
- リスト< 長さ > ids = TinyId 。次のId( " テスト " , 10 );
要約する この記事では、各分散 ID ジェネレーターを簡単に紹介し、詳細な学習の方向性を示すことを目的としています。それぞれの生成方法には長所と短所があり、それをどのように使用するかは特定のビジネス ニーズによって異なります。 |