Amazon Web Services ブログ
スキーマ設計を通じた Amazon DynamoDB スキャンレイテンシーの最適化
この記事では、Amazon DynamoDB のテーブル構造がスキャンパフォーマンスにどのように影響するかについて説明し、テーブルのスキャン時間を最適化する方法をご紹介します。
Amazon DynamoDB は、柔軟なスキーマを使用できる NoSQL データベースです。これは、項目それぞれにどのような属性が存在するかという点で、同じテーブル内の項目が互いに異なることを意味します。
DynamoDB のスキーマとアクセスパターンの大部分は GetItem 操作と Query 操作を中心に方向づけと最適化が行われ、これによってテーブルまたはインデックスから単一項目にアクセスするときに一貫した 1 桁台のミリ秒での応答時間が提供されますが、ユースケースとアクセスパターンには、テーブルとインデックスのスキャンが必要なものもあります。
概要
柔軟なスキーマを持つデータベースでは、データベーススキャンから返されたすべての項目について、ネットワーク応答にデータだけでなく、メタデータも含まれています。このメタデータには、各属性の属性名とデータタイプが含まれる場合があります。
各項目により多くの属性を追加すると、クライアントオーバーヘッドもいくらか追加されます。これは、ネットワーク応答の各列が、適切なクライアントデータ構造にマーシャルされる必要があるからです。その例は Python ディクショナリー、Node.js マップ、Java オブジェクトなどです。
属性メタデータは容量を消費するため、DynamoDB 応答の 1 MB 上限に収まる項目数が少なくなります。その結果として、データのスキャンに必要な往復回数が増えることになります。
テスト方法
パーティションキーとソートキー (どちらも文字列) で構成されるプライマリキーというシンプルな構造のテーブルを 1 つ作成しました。144 個のランダムな文字の文字列が含まれる field1 という名前の 3 番目の文字列属性もあります。
また、3 文字および 6 文字の属性値の両方を持つ、7 文字の属性名 (field01… field24) の異なる組み合わせを使ったテーブルも作成しました。これらのテーブルには、最初のテーブルと同じプライマリキー構造があります。
柔軟なスキーマを持つ NoSQL データベースは、項目ごとに属性名を保存する必要があります。項目の属性が増える、または属性名が長くなると、項目は属性名を保存するためにより多くの容量を消費します。
最後に、24 個の属性 (それぞれが同じ 7 文字の属性名と 100 文字の属性値を持つ) で別のテーブルを作成しました。
各テーブル構造には、次の測定を行います。
- 10,000 項目の挿入にかかる時間。
- 10,000 項目のスキャンにかかる時間。
- 1 MB の上限に収まる項目数。(DynamoDB には単一のリクエストで取得するデータの量に 1 MB の上限があるため、1 MB すべてを取得するスキャンを実行しました。)
- これらの項目を取得し、クライアントでアンマーシャルするためにかかる時間。
実証結果
以下の表は、結果を要約したものです。
総容量 (MB) | 10,000 項目を書き込む時間 (ミリ秒) | 10,000 項目をスキャンする時間 (ミリ秒) | シングルスレッドスループット (MB/秒) | 1 MB をスキャンする時間 (ミリ秒) | 1 MB スキャンでの項目数 | |
144 文字のデータ属性 1 個 | 2.1 | 5057 | 569 | 3.7 | 238 | 4969 |
3 文字のデータ属性 24 個 | 3.0 | 9359 | 2392 | 1.2 | 797 | 3496 |
6 文字のデータ属性 24 個 | 3.7 | 9928 | 2391 | 1.5 | 682 | 2819 |
100 文字のデータ属性 24 個 | 26.3 | 27,553 | 2819 | 9.4 | 110 | 400 |
これらの特定の数値は、このベンチマークテストのために作成された Python クライアントからのものです。Java および Node.js などの他のプログラミング言語も、多くの項目属性を持つことによる同じようなパフォーマンス特性を示しました。
時間の計測は Python プロセスのクライアント側から行いました。Amazon CloudWatch メトリクス内で示されるクエリ時間は、ネットワーク転送または項目のアンマーシャリングを考慮しないため、同じではありません。
また、4 番目のデータ列にあるスループット数値は、シングルスレッドスキャンのものです。並列スキャンを使用することで、スループットを大幅に高くできたと思われます。
分析
実証結果セクションの表の最初の 2 行では、より多くの属性を持つ項目のテーブルへの書き込みにほぼ 2 倍の時間がかかることがわかります。これらの項目をスキャンするには、ほぼ 4 倍の時間がかかります。これは、すべての項目の属性それぞれをサーバーでマーシャルし、クライアントでアンマーシャルする必要があるからです。
表の最後の 2 行からは、どちらのテストにも 7 文字の属性名を持つ 24 個の属性があるため、10,000 オブジェクトの総容量がどのようにスキャン時間に影響するかがわかります。 3 行目には 6 文字の属性値があり、4 行目には 100 文字の属性値があります。大きなデータの書き込みにはより長い時間 (3 倍) がかかりますが、大幅に大きい項目のスキャンにはわずかに長い (18%) 時間しかかかっていません。
これは、属性の数、およびその後のマーシャリングとアンマーシャリングが、スキャン時間を長くする最も大きな要因であるという結論を支持します。しかし、インデックス、フィルタリング、自動増加などを行う他の属性が存在する場合もあるため、属性が 3 つしかない DynamoDB テーブルは必ずしも現実的なものではありません。
結論
今回の主なポイントは、データベースレベルでの操作に対して実際に必要な数だけの属性を使うということです。属性名メタデータの量を減らすには、残りのデータを単一の属性にまとめます (JSON blob がよいかもしれません)。
このテストから引き出せる必然的な結論は、属性名はディスクおよびネットワークスループット両方の容量を消費するため、属性名はできる限り短くすべきだということです。
著者について
Chad Tindel はニューヨーク勤務の DynamoDB スペシャリストソリューションアーキテクトです。Chad は大企業のお客様と連携して DynamoDB ベースのソリューションの評価、設計、およびデプロイメントを行っています。Amazon に入社する前は、Red Hat、Cloudera、MongoDB、および Elastic で同じような役割を担っていました。
Mat Werber は AWS コミュニティ SA チームのソリューションアーキテクトで、サーバーレス、Redshift、DynamoDB、および RDS に深い焦点を当てた AWS スタック全域におよぶアーキテクチャ関連のガイダンスを提供する責任を担っています。また、IT、会計監査、および公会計における経験も持ち合わせています。
Daniel Yoder はロサンゼルスを拠点とするアマゾン ウェブ サービスのシニア NoSQL スペシャリストソリューションアーキテクトです。