DocumentDB
Deep Dive
Takekazu Omi
takekazu.omi@kyrt.in
2017/4/22 R.1.1
自己紹介
近江 武一
JAZUG Azure Storage 担当(自称)
Microsoft MVP for Azure
http://www.slideshare.net/takekazuomi
kyrt inc 2
kyrt.in
github.com/takekazuom
i
white paper
監訳
2016/4/22
はじめに
DocumentDBの簡単な紹介
2016/4/22 kyrt inc 3
本日の話題
今日のネタのために必要最低限な
DocumentDBの紹介
//BUILD 2016 、パーテーションの話
partitioned collection
server side partitioning
kyrt inc 42016/4/22
DocumentDB Capabilities
1. SQL and JavaScript - schema free
⇨自動 tree path based indexing
⇨Schemas や 事前のセカンダリインデックス定義を必
要としない
⇨SQL and JavaScript言語に統合されたクエリ、 hash,
range、spatial(位置情報)
⇨JavaScriptに統合された、複数ドキュメントに渡ったト
ランザクション
kyrt inc 52016/4/22
https://channel9.msdn.com/events/Ignite/Australia-2017/DA335b
DocumentDB Capabilities
2. レイテンシー保証
⇨< 10ms read/<15ms write P99
⇨リクエストのローカルリージョン処理
3. 書き込み最適化、SSDに最適化された、
latch-free database
kyrt inc 62016/4/22
DocumentDB Capabilities
4. 複数の整合性レベル
⇨ Strong
⇨ Bounded staleness
⇨ Session
⇨ Eventual
5. Elastic で 制限なしの global scale
⇨ ローカルとグローバルで、別々にスケールするスループッ
トとストレージ
⇨ 透過的な partition management と routing
kyrt inc 72016/4/22
LB Resource
Governor
Transport
Admission Control
Database Engine
Resource
Controller
JavaScript
Runtime
TC
Bw-tree++ (Latch free,
Resource governed, Log
structured)
RSM
Query
Engine
Index
Manager
Federation
VMs
Replica
Database Engine
• DocumentDB サービスは、リングトポロジ(別名フェデレーショ
ン)を使用したオーバーレイネットワーク
• リソースはパーテーション分割され federation、データセンター、
リージョンに跨る
• パーティションはレプリカセットで高可用性構成
• レプリカは、DocumentDB DBエンジンをホストし、レプリケー
ションプロトコルとローカル永続性を実装
https://channel9.msdn.com/events/Ignite/Australia-2017/DA335b
2016/4/22 kyrt inc 8
1. パーティションのデータはSSDのローカ
ルディスクに保存
2. パーティションの可用性はリプリケー
ションで担保
kyrt inc 92016/4/22
https://docs.microsoft.com/ja-jp/azure/documentdb/documentdb-partition-data
論理構造
リソースモデル
2016/4/22 kyrt inc 10
リソース階層モデル
kyrt inc 112016/4/22
https://docs.microsoft.com/ja-jp/azure/documentdb/documentdb-resources#a-namehierarchical-resource-modela階層型リソース-モデル
② ③①
①database -> ②collection -> ③document
の階層構造
コレクション
 コレクションは論理リソース、1 つ以上の物理パーティショ
ンで構成
 コレクション内のパーティション数は、ストレージのサイズ
やコレクションのプロビジョニング済みスループットに基づ
いて DocumentDB によって決定(?)
 DocumentDB のすべてのパーティションには固定された
量の SSD を使用したストレージが関連付けられる
 パーティションは可用性を高めるためにレプリケートされる
