TPC-CによるScalarDBのベンチマーク方法について
本記事では、OLTP (Online Transaction Processing) システムの標準ベンチマークであるTPC-Cを用いてScalarDBの性能を評価する方法について説明します。(英語版はこちら)
使用するベンチマークツールは、TPC-Cの仕様に基づいてワークロードを発生させるScalarDBのアプリケーションとして実装されています。TPC-Cのような実世界を模した複雑なワークロード、アプリケーションを、ScalarDBのデータモデル、インタフェースを用いてどのように実現しているのか、どういった工夫点があるかについても紹介します。設計時に考慮すべきポイントなど、ScalarDBアプリケーション開発時の参考になれば幸いです。
TPC-Cの概要
TPC-Cは、OLTPデータベースの業界標準ベンチマークです。TPC-Cは卸売業の受注処理アプリケーションをモデルとしており、使用されるデータベースは、Warehouse、Customer、Order、Itemなど9つのテーブルで構成されています(詳細は TPC-C Standard Specification Revision 5.11 より引用した下図を参照)。Itemテーブルを除いて、各レコードはWarehouse毎に用意することになっており、Warehouseの数はスケールファクタとして設定可能です。
TPC-Cには、New-Order、Payment、Order-Status、Delivery、Stock-Levelの5つのトランザクションタイプがあります。各トランザクションの割合は仕様で定義されており、約90%のトランザクションがWrite-Intensiveな2つのトランザクションNew-Order・Paymentで占めています。TPC-Cのトランザクションは、ほとんどが1つの (ローカル) Warehouseにアクセスしますが、約10%のトランザクションが別の (リモート) Warehouseにもアクセスします。
TPC-CによるScalarDBのベンチマーク方法
ScalarDBのベンチマークツールは以下のリポジトリで提供されています。現在は、ワークロードとしてTPC-CとYCSBが提供されています。
ベンチマークツールはKelpieというテストフレームワークを用いて実装されているため、はじめにこちらから最新版のKelpieアーカイブ (e.g., kelpie-1.2.3.zip) をダウンロードし、任意の場所に展開しておきます。
次に、ScalarDBのベンチマークツールをビルドします。Java (OpenJDK 8 or higher)が動作する環境を用意の上、下記を実行してください。
./gradlew shadowJar
次に、ScalarDB Schema Loaderを使用してテーブルを定義します。こちらから最新版のSchema Loaderを取得し、スキーマを記載した“tpcc-schema.json”を指定して実行してください。
java -jar scalardb-schema-loader-<version>.jar --config /path/to/scalardb.properties -f tpcc-schema.json --coordinator
テーブルが定義できたら、スケールファクタやワーカースレッド数等を指定した設定ファイルを用意します。サンプルの設定ファイル tpcc-benchmark-config.toml がリポジトリの直下にあります。
スケールファクタは設定ファイルの [tpcc_config] セクションにある num_warehouse で、ロード用のワーカースレッド数は同セクションの load_concurrency で指定できます。実行時のワーカースレッド数は [common] セクションの concurrency で指定できます。その他のオプションについてはこちらを参照してください。
以上で準備完了です。ベンチマーク開始するには次のようにKelpieコマンドを実行します。正常に完了すると、スループットや平均レイテンシなどが得られます。
${kelpie}/bin/kelpie --config your_config.toml
なお、${kelpie}
は上記でアーカイブを展開して得られたKelpieのディレクトリです。また、初期データのロードのみを行う--only-pre
オプションや初期データのロードをスキップし既存のデータでベンチマークの実行のみを行う--except-pre
オプションを指定することもできます。
TPC-Cベンチマークの実装
ScalarDBでTPC-Cベンチマークを実装するにあたって考慮すべき点についていくつか述べます。
スキーマ設計
最も重要なポイントの1つは、TPC-CのテーブルスキーマをScalarDBのデータモデルでどう表現するかということです。
TPC-Cのトランザクションの多くクエリは、主キーを指定してレコードをアクセスするpoint queryです。そのため、基本的には各テーブルの主キーのカラムをScalarDBのpartition keyに指定しておけば、ScalarDBの get/put/delete インタフェースでそれらのpoint queryを表現することができます。なお、カラムやデータ型は基本的にそのままマッピングすることができます。
いくつかのテーブルに対しては、複数レコードを一度に取得するscan queryが発行されます。ScalarDBは多次元マップのKey-Value形式を採用しているため、単純なKey-Value形式と比較して、これらのscan queryを直感的かつシンプルに扱うことができます。ただ、より効率良くスキャンを行うためには、対象テーブルの複合主キーを、適切にpartition keyとclustering keyに分けることが重要です。
具体例を挙げて説明します。OrderStatusトランザクションでは、Warehouse ID, District ID, Order IDを指定してある注文の明細(order-line)を取得する必要があります。また、StockLevelトランザクションは、ある倉庫の配送区域 (Warehouse ID, District ID) の直近20件の注文の明細 (order-line) を取得する必要があります。
order-lineテーブルの主キーは、(warehouse ID, district ID, order ID, order-line number)です。OrderStatusトランザクションだけを想定して、(warehouse ID, district ID, order ID)をpartition keyに、order-line numberをclustering keyに指定してしまうと、StockLevelトランザクションは、注文毎に明細の取得が発生し、合計20回ものscanを発行しなければならなくなってしまいます。ここでは、(Warehouse ID, District ID)をpartition key、残りをclustering keyとしておき、scan操作のフィルタ機能を活用して両方のトランザクションが効率良く問合せ可能にします。
セカンダリインデックス
TPC-Cトランザクションのscan queryの中にはセカンダリインデックスを必要とするものがあります。以下の2つのケースです。
- (Warehouse ID, District ID, Customer Last Name) を指定して
Customer IDをスキャン - (Warehouse ID, District ID, Customer ID) を指定して
Order IDをスキャン
ScalarDBは、現在、単一カラムに対するセカンダリインデックス機能のみをサポートしています。そこで、scalardb-benchmarksにおけるTPC-Cの実装では、あらかじめ索引付け用のカラムを用意しておき、レコード挿入時に、索引対象キーの値を単一の文字列にエンコードして格納します。
下位のデータベースシステムの制約などにより、ScalarDBのセカンダリインデックスを使用しない場合には、通常のテーブルでセカンダリインデックスに相当するマッピングを保持する汎用的な方法もあります。scalardb-benchmarksでこの方法を使用する場合、` — use-table-index`を指定してください。ただ、参照レコードや更新レコードが増加し、性能に影響することからデフォルトでは無効としています。
結合と集約クエリ
TPC-CはOLTPシステム向けベンチマークですが、COUNT()やSUM()による簡単な集約や、結合を必要とするクエリがあります。ScalarDBのデータアクセスAPIには集約や結合はありませんが、(この程度であれば高度なオプティマイザや実行エンジンなしに) アプリケーション側で容易に実装することができます。
具体的には、scalardb-benchmarksのTPC-C実装では、以下の2箇所でアプリケーション側の集約処理を行っています。
- Deliveryトランザクション: ある注文に関する注文金額の合計 (集約)
- Stoke-Levelトランザクション: 直近の注文で指定された品目のうち、倉庫内で数量が閾値未満の品目の数 (結合・集約)
まとめ
本記事では、OLTPシステム向け標準ベンチマークであるTPC-Cを用いてScalarDBの性能を評価する方法と、ScalarDBを用いたTPC-Cベンチマークツールの実装について紹介しました。使用方法や実装の詳細は、以下のリポジトリ内のREADMEやコードをご覧ください。