読者です 読者をやめる 読者になる 読者になる

テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

I/Oベンチマークフレームワークperflexの紹介

技術的にはどうということはないのですが, 欲しいものがなかったので, とりあえず作りました. 一応動くようになったので, 紹介します. もし同じようなものがあったら教えてください. そちらを使います.

github.com

perflexは, 「ユーザランドからのパフォーマンス測定を柔軟に行うことが出来る」ことを目指したフレームワークです. 主に, ネットワークごしのストレージやデータベースに対するユーザランドから見た性能を評価するために使うのが適切だと思います. rakyll/boom · GitHubをより一般化するという位置づけです.

仕組みは簡単で,

  • 入力として関数(Any -> T)のリストを受け取る
  • これをFutureでラップして, 固定サイズプールの中でFutureを実行していく
  • 最終的な結果であるSeq[Try[T]]に対して, レポートを生成する

レポートは, 合成可能になっています. 例えば, 「単に実行の成功失敗のカウントだけを表示する」というものもあれば, 「レスポンスタイムのdistributionを表示する」ものもあります. 必要に応じて作っていくことが可能だと思います. これら個別の部品をreporterと呼んでいます.

各reporterは「自分がレポートを作成するためにどういう統計情報が必要か」ということを知る必要があるのですが, これは型検査を通すようにしています. 例えば, TimeSummaryという応答時間に関するサマリを作成するreporterは, Timeという統計情報が必要であるため, 上記Tは, statkind.Time traitのサブクラスである必要があります.

私の構想では, コミュニティがstatkindやreporterを追加していき, さまざまなI/Oシステムに対するベンチマークテストや負荷試験に応用されれば良いかと思っています.

将来的には, Akkaのlocation transparencyの性質を利用して, vdbenchのように, 複数のworkerノードからリクエスト発行を行うことも出来るようにしようと思っています.

これが開発に使っているテストコード(タスクは仮)であり,

import perflex.{ReportMaker, Runner, _}

import scala.util.Random

object MainTest extends App {

  case class MyType(time: Long, statusCode: Int) extends Object
  with statkind.Time
  with statkind.StatusCode

  val tasks = Stream.fill(1000)(Random.nextInt % 1000).map(a => (_:Any) => MyType(a.abs, 200)) ++ Stream(
    (_: Any) => MyType(111, 200),
    (_: Any) => MyType(222, 403),
    (_: Any) => MyType(2, 403),
    (_: Any) => MyType(3, 403),
    (_: Any) => { assert(false); MyType(333, 200) }
  )

  val runner = new Runner(tasks).concurrentNumber(8)
  val result = runner.run

  val report = new ReportMaker(result).make(
    Seq(
      new reporter.SuccessStat,
      new reporter.TimeSummary,
      new reporter.TimeDistribution,
      new reporter.StatusCodeStat
    )
  )

  println(report)
}

今のところ以下のような出力を得ることが出来ます.

Success/Failure:
  Success: 1004
  Failure: 1

Summary:
Total:        509694
Slowest:      998
Fastest:      1
Average:      507.66336

Response time histogram:
    50.849998 [        89] | ***************
   150.549988 [        99] | ****************
   250.249985 [       107] | ******************
   349.949982 [        99] | ****************
   449.649994 [        96] | ****************
   549.349976 [        94] | ***************
   649.049927 [       105] | *****************
   748.750000 [       118] | ********************
   848.449951 [       107] | ******************
   948.150024 [        90] | ***************

statusCode

コメントあればお願いします.

(追記)

レスポンスタイムの試行毎の推移を簡単に確認出来るといい. preflexはあくまでも簡易な性能測定のものだからこのグラフ描画はチープでいい. 以下のように点線でグラフを描くreporterを実装した. すべてがコマンドラインの上で片付くのが魅力だ.

Response time change:
  |                      .
  |                         .
  |                        .
  |                           .
  |                         .
  |                          .
  |                        .
  |                        .
  |                        .
  |                      .
  |                          .
  |                      .
  |                           .
  |                          .
  |                       .
  |                       .
  |                            .
  |                         .
  |                         .
  |                        .