Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Future LT#12 UUIDは本当に一意を保証してくれるのか?
Search
kkuchikata
August 24, 2021
Technology
0
1.1k
Future LT#12 UUIDは本当に一意を保証してくれるのか?
フューチャーアーキテクトのLT大会第12回(発表資料)
UUIDが本当に一意か疑って調査した話
kkuchikata
August 24, 2021
Tweet
Share
Other Decks in Technology
See All in Technology
誰も全体を知らない ~ ロールの垣根を超えて引き上げる開発生産性 / Boosting Development Productivity Across Roles
kakehashi
1
220
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
Lambda10周年!Lambdaは何をもたらしたか
smt7174
2
110
VideoMamba: State Space Model for Efficient Video Understanding
chou500
0
190
Platform Engineering for Software Developers and Architects
syntasso
1
520
AWS Media Services 最新サービスアップデート 2024
eijikominami
0
200
B2B SaaSから見た最近のC#/.NETの進化
sansantech
PRO
0
760
100 名超が参加した日経グループ横断の競技型 AWS 学習イベント「Nikkei Group AWS GameDay」の紹介/mediajaws202411
nikkei_engineer_recruiting
1
170
AGIについてChatGPTに聞いてみた
blueb
0
130
Shopifyアプリ開発における Shopifyの機能活用
sonatard
4
250
Lambdaと地方とコミュニティ
miu_crescent
2
370
iOS/Androidで同じUI体験をネ イティブで作成する際に気をつ けたい落とし穴
fumiyasac0921
1
110
Featured
See All Featured
Optimizing for Happiness
mojombo
376
70k
Visualization
eitanlees
145
15k
The Cult of Friendly URLs
andyhume
78
6k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Site-Speed That Sticks
csswizardry
0
24
The Invisible Side of Design
smashingmag
298
50k
Building Better People: How to give real-time feedback that sticks.
wjessup
364
19k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
410
Designing Experiences People Love
moore
138
23k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Transcript
今だから言える 『UUIDは本当に一意を保証 してくれるのか?』 疑ってました
自己紹介 ・名前 朽方邦孝 ・所属 フューチャーアーキテクト 金融サービス事業部 ・得意な言語 SQL
UUIDとは 出典: IT用語辞典 e-Words 一意? (・。・;
UUIDとは 出典:https://securesamba.com/term/uuid/ 一意じゃないの? (・。・;
UUIDとシーケンスの違い UUID 数値シーケンス サンプル 0aebf1c2fd8811eb849800059a3c7a00 1,2,3,4~等 順序 ランダム(連番にはならない) 連続 その他
IDを推測し難い 連番のためIDが推測しやすい データサイズ ※ 16BYTE(=128bit / 8) ⇒DBに入れるとINDEXが重い 2BYTE(1から32767) 4BYTE(1から2147483647) 8BYTE(1から9223372036854775807) マスタ 存在しない 必要(1箇所で管理) 同時実行 可 (どのサーバ上でも生成可能) 不可 (マスタがあるサーバでのみ生成可、複数箇 所で利用される場合は順番待ちでボトルネック になりやすい) ※ postgreSQLのカラムサイズの場合
ITエンジニア風に説明すると • 1BITで、0/1の2通りを記録可能 • 128BITで、2^128通り記録可能 • この128bitに一定のアルゴリズム(後述)で0/1をセットしたものがUUID
身近なもので例えると • 1円玉を裏表適当に一直線に128枚並べる、この128枚1セットが1UUID • 128枚セットを延々とランダムに並べ続け、 全く同じ並び順がでる確率が、UUIDが衝突する確率 • 組み合わせは2^128 =340,282,366,920,938,000,000,000,000,000,000,000,000 340澗2823溝6692穣938𥝱
340兆の1兆倍 まったくピンと来ないけれど
UUIDで同じ値が発生する確率(128bit) • 50%弱の確率で衝突が発生するのに、必要な試行回数 ◦ 2^(128/2)=18,446,744,073,709,600,000 1844京6744兆0737億960万 出典: https://ja.wikipedia.org/wiki/誕生日攻撃 2600億回試行で 0.0000000000000001%
(10^-18)
【参考】めったに発生しないもの 確率 備考 落雷(死亡) 0.0001% 2014年米国(25人/260万人) 航空機(死亡) 0.000034% 米国の飛行機に1回搭乗し墜落する確率 宝くじ
0.00001% 2021サマージャンボ宝くじ(1/1000万)
UUIDがバカでかい値なのはわ かったけど どういう仕組みで一意なの?
UUIDのバージョン Ver 生成値 一意性 1 60bit:タイムスタンプ(1/10億秒単位) 14bit:クロックシーケンス 48bit:ノード(MACアドレス、または乱数) 理論的には衝突し得る 2
28bit:タイムスタンプ 6bit:クロックシーケンス 40bit:ローカルID/ローカルドメイン 48bit:ノード 理論的には衝突し得る (DCEシステムにおける権限認可 を目的に設計されたもの、システ ム開発では使用しない) 3/5 122bit:ユニークな名前(URL等)をハッシュ関数で変換 インプットが一意であれば担保 4 122bit:乱数 理論的には衝突し得る ※4bitはバージョン、2bitはバリアントを表す
UUID Ver1の衝突検証 (チート有り)
UUID Ver1のデータ構成 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 11010101011101011010100100010100111111001111100000010001111010111010010100110101000000000000010110011010001111000111101000000000 11010101011101011010100100010101111111001111100000010001111010111010010100110110000000000000010110011010001111000111101000000000 11010101011101011010100100010110111111001111100000010001111010111010010100110111000000000000010110011010001111000111101000000000 11010101011101011010100100010111111111001111100000010001111010111010010100111000000000000000010110011010001111000111101000000000 11010101011101011010100100011000111111001111100000010001111010111010010100111001000000000000010110011010001111000111101000000000 11010101011101011010100100011001111111001111100000010001111010111010010100111010000000000000010110011010001111000111101000000000 11010101011101011010100100011010111111001111100000010001111010111010010100111011000000000000010110011010001111000111101000000000
11010101011101011010100100011011111111001111100000010001111010111010010100111100000000000000010110011010001111000111101000000000 11010101011101011010100100011100111111001111100000010001111010111010010100111101000000000000010110011010001111000111101000000000 48 ノード(MACアドレス) 32 タイムスタンプ 下位 2+14 クロック シーケンス 4 ver 16 タイムスタンプ 中位 12 タイムスタンプ 上位 同一サーバで実行する 場合は同値 シーケンス、+1する 2^14=16384回で0に戻る 0.0000000001秒単位で保持 (上記以上の間隔で生成すると必ず一意)
つまり、同一サーバ上で 1/10億秒以内に 16385回以上生成すると 100%ID衝突が発生
(スーパーコンピュータ並の演算能力さえあれば) 実現可能ですね (・∀・)
私のPCスペックでは 500,000/秒程度しか不可能な ので、今回はチートで時を止 めます (時刻取得が必ず固定値を返すように魔改造)
UUID Ver1の衝突実験 (0.0000000001秒で16385UUIDを生成できるサーバを使用した体) クロックシーケンスが1周し、同じ値が発生 ※DBはpostgreSQL13を使用
UUID Ver4の衝突検証
UUID Ver4のデータ構成 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 00001111100011100100010101001001100010110110100101000110001000111010010010100010010010110101001010111110011011010010100111011000 10011011111100011010010010111010011011111010101101001101010010101000000101101110111010010110101010110010101101000101100110010001 01100010101011100110101011101010111011110001010001001010011101101001101001101010001110111010001110011111001100101010111000101111 00000010010101101111100000011011000111111110100101001010000111011011101111100101111110010001010110111001111101101111100101011101 11010111110100110100010110010011110100100010010101000010101111011001001110111000000000100100100011001000011111001101110000011101 01110011110100010110100101000010110101101110001001001100111111101011111111011010100111000101000010000100010111101001000110011101 00000001111000110010011000010011001110010010011001000001100111001011100011110001011110110100101101010100010010101010011011111010
11111010000101001011110001101011110000100111011001000001000111001010100110100000010010000100111010011101010110010001010111101100 00100100100010001000010110101100110000110111111001000111011011101000010001010101011010001111111111101101101000111001011111110011 62 ランダム 2 var 4 ver 48 ランダム 12 ランダム 固定値:6bit ランダム:122bit
UUID Ver4で同じ値が発生する確率(122bit) • 50%弱の確率で衝突が発生するのに、必要な試行回数 ◦ 2^(122/2)=2,305,843,009,213,690,000 ◦ 230京5843兆92億1369万 出典: https://ja.wikipedia.org/wiki/誕生日攻撃
UUID Ver4の衝突を観測するのに必要なDBサイズ 230京5843兆92億1369万レコード×46Byte(16Byte+レコード情報)※ =98,784,247,808GB =96,468,992TB =94,208PB =92EB ※DBはpostgreSQL13を使用 INDEXを含まない、凡そのサイズ INDEX含む場合はさらに倍程度必要
出典:情報通信白書平成26年版 全世界の 92EB
UUID Ver4の衝突を観測するのに必要なDB費用 230京件、92EBのデータを保持するには、 1DBサーバ(9646TB)×1万台が必要 1DBサーバ内に23万テーブル作成 (1テーブルに10億レコードを保持) 月120万$×1万台 ×3ヶ月※ =¥3,938,476,542,000 ≒4兆円
※50万件/1secのペースで 1万台×64CPUで並列実行 超々ざっくりの適当な計算です <(_ _)>
UUIDを3000万件INSERT時の処理速度変化① (100万件毎のINSERT時間) 0 50 100 150 200 250 300 1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 INDEX 有り INDEX 無し 単位(秒) 単位(100万件) 総レコード 件数 INDEX 有り INDEX 無し 1M 13.49 1.97 2M 12.28 1.91 3M 12.77 1.95 4M 14.61 1.97 5M 24.47 2.02 6M 33.86 2.44 7M 44.99 2.17 8M 42.92 2.24 9M 48.11 2.01 10M 57.6 2.38 11M 54.74 2.23 12M 59.61 2.3 13M 75.68 1.97 14M 76.19 2.6 15M 74.11 2.18 16M 62.93 2.11 17M 78.54 1.9 18M 76.34 1.93 19M 69.48 2.46 20M 77.47 2.24 21M 104.58 2.42 22M 112.26 2.29 23M 126.25 2.04 24M 130.18 2.21 25M 153.48 1.81 26M 198.14 1.94 27M 218.42 1.91 28M 225.18 2.79 29M 246.75 2.5 30M 235.41 2.7 単位(秒)
UUIDを3000万件INSERT時の処理速度変化② (3000万件INSERT完了までの累計時間) 単位(秒) 単位(100万件) 0 500 1000 1500 2000 2500
3000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 INDEX有り INDEX無し 自分のノートPC内で3回 実施した平均値 ※環境・性能によって曲 線の傾きは変わります
まとめ • V1 ◦ 累計生成回数によらず衝突発生確率は一定 (タイムスタンプを含むため) ◦ 衝突を発生させるにはスーパーコンピュータ並の性能が必要 • V4
◦ 累計生成回数に応じて、衝突発生確率が指数関数的に上がる ◦ 衝突発生確率が現実的な値になるほど、DBにデータを保持するのは、 物理的・処理性能的に困難(大幅な速度低下が見込まれる)
None