Amazon Web Services ブログ

Amazon DynamoDB スキャンパフォーマンスに対する Python バージョンの影響の分析

Amazon DynamoDB は、柔軟なスキーマを使用できる NoSQL データベースです。これは、項目それぞれにどのような属性が存在するかという点で、同じテーブル内の項目が互いに異なることを意味します。

前の AWS ブログ記事では、項目あたりの属性数の影響について検証しましたが、私たちは先日、お客様の Python アプリケーションにおけるスキャンが遅いという問題を解決するお手伝いをしていた時、Python バージョンのアップグレードがパフォーマンス向上に役立つかどうかを確認するために、異なるバージョンの Python インタプリタを調べました。

この記事では、Python インタプリタのバージョンがスキャンパフォーマンスにどのように影響し得るかをお見せしたいと思います。

手法

パーティションキーとソートキー (どちらも文字列) で構成されるプライマリキーというシンプルな構造の DynamoDB テーブルを 1 つ作成しました。また、それぞれに 7 文字のキー名 (「field01」、「field10」、など) を含む、個別の 6 文字の文字列属性 24 個 (6 x 24 = 合計 144 文字) で構成されるもうひとつの DynamoDB テーブルも作成しました。

DynamoDB には、単一のリクエストで取得するデータの量に 1 MB の上限があるので、ランダムなデータ 10,000 項目でテーブルをシードしてから、1 MB の上限内に収まるだけの項目を取得する単一のスキャンを実行します。その後、クライアント側でこれらの項目を取得し、アンマーシャルするためにかかる時間を測定します。

ウォークスルー

以下は、Python バージョンの比較に関する典型的な質問です。

  • Python のあるバージョンを使用する場合と、別のバージョンを使用する場合とでは、どのようにパフォーマンスが変化するのか?
  • 20 個の属性がある場合と、それらの一部をマージして 5 個の属性しかない場合とでは、どのようにパフォーマンスが変化するのか?
  • 属性の名前を「thisIsAnEnterpriseAppWithLongAttributeNames」のような長いものから「foo」や「x」だけなどに変更した場合、どのようにパフォーマンスが変化するのか?

ベンチマーキングツール

私たちは、これらのテストに使用した小さなベンチマーキングツールを公開しました。このツールでは、以下を行うことができます。

  • ユーザー独自の環境でこれらのテストを再現する。
  • テーブル構造にカスタム定義を提供する。

テーブル内の各属性の名前、およびその属性内のデータのサイズを指定することができます。テストの結果は、先ほど挙げたような質問に対する回答を提供するはずです。

詳細については、dynamodb-python-query-speed-test GitHub リポジトリをご覧ください。

実証結果

以下の表は、結果を要約したものです。

Python バージョン 1 MB をスキャンする時間 50,000 項目をスキャンする時間
2.7.16 1,112 ミリ秒 20 秒
3.7.2 618 ミリ秒 12 秒

6 文字の属性名と 6 文字の文字列値で構成される 24 個の属性では、1 MB のスキャン応答制限内で 2,819 項目を取得し、アンマーシャルすることができました。Python 2.7.16 では、5 回に渡る 1 MB の項目のスキャンにおいて 1 スキャンページあたり平均 1,112 ミリ秒かかり、50,000 項目すべてをスキャンするには約 20 秒かかりました。

# pyenv local 2.7.16
# python run.py --table dynamodb-speed-test-blog --region us-east-2 --query 10000 --rounds 5 --rcu 100000 --wcu 100000 --schema schemas/24_attributes_7_char_names_6_byte_data.schema
...
GRAND TOTALS:
    Items queried: 50000
    Elapsed time: 19754.6 ms
    Avg. time per item: 0.395 ms

Python 3.7.2 では、同じ 2,819 項目の取得とアンマーシャルに平均 618 ミリ秒かかり、50,000 項目すべてをスキャンするには約 12 秒かかりました。

# pyenv local 3.7.2
# python run.py --table dynamodb-speed-test-blog --region us-east-2 --query 10000 --rounds 5 --rcu 100000 --wcu 100000 --schema 
schemas/24_attributes_7_char_names_6_byte_data.schema
...
GRAND TOTALS:
    Items queried: 50000
    Elapsed time: 11875.6 ms
    Avg. time per item: 0.238 ms

まとめ

この結果、いくつかの面で Python 3.7.2 の効率性が Python 2.7.16 よりも約 40% 高いことがわかりました。

  • クライアントと DynamoDB との間のネットワークトラフィックの処理
  • DynamoDB API レスポンスを Python ディクショナリーにアンマーシャルするために必要な文字列の解析

属性名については、引き続きそれらを短くすることを検討してください。また、ユースケースのインデックス作成とクエリの需要を満たすために最低限必要な数の属性も必要です。

ただし、古いバージョンの Python を使用している場合は、最新バージョンの Python 3 にアップグレードするだけで大幅なパフォーマンス向上が実現できるはずです。大規模なコードベースを Python 3 にアップグレードするには若干作業を行う必要がありますが、コードの Python 3 への移行に役立つツールとドキュメントを見つけるには、Python 2 から Python 3 への移植を参照してください。

 


著者について

 

Chad Tindel はニューヨーク勤務の DynamoDB スペシャリストソリューションアーキテクトです。Chad は大企業のお客様と連携して DynamoDB ベースのソリューションの評価、設計、およびデプロイメントを行っています。Amazon に入社する前は、Red Hat、Cloudera、MongoDB、および Elastic で同じような役割を担っていました。

 

 

 

Mat Werber は AWS コミュニティ SA チームのソリューションアーキテクトで、サーバーレス、Redshift、DynamoDB、および RDS に深い焦点を当てた AWS スタック全域におよぶアーキテクチャ関連のガイダンスを提供する責任を担っています。また、IT、会計監査、および公会計における経験も持ち合わせています。

 

 

 

Daniel Yoder はロサンゼルスを拠点とするアマゾン ウェブ サービスのシニア NoSQL スペシャリストソリューションアーキテクトです。