Everyday Deadlock

by hayamiz.com

本当は怖いPostgreSQL性能測定

2012/12/25

この記事は,PostgreSQL Advent Calendar 2012の12月25日分の記事です(書く人がいなさそうなので勝手に)。 PostgreSQLの性能測定に絡めつつ,データベースシステムの性能測定に関する様々な罠について, 傾向と対策を書いてみようと思います。

この記事のきっかけとなったのが, 永安さんのPostgreSQL Advent Calendar 2012(全部俺) の,PostgreSQL Deep Dive: データブロックサイズの変更と分析系クエリへの性能影響(SSD編) という記事です。 みんな大好きSSDの上で,DWH系のワークロードを動かした場合の性能について, DBのブロックサイズが与える影響を測定した記事です。

今回は,この記事へのツッコミという形で性能測定の罠を紹介してゆくことにします。

※ 念のために断っておきますが,当該記事を貶める意図があるわけではなく, タイムリーかつ題材としてもちょうどよい内容だったのでネタにさせてもらいました。 12月に毎日書く記事の中で,これだけの測定をして記事を書くところまでもっていける技量は見習いたいすなあ。 データを測定したり,それを記事にするという作業に比べると, 批判をするのはそこに乗っかるだけのお気楽な作業です。 面白い記事を書いてくださった永安さんに敬意を表しつつツッコマせてもらいます。

罠その1:クエリ実行時間

性能測定を行い,そして分析をする際には,メトリクス(測定基準)に何を選ぶかが極めて重要です。 メトリクスは,自分が分析したい対象をできるだけ素直に表す指標を選ばなければなりません。

データベースの性能測定というと,まずクエリの実行にかかる時間をメトリクスとしてしまいがちですが, これは大きな誤りです。 なぜならば,データベースはハードウェアとOS・DBMSという大規模なソフトウェアが複雑に絡み合った集合体です。 その中で,クエリ実行時間とは一体何を表しているのか,よく考えてみる必要があります。 たとえばアグリゲーションで複雑な計算を行う場合には, ストレージのI/OよりもCPU処理がボトルネックとなり, クエリ実行時間にストレージのI/O性能はあまり反映されません。

もちろん最終的にユーザに見える数字として,クエリ実行時間は重要です。 ただ,クエリ実行時間は最後のまとめとして押さえるポイントではあっても, 性能分析のメトリクスとして使える場面はそれほど多くないということです。

今回ネタにする記事では, 分析したい対象は「どのブロックサイズを使うと,SSDのI/O性能を一番引き出せるか」だと思います。 特にDWH系のテーブル全舐めクエリを対象としているようなので, このような場合にはI/Oのスループットがメトリクスとしては適切そうです。 iostat等でI/Oスループットの時系列データをとってプロットすると, SSDが頑張っている感も伝わりそうです。

ちなみに手前味噌になりますが,iostatでは時系列データをグラフにプロットするには加工にひと手間いるとか, 測定間隔が1秒より短くできないといった問題があるので, 僕は自前で PerfMonger というツールを作ってI/O性能測定をしています。 PerfMongerでは0.1秒とか0.05秒単位でI/O性能測定を行うことが出来る上, 1回のデータは1行のJSONデータとして出力します。 そのため,データの加工やグラフへのプロットも楽におこなうことができます。

参考リンク:性能測定、しましょうか:PerfMonger 0.1.0 をリリースしました | Everyday Deadlock

罠その2:システムの"状態"と測定対象

メトリクスが決まったら,実際に環境を整えて測定を行っていくことになるのですが, 測定実験を行う際にはシステムの状態に気を付けなければなりません。 特に,キャッシュに何が乗っているかということには気を配る必要があります。

  • ディスクのキャッシュ
  • ストレージコントローラのキャッシュ
  • Linuxのページキャッシュ
  • PostgreSQLの共有バッファ
  • pgpoolやpqcなどのクエリキャッシュ
  • CPUのキャッシュ

システムのあらゆる場所にはキャッシュを始めとした"状態"があります。 それぞれ違う状態のシステムに対して同じクエリを実行しても, I/O性能や実行時間は異なるものとなるでしょう。 それらの測定結果は,それぞれ異なるものとして扱わなければなりません。

その意味では,当該記事の下記のグラフは, PostgreSQLを起動してから同じクエリを 「違う測定結果」の平均をとってしまっているので, 何を意味しているのかわからないグラフになってしまっています。

■テーブルフルスキャン (略) 以下が、ブロックサイズ別のlineitemテーブルへの実行時間(5回平均)です。

一方で,その下にある次のグラフは有用です。

これを見るとブロックサイズを8kBから32kBへと大きくするに従ってパフォーマンスが向上しているように見えます。 ブロックサイズを変えることで、本当にこれだけパフォーマンスが向上しているのでしょうか。 その点を確認するために、5回分の実行時間を個別に比較したものが以下のグラフになります。

このグラフは,1回目から5回目にかけて,実行時間が大きく変化しうる, つまり何かしらの"状態"が変化していく過程を描き出しています。 これに併せて,I/Oのスループットのデータもあると更に面白いデータになると思います。

「この変化がなぜ起きているか」を掘り下げるような分析は僕が日々やっている作業なのですが, まあその話は割愛します。今回の測定に関しては,おそらくLinuxのページキャッシュ周りとの絡みでしょうか? 記事に明記されていないのでちょっと判断が難しいところですが。

