Generating unique id numbers in Azure

Post on 10-May-2015

2.466 views 5 download

Tags:

description

Global Windows Azure Boot Camp 2014 Japan の資料です。

Transcript of Generating unique id numbers in Azure

Generating unique ID numbers

in Microsoft Azure

kyrt Takekazu Omi

takekazu.omi@kyrt.in

@takekazuomi

2014/3/29 1.0.1

Generating unique ID numbers

in Microsoft Azureスケーラブルな ID 生成手法の比較と、 twitter snowflake に見る工夫

2014/2/26 kyrt @takekazuomi 2

Agenda

• Challenge• スケーラブルなサービスとスケーラブルな採番

• twitter snowflake• スケーラブルな分散採番サービスの例

• Cloud Design Patterns• 応用例

kyrt @takekazuomi 32014/2/26

Challengeスケーラブルなサービスには、スケーラブルな採番が必須課題と背景的な話「またの名を Challenge を課題と訳さないで」

2014/2/26 kyrt @takekazuomi 4

ID 生成の要件

1. ユニークである重複が無い。これは ID をキーにしたいので当然ですね。

2. 時系列で増えていく(または減っていく)ID が生成される度に増加していくのは連番での重要な性質の一つ

3. 秒間の発行数採番を一箇所で行わずに分散してするとスケールする

4. 連続性連続した欠落の無い番号の生成

kyrt @takekazuomi 52014/2/26

ID 生成のパターン

1. SQL Database の自動連番を使う• スケールしない、耐障害性を考慮すると複数台必要

2. ID Provider が完全に独立して存在する• GUID 等、 128bit 16 byte

3. 擬似 ID Provider が、擬似 ID を生成し、 UNIQUE 性は別システムで担保される

4. ID Provider の Network Service を使う• Azure Cache, memcached, redis の increment 等

5. ID Provider の Cluster Service が実装されていて Cluster 内で合意をとって ID を生成する• snowflake

kyrt @takekazuomi 6

最初の2つ

• SQL Database の利用• 秒間の発番数、同時接続数に問題なければ、従来どおり利用可能• 上記の問題があるなら、複数の DB を使う (sharding) という方法も

ある• しかし、仕組みとしてはちょっと重い。コストも高い。• 秒間 100 程度まで

• GUID の利用• クライアントで完結するので、速くてスケールするしかし• 128bit あって長い( 16 byte)• 時系列で並ばない→ 時間由来のデータを prefix にすることで解決

kyrt @takekazuomi 7

時系列のキーの例

.Net なら、 Tikcs などを使う

こんな感じvar id =

string.Format("{0:D19}{1:N}",DateTime.UtcNow.Ticks, Guid.NewGuid());

var reverseId =