kyrt inc 122016/4/22
https://docs.microsoft.com/ja-jp/azure/documentdb/documentdb-resources#a-namecollectionsaコレクション
RU(Request Unit)
RUは、コンピューティング・
リソースの消費量を表す単
位
予約したRU分を利用するこ
とができる
予約RUの量が課金に反映
される
予約RUを超えるとスロットリ
ングされる
kyrt inc 132016/4/22
% CPU% memory
% IOPS
Partitionの活用
2016/4/22 kyrt inc 14
Partitioning Model
kyrt inc 152016/4/22
CollectionPartition1
Partition2
Partition3
PartitionN
Partition….
Partitioning Model
kyrt inc 162016/4/22
Partition Key = city
東京
ロンドン
パリ
・・・
北京
ベルリン
ボストン
福岡
ニューデリー
札幌
ボストン
シアトル
横浜
👎 特定のパーテーションキーへの集中
kyrt inc 172016/4/22
東京
ロンドン
パリ
・・・
北京
ベルリン
ボストン
福岡
ニューデリー
札幌
ボストン
シアトル
横浜
👍アクセスを全体へ
kyrt inc 182016/4/22
東京
ロンドン
パリ
・・・
北京
ベルリン
ボストン
福岡
ニューデリー
札幌
ボストン
シアトル
横浜
👍cross-partition lookupを最小にせよ
kyrt inc 192016/4/22
東京
ロンドン
パリ
・・・
北京
ベルリン
ボストン
福岡
ニューデリー
札幌
ボストン
シアトル
横浜
Partition Key Design Goals
 いつも全体的に負荷がかかるようにする
⇨ Hotspotのパーテーションを作らない
 全てのパーティションにファンアウトするようなクエリーを避ける
⇨ SDKは賢い、Where句に partitionKey 入れるべし
 パーティションキーを指定した場合、<1GB未満で1,000RU /秒未満に
⇨ 結果が大きすぎたり、RU使いすぎのクエリはNG
 パーティションキーの選択にトランザクションのニーズを反映する
⇨ 同一パーテーション内の場合、トランザクションナルな更新が可能
2016/4/22 kyrt inc 20
Partition Key の選択
Partition Keyの選択
 データアクセスパターンを理解し、もっとも多い操作に最
適化する
 よく使われる TOP Nクエリーのフィルター条件から選ぶ
General Tips:
 HOT partition を作らない
 高いカーディナリティ。
More partition key values = happiness 😊
2016/4/22 kyrt inc 21
重要な特性
 パーティションのデータはSSDのローカルディスクに保存
 パーティションの可用性はリプリケーションで担保
 パーティションはハッシュのみ(レンジなし)
 通常1 物理パーティションに複数のパーティション キーが入
る
 パーティション キーが、パーティションにまたがることは無い
 パーティションが溢れた場合、パーテーションキーを別パー
テーションに移動させる
kyrt inc 222016/4/22
https://docs.microsoft.com/ja-jp/azure/documentdb/documentdb-partition-data
よし確認だ
2016/4/22 kyrt inc 23
documentdb-benchmark
GitHubのDocumentDB .NET SDKのサンプ
ルコードの中のベンチマーク
kyrt inc 242016/4/22
https://github.com/Azure/azure-documentdb-dotnet/tree/master/samples/documentdb-benchmark
待ってます
kyrt inc 252016/4/22
秒間の書込数
使ったRU数
ベンチマークの内容
 右記のようなJSONを100万件
Insert
 idとpartitionKeyはguidで毎回生
成
 Consistencyは、session
 Indexing Policy
https://goo.gl/nrYA89
 コレクションの予約RUは、2万か
ら25万
 DS5_V2 1台でカジュアルに測
