工場長のブログ

日々思ったことを書いてます。

YCSBでNoSQLのベンチマーク その2

YCSBを使ってみよう的なテーマで書いた前回の続きとして、今回は結果の読み方や負荷パターンの調整について書いてみる。

今回の目次は以下のとおり。

  1. コマンドのパラメータの読み方
  2. DBENGINEごとの接続設定
  3. workloadファイルの読み方/書き方
  4. 結果の読み方

コマンドのパラメータの読み方

基本的には起動は以下のようなイメージ。

./bin/ycsb DBENGINE (run|load) -P CONFIGFILE [ -threads n ] [ -p key=value ] [ -s ]

DBENGINEのところはdynamodbやらredisやらmongodbやらが入る。
その次はrunかloadが来る。これは動作モードを決定する値でrunはトランザクションフェーズ(読み込み&更新系)、loadはロードフェーズ(書き込み)の動作になる。
以下、パラメータのリスト。

パラメータ名 意味 デフォルト
P プロパティファイルをロードする。複数指定可能。 -
threads スレッド数 1
p 特定のプロパティを渡す。プロパティファイルの中の指定をオーバーライドできる -
s 実行中のステータスを表示する -

プロパティファイルというのが接続設定を書いたり負荷の設定を書いたりと、もろもろの設定を書くためのファイル。
ここからはプロパティファイル周りについて書いていく。

DBENGINEごとの接続設定

DBENGINEごとにいろいろ接続のための設定をしなければならない。例えばDynamoDBならAWSのCredentialやAPIエンドポイントだったり、redisだったらホスト名とポート番号だったりという具合。
じゃあ実際それぞれどこにどう書けばいいのかというと、これが統一的なドキュメントが無いw
それぞれのDBENGINEへの接続クラスのsorceディレクトリの中にREADMEがあることが多いので、これをもとに辿っていく。
例えばDynamoDBのREADMEを読むと、

$YCSB_HOME/bin/ycsb load dynamodb -P workloads/workloada -P dynamodb.properties

と起動しろと書いてあるので、このdynamodb.propertiesを読んでみる。

$ less dynamodb/conf/dynamodb.properties
dynamodb.awsCredentialsFile = PATH_TO_CREDENTIAL
dynamodb.primaryKey = id
dynamodb.endpoint = http://dynamodb.ap-northeast-1.amazonaws.com
requestdistribution = zipfian
#dynamodb.debug = false
#dynamodb.connectMax = 50
#dynamodb.consistentReads = false
#fieldcount = 10
#fieldlength = 90

こうみるとdynamodb.*といういくつかの特有なプロパティがあるのでこのあたりを設定してあげればつながることがわかる。


ちなみにこれは親切なほうで、redisの場合はREADMEがないw
じゃあどうすればいいかというと、sourceを読むw

$ less redis/src/main/java/com/yahoo/ycsb/db/RedisClient.java
(snip)
    public static final String HOST_PROPERTY = "redis.host";
    public static final String PORT_PROPERTY = "redis.port";
    public static final String PASSWORD_PROPERTY = "redis.password";

そうするとこんな感じに変数が見つかったりするので、じゃあこれを設定すればいいのだろうということでredis.confというファイルを作ってreds.hostやらredis.portやらを書いて、コマンド起動時に-Pで渡してあげたら動いた。

とまあこんな感じにundocumentedな部分も多いが、なんとかやっていきましょうw

workloadファイルの読み方/書き方

YCSBをインストールするとルートディレクトリの直下にworkloadというディレクトリが生成されていて、ここにworkload(a|b|c|d|e|f)というファイルがある。これがどんな負荷をかけるかを指定するworkloadファイル。

中身はこんな感じになっている。

$ cat workload/workloada

recordcount=1000
operationcount=1000
workload=com.yahoo.ycsb.workloads.CoreWorkload

readallfields=true

readproportion=0.5
updateproportion=0.5
scanproportion=0
insertproportion=0

requestdistribution=zipfian

上記にないものも含め、設定項目は以下のとおりです。

項目 意味
recordcount ロードフェーズで挿入するデータのレコード数
operationcount トランザクションフェーズで実行されるクエリの回数
workload workloadを実行するクラス。いじったことはない。
fieldcount 1レコードあたりのフィールド数
fieldlength 各フィールドのサイズ
readallfileds レコード内の全フィールドを読むのか(true)、1つだけにするか(false)
readproportion 全operationに対する読込の割合
updateproportion 全operationに対する更新の割合
insertproportion 全operationに対する挿入の割合
scanproportion 全operationに対するスキャンの割合
readmodifywriteproportion 全operationに対する読込、修正、更新の割合
requestdistribution リクエスト分布方式、uniform、zipfian、latestから選択
maxscanlength スキャンする際の最大レコード数
scanlengthdistribution スキャンするためのレコード数と各スキャンでのリクエスト分布方式
insertorder データ挿入する順序。キー順(ordered)かハッシュ順(hashed)

ちなみに、requestdistributionのそれぞれの値の意味はだいたいこんな感じ。

  • uniform
    • 均等分布
  • zipfian
    • ランダムに(?)偏る
  • latest
    • 新しいデータにアクセスが偏る

結果の読み方

最後は結果の読み方。下記はトランザクションフェーズの結果を適当に省略したもの。

[OVERALL], RunTime(ms), 185903.0
[OVERALL], Throughput(ops/sec), 537.8611426389031
[UPDATE], Operations, 50044
[UPDATE], AverageLatency(us), 21046.522180481177
[UPDATE], MinLatency(us), 6661
[UPDATE], MaxLatency(us), 255970
[UPDATE], 95thPercentileLatency(ms), 27
[UPDATE], 99thPercentileLatency(ms), 29
[UPDATE], Return=0, 50044
[UPDATE], 0, 0
[UPDATE], 1, 0
[UPDATE], 2, 0
[UPDATE], 3, 0
[READ], Operations, 49946
[READ], AverageLatency(us), 19815.733532214792
[READ], MinLatency(us), 4863
[READ], MaxLatency(us), 259948
[READ], 95thPercentileLatency(ms), 27
[READ], 99thPercentileLatency(ms), 28
[READ], Return=0, 49946
[READ], 0, 0
[READ], 1, 0
[READ], 2, 0
[READ], 3, 0
[READ], 4, 2

読み方的には、

  • 全体的(OVERALL)なスループットが 537.86.../sec
  • 更新(UPDATE)の平均/最小/最大レイテンシがそれぞれ21046us, 6661us, 255970us
  • 更新(UPDATE)クエリのうち95%は27ms以内、99%は29ms以内に終了
  • 参照(READ)の平均/最小/最大レイテンシがそれぞれ19815us, 4863us, 259948us
  • 参照(READ)クエリのうち95%は27ms以内、99%は29ms以内に終了

とか、だいたいそんな感じ。

まとめ

今回はYCSBを使って実際にデータを計測するためのチューニングというか設定方法を書いてみた。
NoSQLとか使うときはこういうツールを使って「実際に自分が必要とするだけの負荷をかけて試験してみようね」っていうお話でした。