string.Format("{0:D19}{1:N}“,long.MaxValue-DateTime.UtcNow.Ticks, Guid.NewGuid());

結果0635317467093215594d1931d619d7041c69ececd37383ca4ae85880545697615502266d18953688dc4fbdb84da60f4d8e25c8

しかし長い・・・・・ 19+32 で 51 文字。(工夫の余地はあるけど)kyrt @takekazuomi 8

擬似 ID Provider パターン

• Client で擬似的に ID を生成して、 UNIQUE 性は、永続化レイヤーで担保• retry の発生頻度にパフォー

マンスが依存• 性能が永続化レイヤーに依存• スケールのためには永続化レ

イヤーの分散が必要• SQL Database  < Storage

Table ( 分散の容易度 )

kyrt @takekazuomi 9

SQL Database (Windows Azure)

Storage Table

or

④ retry

Client 永続化レイヤー

① 擬似 ID で Insert

② 重複無しで成功

③ 重複有りで失敗

Cache などの Network Service を利用

• RBD の自動連番より小さなレイテンシー (1-2ms)• ID は時系列で増える• 耐障害性に課題

• HA 構成、永続化オプションを考慮

• 工夫• 起動時の時間+ incremental

number• 障害後にかぶらないように

kyrt @takekazuomi 10

Client Cache

ID を取得

Windows Azure Cache

memcached

or

redis

or

課題整理

1. latency (レイテンシー)HA のために、 Node 間通信、永続化に時間がかかる。 retry が発生すると時間がかかる

2. reliability (信頼性)採番系が一箇所なのは、 UNIQUE の担保には有利だが、障害に弱くなる。→分散すれば Ok

3. scalability (スケーラビリティ)分散が必要。 ID 生成が分散して Node 間通信が少なければ、スケーラビリティが上がる

4. data size (データサイズ)data size を大きくして冗長性を増せば、 retry の頻度は下がる

kyrt @takekazuomi 11

特性の比較

kyrt @takekazuomi 12

latency reliability scalability data size

SQL 自動連番 ◯ × × ◯

GUID 等 ◯ ◯ ◯ ×

Pseudo ID and Retry △※ 1 ◯ ◯ △

Cache ◯ × △ ◯

Snowflake ◯ ◯ ◯ ◯

※ 1 Data Size を小さくすると、衝突が起きやすくなるのでレイテンシーが上がる

ここまでのまとめ

• 永続化ストレージ• latency (↓)、 reliability (↑)、 scalability (↓)、 data size (↑)• scalability 改善には、パーティショニングが必要 → パーテーションを跨い

だ UNIQUE 性に制限、 data size (↓)

• On Memory• latency (↑)、 reliability (↓)、 scalability (↓)、 data size (↓)• reliability 改善

• 複数 Node で HA 構成にすれば良い。しかし、更新の度に、 Node 間で通信して合意をとると latency が悪化

• scalability 改善• シングル Node だと Node の性能上限=スケールの上限になってしまうので、複数

Node 構成にしたい。しかし、

kyrt @takekazuomi 13

↑ :良↓ :悪

こんなのがあったら

•GUID のように速く•SQL の自動採番のように並んで•簡単に使える•そんなに長くない (longぐらいで入ると嬉しい)

kyrt @takekazuomi 14

twitter snowflakehttps://github.com/twitter/snowflake/

kyrt @takekazuomi 15

snowflake の短い説明

• snowflake は、 Twitter 社が作成した、 UNIQUE な ID 生成のネットワークサービス。いくつかの簡単な保証で高いスケーラビリティを実現

• Twitter 社が、 MySQL から Cassandra に移行するにあたって、 Cassandra には シーケンシャルな id 生成の仕組みが無かったことから作成• 参考: Twitter IDs, JSON and Snowflake

https://dev.twitter.com/docs/twitter-ids-json-and-snowflake• ソースは https://github.com/twitter/snowflake/ に公開• ライセンス、 Apache License, Version 2.0

kyrt @takekazuomi 162014/2/26

基本的なアイディア

• Clock Skew (クロックスキュー)に上手く対応することで、オンメモリの計算だけで UNIQ な ID を生成する

• 永続化レイヤーの支援無しに UNIQ な ID が生成できる、 ID 生成はオンメモリなので速い( 10k ids per second per process Snowflake https://github.com/twitter/snowflake/ )というのが特徴

• GUID v1 と似ているが、半分のデータ量 64bit(long) で、おおよそ時系列で増えていく「 (Roughly) Time Ordered 」

kyrt @takekazuomi 17

データ構造

• snowflake では、 64bit を上記のように分割して使います• time が時間由来の数字でミリ秒単位• machine id は、 datacenter id と、 worker id で構成されていて、

Cluster 内の Node固有の値• sequence number は、同一時間の連番

kyrt @takekazuomi 18

ポイント

• 時間由来のデータが先頭 41bit なので発番の時間順に並びます• ms で 41bit だと  (2^41)*(10^-3)/60/60/24/365 で約 69年

•各インスタンスは、 クラスター内で UNIQUE な、 machine id を持ちます• machine id が重複しない限りは ID は重複しない

• 同時間内の発番では、 sequence number がインクリメントされます• ms 内の発番は、 2^12 = 4096 まで

採番情報は on memory のみで処理kyrt @takekazuomi 19

time skew対策

• 最後に発番してから timestamp が戻っていないか確認 L63• 巻き戻っていればエラーで帰る(呼び出し側が再試行する)

kyrt @takekazuomi 21

time 41bit の有効利用

•開始時間を採番の開始時間と合わせて bit を有効利用• TwEpoch は、 2010/11/04 。 2010/11/01 + 69年

kyrt @takekazuomi 22

sequence

• 同一 timestamp なら、 _sequence をインクリメントして採番 `L72 <https://gist.github.com/takekazuomi/9571376#file-idworker-cs-L72>`_• timestamp が進んでいれば、 _sequence = 0 で採番 `L82

<https://gist.github.com/takekazuomi/9571376#file-idworker-cs-L82>`_• 同一 timestamp 内で、 _sequence がオーバーフローした場

合は、 timestamp が変わるまで待つ `L75 <https://gist.github.com/takekazuomi/9571376#file-idworker-cs-L75>`_

kyrt @takekazuomi 23

起動時にWorker Id の重複を確認

構成

• snowflake の Worker は複数の Node で構成• Node の起動時に Worker Id

の重複を zookeeper を使って担保

• GUID では、 MAC Address 48bit が、 machine Id相当

kyrt @takekazuomi 24

Client

snowflake cluster

ID 要求

zookeeper cluster

machine id を重複させない仕組

• snowflake では、 machine id の下位 5bit の Worker Id をzookeeper で管理しています• 起動時に Worker Id で、 Ephemeral Nodes を作成

kyrt @takekazuomi 25

/workerIdZkPath

/

/0 /1 /2 /n

worker id の ephemeral node

1. 同じ Node 名では1つのみ2. session が切れると node は消える

kyrt @takekazuomi 26

Micorosoft Azure でどうするか

• Azure Blob のリースを使うとほぼ同じことができます• Worker Id の path の lease が取れば、重複なしで起動 Ok• インスタンスが生きてる間は、 Lease を更新• 参考: Cloud Design Patterns

• patterns & practices• Leader Election Pattern 、 BlobDistributedMutex

/workerIdZkPath

/

/0 /2 /n/1

Blob Lease でBlobDistributedMutex 利用

まとめ

• snowflake は、 on memory で時間情報を元に高速に ID を生成する• ID の一部には machine   id が含まれていて、 node の起動

時に zookeeper を使って重複を確認する• 起動後は、 node-zookeeper 間の通信は ephemeral nodes

の keep alive のみ• 時間の巻き戻り対策がされている( time service対策)• zookeeper の ephemeral nodes 相当の機能は Azure Blob

で実装できる

kyrt @takekazuomi 27

Appendix

2014/2/26 kyrt @takekazuomi 28

リファレンス• Twitter IDs, JSON and Snowflake

• https://dev.twitter.com/docs/twitter-ids-json-and-snowflake

• snowflake source code• https://github.com/twitter/snowflake/

• Cloud Design Patterns / patterns & practices• Leader Election Pattern http://msdn.microsoft.com/en-us/library/dn568104.aspx• BlobDistributedMutex Code http://aka.ms/cloud-design-patterns-sample

• Apache ZooKeeper• http://zookeeper.apache.org/• http://zookeeper.apache.org/doc/r3.2.1/zookeeperProgrammers.html#Ephemeral+Nodes

• Twitter の snowflake について(お勧め)• http://www.slideshare.net/moaikids/20130901-snowflake

• 全ての情報は 2014/3/29 時点のものです。2014/2/12 kyrt @takekazuomi 29