定
{
"partitionKey": "dd68c787-8abf-4ce1-8153-22aa652dbf8f",
"id": "d12df4b1-d572-4f1d-bc61-78894e17c051",
"playerId": "a067ff",
"hashedId": "bb0091",
"countryCode": "hk",
"nickname": "DannyBoy",
"nicknameLower": "dannyboy",
"score": 0,
"secondaryScore": 18,
"indexScore": 0.18,
"level": 1,
・・・・・ snip ・・・・・
"chatMessages": [ {
"playerId": "67879d8e",
"name": "lee",
"message": "hi",
"time": 760455049,
"notificationType": "None"
kyrt inc 262016/4/22
書込数/予約RU
1,192
2,402
4,804
9,472
14,068
0
2,000
4,000
6,000
8,000
10,000
12,000
14,000
16,000
20,000 40,000 80,000 160,000 250,000
書込数
予約RU
kyrt inc 272016/4/22
Request Charge
DocumentDB では、使ったリクエストで使ったRUが
わかる
レスポンスの 「x-ms-request-charge」で、リクエスト
の処理に使われたRUが帰る
.NET SDK では、 ResourceResponse<T>の
RequestCharge プロパティ
ポータルの DocumentDB クエリ エクスプローラー
でも表示
kyrt inc 282016/4/22
実RU/予約RU
12,495
25,172
50,349
99,266
147,438
0
20,000
40,000
60,000
80,000
100,000
120,000
140,000
160,000
20,000 40,000 80,000 160,000 250,000
実RU
予約RU
kyrt inc 292016/4/22
実RUの取得
CreateDocumentAsync の戻り、
ResourceResponce<T>.
RequestCharge に使ったRUが入っている
https://goo.gl/y7zZtP
REST APIでは、「x-ms-request-charge: 」の
レスポンスヘッダー
kyrt inc 302016/4/22
書込当たりの実RU
予約RU writes/s RU/s RU/write
20,000 1,192 12,495 10.5
40,000 2,402 25,172 10.5
80,000 4,804 50,349 10.5
160,000 9,472 99,266 10.5
250,000 14,068 147,438 10.5
kyrt inc 312016/4/22
https://docs.microsoft.com/ja-jp/azure/documentdb/documentdb-request-units#a-nameestimating-throughput-needsaスループットの
ニーズの推定
要求ユニット計算ツール
kyrt inc 322016/4/22
https://www.documentdb.com/capacityplanner#
Partitionの状況の確認
2016/4/22 kyrt inc 33
partition-stats
ベンチマークと同じレポジトリ
Collection のquota情報取得
CollectionのURLを「x-ms-documentdb-
populatequotainfo」を付けてGET
Collectionのパーテーション数、 ドキュメント
数、ドキュメントサイズ、それぞれのパーテー
ションのドキュメントサイズが分かる
kyrt inc 342016/4/22
https://github.com/Azure/azure-documentdb-dotnet/tree/master/samples/partition-stats
1. collectionの利用状
況取得
2. partition key range
情報取得
3. 個々のpartitionの
利用状況取得
kyrt inc 352016/4/22
25
10Gのやつだと1になる
Partitioned Collectionは25
Collectionの情報取得
kyrt inc 362016/4/22
リクエスト
GET https:// ・・・・・・・ /dbs/db01/colls/datawp01 HTTP/1.1
x-ms-documentdb-populatequotainfo: True
レスポンス
x-ms-resource-quota: storedProcedures=100;triggers=25;functions=25;collect…
x-ms-resource-usage: storedProcedures=0;triggers=0;functions=0;collectionS…
1. storedProcedures
2. triggers
3. functions
4. collectionSize
5. documentsCount
6. documentsSize
Quota と Usage それぞれ
collectionのURI
quota情報を要求
Partition key range の取得
kyrt inc 372016/4/22
リクエスト
GET https://・・・・・・・/dbs/db01/colls/datawp01/pkranges HTTP/1.1
レスポンス
{
"_rid": "-agDAI5mHQA=",
"PartitionKeyRanges": [
{
"_rid": "-agDAI5mHQACAAAAAAAAUA==",
"id": "0",
“_etag”: “”00008600-0000-0000-0000-58fa994b0000“",
"minInclusive": "",
"maxExclusive": "05C1A53DB92960",
"ridPrefix": 0,
レスポンスのBodyにパーテーション
レンジの配列が帰る
パーテーションレンジのId
パーテーションの範囲
Partitionの情報取得
kyrt inc 382016/4/22
リクエスト
GET https://・・・・・・・/dbs/db01/colls/datawp01/docs HTTP/1.1
x-ms-documentdb-partitionkeyrangeid: 0
レスポンス
x-ms-resource-quota: documentSize=10240;documentsSize=10485760; ・・・・・・・
x-ms-resource-usage: documentSize=5;documentsSize=4371;document ・・・・・・・
document rootのURI
partition key rangeのid
partition map (partition key range) を事前に所得
Hot partition
2016/4/22 kyrt inc 39
キーの偏在
Hot キーのパターンを少なくしHot partitionを
作成
4万RU、キーは2つだけ
kyrt inc 402016/4/22
340 write/s, 3,600RU
kyrt inc 412016/4/22
25パーテーションを2つ利用
4万RU*2 / 25 = 3600
しかも20GBで (250GB/25*2=20GB)
{"Errors":["Storage quota for 'Document' exceeded."]}
スロットリング(429)
Hot partition は深刻
Partitioned collectionでは、キーを散らさないとお
金を捨てるようなもの
最悪、25万RU(170万=25万/100*683円)で、
68,300円程度の性能しか出ない
Partition Keyの設計は重要
Hot partition は、Collectionを分ける手もある
kyrt inc 422016/4/22
Partition 指定の効果
2016/4/22 kyrt inc 43
Short Answer
松崎さんのBlogを読もう
Azure DocumentDB – Understanding key
features
https://blogs.msdn.microsoft.com/tsmatsuz/201
6/12/07/azure-documentdb-and-mongodb-
partitioning-replication-indexing/
kyrt inc 442016/4/22
もう少し長い説明
DocumentDBのクライアント(.NET, Java, node.js,
python)は、 Fan-out Queryをサポート
複数パーテーションにクエリーを投げてまとめて結果
を返す機能がある。
クエリーは並列で実行される。.NETでは、並列度は、
FeedOptions.MaxDegreeOfParallelismで指定
クエリーに、 Partition Keyが指定されていると、該当
のパーテーションだけにリクエストが送られる
kyrt inc 452016/4/22
Partition Key指定のなにが嬉しいのか?
Fan-out Queryの場合、パーテーションの数
(25回)リクエストが処理
1. クライアント負荷が大きい
2. サーバー側では、RUを消費
kyrt inc 462016/4/22
QueryにPartition Keyを入るは吉
クライアントでPartitionを見つける仕組み
Partition key range の情報からhashの範囲が
分かる
hashは、MurmurHash のアルゴリズムがベース
になっている
松崎さんがコードを公開してくれてる
https://github.com/tsmatsuz/DocumentDbPart
itionResolveSample
松崎さん ありがとう。
kyrt inc 472016/4/22
おまけ
2016/4/22 kyrt inc 48
Bw-Tree
 Bw-Treeは、SQL Server のインメモリ OLTP でも、メモリ最
適化非クラスター化インデックスで使われている
 ラッチフリー、マルチコア環境向むけに最適化した高速B+ツ
リーの亜種
 The Bw-Tree: A B-tree for New Hardware Platforms
https://www.microsoft.com/en-
us/research/publication/the-bw-tree-a-b-tree-for-new-
hardware/
kyrt inc 492016/4/22
着目点
Design for multi-core.
⇨Multi-core CPUの性能を活かすにはラッチがブロッ
クになる
⇨multi-core processor のパフォーマンスは、CPU
cacheのヒット率に依存する
Design for Modern Storage Devices
⇨Bw-Treeは、SSDをターゲットにしている。
⇨Bw-Tree は、log structuring な構造を取ることで、
SSDのFTLレイヤーの影響を回避する
kyrt inc 502016/4/22
kyrt inc 512016/4/22
MurmurHash
1. Austin Appleby氏が考案
2. 衝突困難性と一様性に優れる
3. 計算コストがMD5等よりも圧倒的に優れる
4. 非暗号ハッシュアルゴリム
 MurmurHash
https://en.wikipedia.org/wiki/MurmurHash
 高速ハッシュアルゴリズム
http://www.yosbits.com/wordpress/?p=1442
kyrt inc 522016/4/22
kyrt inc 532016/4/22
ありがとうございました

Global Azure Bootcamp 2017 DocumentDB Deep Dive

Editor's Notes

  • #4 Azure使ったことある de:code
  • #5 //BUILD 2016
  • #7 1Kぐらいで、read 5ms以下、write 10ms
  • #8 ステルネス
  • #9 論理構成 リージョン、データセンター、フェデレーション、フォールトドメイン、レプリカ 物理構成 リソース、パテーションセット、パテーション、レプリカに置かれる。
  • #10 この仕組で上手くいくのかって話は、一貫性の話もしないといけません。
  • #25 グレートなのは良いけど、SDKのソースはまだ無いのね
  • #33 11.05で計算しているので、実測より若干多めだけど、妥当なせん。 でも、予約値は少々小さめにでている。
  • #51 FTL(Flash Translation Layer) 通常のHDDと同じように扱っても大丈夫にするためのレイヤー
  • #53 ムームーハッシュだと思う