罠その3:"ボトルネック"になっていないものは測れない

さて,当該記事の分析の目的は 「どのブロックサイズを使うと,SSDのI/O性能を一番引き出せるか」 ということでした。

これを調べるためには,SSDへのI/Oがボトルネックとなる状態を作り出さなければなりません。 なぜならば,I/O以外の部分がボトルネックになっていたら, そもそもSSDはヒマなわけです。つまりSSDへのI/Oが効率化されたところで, クエリ処理性能全体は変わりません。

ボトルネック

すごく抽象的にコンピュータシステムを眺めると, システムは1つの大きな「資源の流れ」です。 ディスクからメモリへとI/Oリクエストやデータが流れ, メモリからCPUへとデータが流れ, CPUから演算結果がメモリへと流れ, …というように,コンピュータの動きというのはデータをシステムの中で流す行為として見ることができます。 そのなかで,流れの勢いを制限するのがまさに「ボトルネック」です。

コンピュータシステムにおける測定とは, 測りたい対象をいかにボトルネックにするかで勝負が決まります。 いくら大量に資源を流しても, ボトルネックになっていない部分の「流れの幅」は知ることができません。

そしてボトルネックを作り出すためには, 大体どの部分がどのくらいの「幅」を持っているか, ということを数値感覚として理解していなければなりません。 ディスク1本の帯域が○MB/sで,10本まとめると○MB/sだけど,RAIDカードの性能が○MB/sで,…などなど, 徹底的にやる場合にはこういった基本性能を実測によって把握しておくことが必要です。 あと,手元のサーバでは複数のHashAggregationがあるクエリの場合には, PostgreSQLが捌けるのが30MB/sくらいなので, 多少複雑な集計処理をするときにはI/Oがネックになることはほとんどなさそうです。

という観点でみると, 当該記事では, まずデータベース全体で25GBで,メモリが16GBなので, ページキャッシュにかなりのデータが乗ることになり, SSDとのI/Oがボトルネックになることは少なそうです。 SF=10だと一番大きいテーブルのlineitemでも8GB程度なので, 1回スキャンしたら全部メモリに乗ってしまうような規模感のような気がします。

物理メモリを抜くわけにもいかないので, こういう場合には隣でmallocだけして何もしないプログラムを動かして, ページキャッシュに事実上使える量を削るとか,いろいろ策はあります。

さらに余談になりますが,ディスク1本の性能や,コントローラの性能,メモリの性能, はたまたCPUのメモリアクセスのスピードなど, システムの基本性能情報を測定するためのツールmicbenchを自作していたりします。

参考リンク:性能測定、しましょうか:micbench 0.1.0 をリリースしました | Everyday Deadlock

まとめ

この記事では,PostgreSQLの性能測定においてはまりがちな3つの罠について紹介しました。 永安さんの記事をダシにするような形になって申し訳ない感じなのですが, 理屈だけではなく実例もあったほうが理解しやすいだろうと思い,引用させて頂きました。

PostgreSQL Advent Calendar 2012 の13日目の記事 PostgreSQLのメモリ管理 | Everyday Deadlockにおいて書いたように, 僕の所属する喜連川研究室ではこのような性能測定の基礎をみっちりと叩きこまれます。 そのせいもあってか,性能測定と聞くとピンと反応して, 他人の行った性能測定の細かい問題についてあれこれ気になり, 質問しまくってドン引きされるということを繰り返しておりますが, 皆さん仲良くしてくれるとうれしいです。。。

PostgreSQL Advent Calendar 2012が終わり,2012年ももう終わろうとしていますね。 今年のクリスマスイブは,1TBのPostgreSQLのデータにインデックスを張りながら, 取りこぼした大学院の単位を集めるべくレポートを書きながら過ごしました。

この手の性能測定の話は,これもPostgreSQLのメモリ管理 | Everyday Deadlockに書きましたが,たいへんよい教科書があります。

The Art of Computer Systems Performance Analysis: Techniques for Experimental Design, Measurement, Simulation, and ModelingThe Art of Computer Systems Performance Analysis: Techniques for Experimental Design, Measurement, Simulation, and Modeling
R. K. Jain

Wiley
売り上げランキング : 197817

Amazonで詳しく見る by AZlink

【宣伝】大晦日にデータベースの同人誌をコミケで売ります

来る2012年大晦日、コミックマーケット(コミケ)C83にてデータベースの同人誌「The Database Times vol.2」を頒布予定です。

何を言っているのかわからない方のために説明すると、コミケでは漫画やアニメの同人誌だけが売られているわけではなく、プログラミングやネットワーク技術、電子工作等々の技術的な内容を扱った同人誌も少なからず存在します。その手のサークル一覧が毎回作られているほどです(参考:UNIXユーザーのためのコミケット82情報ページ)。

中身としては、Hadoop、ネットワーク、機械学習など雑多な感じです。先日開催されたPgDayのレポートなんかも混ざっています。何かの間違いでクソ寒い大晦日に海の上の埋立地まで出向くお暇のある方は、是非にご覧になって下さい。

あと、今年の夏コミで売ったThe Database Times vol.1では、PostgreSQLのご先祖様であるINGRESの歴史について解説した記事を書きました。冬コミで再販予定です。Kindle版の販売も始めました。

category: database
tags: postgresql and database
このエントリーをはてなブックマークに追加

この記事にコメントする

comments powered by Disqus


このエントリーをはてなブックマークに追加