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

中年engineerの独り言 - crumbjp

LinuxとApacheの憂鬱

MongoDB 2.4 の性能 徹底評価(レコード長による評価)

前回のMongoDB 2.4 の性能 徹底評価の反響が大きかったので続編。

今回の調査対象

ドキュメントサイズ毎の性能を評価する。

今回の検証用にベンチを書いた。
性能見積りにも使えると思うので、紹介しておきます。
MongoDB-JP/mongo_bench

今回の検証も、Sakura VPS 2G で行った。
専用環境ではないので、ある程度まわりの影響を受けている。(何度もベンチを取って極力排除はしたが、、)

また、記事に載せた以外にも色々と検証しており、その結果も少し混ざっていたり。。

オンメモリデータの処理が高速な事は解っているので
今回の検証の肝は『ディスクアクセス』
MongoDBはメモリ以上のデータを扱う為のプロダクトなのでなるべく性能が出ない様な条件=ワーストケースを狙った。

2GBメモリに対して40GBのデータを扱い、データ全体を万遍なく使うようなクエリーを発行する。

評価ドキュメントのサイズ

MongoDBのドキュメントサイズは非連続で、ぴったりのサイズでは計測出来ない。
またクライアント側で扱うドキュメントサイズとmongod上のオブジェクトサイズは若干異なるようだ。
データ総量が大体40GBになるようなデータで計測した。
またデータサイズに便宜上の名前をつけた。

名前 参考サイズ 件数 総データ量 クライアント側サイズ mongod上サイズ
small 400 B 1億 約34GB 385 400
mild 1 KB 4000万 約38GB 1009 1136
normal 4 KB 1000万 約38GB 4081 4592
extent 10 KB 400万 約38GB 10225 11248
large 40 KB 100万 約38GB 40945 45040
more 100 KB 40万 約40GB 102385 106480
pretty 400 KB 10万 約40GB 409585 425968
extra 1 MB 4万 約39GB 1023985 1048564
massive 4 MB 1万 約39GB 4095985 4194354

結論

例によって長いので、結論を上に持ってきた。
グラフ&データは下の方にある。

今回発見した特筆すべき点
フィールドタイプ(型)変更のコストが非常に高い
PAGE_SIZE=4KBが性能に与える影響が意外に大きい
INSERT編

件数観点、サイズ観点、CPU観点から評価した。

  1. 同一DBに並列にINSERTした場合の性能が特徴的。
    • ドキュメントサイズが小さい場合INSERTはCPU依存。並列化は悪影響が出る。
    • ドキュメントサイズが大きい場合INSERTはIO依存。並列化の恩恵を受ける。
    • 分岐点は4KB〜10KB付近
  2. 件数の観点ではサイズが小さいドキュメント程速く処理できる(当然)
  3. スループット観点では100KB〜がオイシイ
    • GridFSのデフォルト分割単位が256KBなのも納得
  4. CPU使用率観点では大きいドキュメントほど負担が少ない
INDEX編

数値フィールドにインデックスを張った際の性能を検証。

  1. 件数が一番大きな要素
    • 数値フィールドは固定長なので単純に扱うデータが大きくなるので当然
    • 読み込むデータもデータファイル上に万遍なく散っているのでページフォルトも起きる
    • ソートコスト
  2. PAGE_SIZE=4KB
    • ドキュメントサイズが4KB未満か否かで大きな差が出た(1ページフォルト毎に複数件読める)
    • ドキュメントサイズ=10KBの時に若干性能が落ちている。(4KBの倍数ではなく無駄が多い)
    • (理想的にはread ahead (blockdev --getra : default 256KB) も効くと思ったがあまり関係は見られなかった)
(in-place)UPDATE編

フィールドのタイプ(整数/文字列)による違い、タイプ変更、更新するデータサイズなどの観点から評価する。

下記5パターン計測した

  • INSERT直後(Number) -> Number
  • Number -> Number
  • Number -> NumberLong
  • string(30) -> string(30)
  • string(100) -> string(100)
  1. フィールドタイプ
    • 想像以上にタイプ変更はコストが高い!!
    • ドキュメント全体のINSERTとほぼ同じコストがかかる。
    • INSERT直後のNumberはNumberではない様に見える(丁度タイプ変更と同じ位の性能)
  2. インデクシングの時と同じくPAGE_SIZE=4KBが性能に現れてくる。
    • 4KB越えると平坦。
    • ドキュメントサイズ=10KBの時に特徴的な結果が出ている。(4KBの倍数ではない)
  3. 対象フィールドの型やサイズはあまり関係しないようだ(極端に大きなフィールドは未調査)
  4. 4MBドキュメントstring(100) -> string(100)更新の異常値の理由は不明(再現性あり)
FETCH編

シーケンシャルアクセス、ランダムアクセスによる性能の違い。
FETCH件数と転送サイズ、どちらが支配的なのか?並列性。の観点検証した。
しかし本来MongoDBはmulti core & multi node 前提なのでレイテンシーだけ気にすれば良い。
レプリカセット台数見積りの参考程度の話。

下記7パターン計測した

  • 全件の1/25を一括取得(ランダムアクセス&1スレッド)
  • 全件の1/25を一括取得(ランダムアクセス&10スレッド)
  • 全件の1/25を一括取得(ランダムアクセス&100スレッド)
  • 全件の1/25を一括取得(シーケンシャルアクセス&1スレッド)
  • 全件の1/25を一括取得(シーケンシャルアクセス&10スレッド)
  • 全件の1/25を一括取得(シーケンシャルアクセス&100スレッド)
  • 2500件を一括取得(ランダムアクセス&1スレッド)
  1. ドキュメントサイズ
    • 100KBを超えるサイズになると並列性、シーケンシャルアクセスの恩恵などの影響は希薄になる
  2. シーケンシャルアクセス
    • 基本的に高速。
    • 最初からI/Oコストや転送コストが支配的で、並列性は無い。
    • シーケンシャルアクセスでデータを読んでいる最中に別のクエリーが別の領域を読む為に割り込んで来る事が大きな要因だろう。
    • 10スレッドアクセスの時CPU使用率が高くパフォーマンスが良いので、この辺りの負荷が丁度良くバランスが良いのだろう。
  3. ランダムアクセス
    • データが小さい場合は、基本的に並列度を上げる程性能が良くなる。
    • データが大きくなるにつれ、I/Oコストや転送コストが支配的になって行き、並列度性が無くなる。

結果

INSERT編
ドキュメントサイズ 並列度 件/秒 MB/秒 CPU(%)
small 400 B 1 4565.5 11044.9 8.04 179.68
mild 1 KB 1 2677.5 9850.9 14.37 176.79
normal 4 KB 1 1121.9 7174.3 34.68 161.18
extent 10 KB 1 1140.2 4891.1 34.20 149.57
large 40 KB 1 771.43 2207.6 50.61 131.29
more 100 KB 1 649.92 1102.5 60.09 121.40
pretty 400 KB 1 576.76 293.4 67.72 101.85
extra 1 MB 1 474.16 160.1 82.38 98.83
massive 4 MB 1 448.84 50.3 87.02 93.12
small 400 B 10 9053.9 21903.1 4.05 95.91
mild 1 KB 10 4060.5 14939 n 9.47 89.44
normal 4 KB 10 1393.8 8912.8 27.92 86.49
extent 10 KB 10 817.8 3507.8 47.69 53.53
large 40 KB 10 452.9 1296.2 86.20 44.20
more 100 KB 10 362.78 615.4 107.65 39.44
pretty 400 KB 10 340.77 173.3 114.62 37.25
extra 1 MB 10 249.72 84.3 156.41 42.72
massive 4 MB 10 198.74 22.2 196.54 45.14

  • 件数を多く扱うなら4KB以下が良い
  • 100KBを超えるドキュメントは効率良くストア出来る

graph

INDEX編
ドキュメントサイズ 件/秒 CPU(%)
small 400 B 1974.06 50657 92.34
mild 1 KB 1029.91 38838 67.06
normal 4 KB 359.17 27841 69.68
extent 10 KB 442.08 9048 25.53
large 40 KB 324.97 3077 18.84
more 100 KB 273.76 1461 16.71
pretty 400 KB 108.99 917 15.71
extra 1 MB 95.18 420 7.51
massive 4 MB 69.85 143 3.16


  • ドキュメントサイズ4KBの場合の処理効率が良い。
  • ドキュメントサイズ10KBの明らかな性能劣化

graph

(in-place)UPDATE 性能

INSERT直後(Number) -> Number

ドキュメントサイズ 件/秒 更新サイズ(MB/秒) CPU(%)
small 400 B 3395.18 29453.4 0.58986 97.1
mild 1 KB 1850.37 21617.2 0.43293 93.3
normal 4 KB 1012.54 9876.1 0.19779 83.0
extent 10 KB 946.43 4226.4 0.08464 50.6
large 40 KB 670.99 1490.3 0.02984 41.1
more 100 KB 589.30 678.7 0.01359 36.6
pretty 400 KB 593.74 168.4 0.00337 31.8
extra 1 MB 503.22 79.4 0.00159 42.6
massive 4 MB 563.88 17.7 0.00035 42.3

Number -> Number

ドキュメントサイズ 件/秒 更新サイズ(MB/秒) CPU(%)
small 400 B 914.26 109377.1 2.19051 86.6
mild 1 KB 772.18 51800.9 1.03742 73.8
normal 4 KB 619.68 16137.1 0.32318 63.2
extent 10 KB 831.80 4808.8 0.09630 22.7
large 40 KB 513.76 1946.4 0.03898 17.7
more 100 KB 372.58 1073.5 0.02150 18.7
pretty 400 KB 135.85 736.0 0.01474 15.6
extra 1 MB 108.69 367.9 0.00737 8.6
massive 4 MB 48.50 206.1 0.00412 4.4

Number -> NumberLong

ドキュメントサイズ 件/秒 更新サイズ(MB/秒) CPU(%)
small 400 B 3387.05 29524.1 0.59128 97.6
mild 1 KB 1835.21 21795.8 0.43650 93.0
normal 4 KB 968.37 10326.5 0.20681 82.6
extent 10 KB 974.38 4105.1 0.08221 48.4
large 40 KB 696.98 1434.7 0.02873 40.4
more 100 KB 585.97 682.6 0.01367 37.9
pretty 400 KB 568.59 175.8 0.00352 33.7
extra 1 MB 522.38 76.5 0.00153 39.3
massive 4 MB 529.04 18.9 0.00037 44.7

string(30) -> string(30)

ドキュメントサイズ 件/秒 更新サイズ(MB/秒) CPU(%)
small 400 B 923.2 108312.4 4.95815 83.0
mild 1 KB 738.8 54139.5 2.47831 76.2
normal 4 KB 658.5 15185.8 0.69515 56.8
extent 10 KB 829.0 4824.9 0.22087 22.4
large 40 KB 504.9 1980.3 0.09065 19.0
more 100 KB 372.3 1074.2 0.04917 18.4
pretty 400 KB 137.0 729.8 0.03341 17.3
extra 1 MB 102.9 388.3 0.01777 9.1
massive 4 MB 51.4 194.5 0.00890 4.1

string(100) -> string(100)

ドキュメントサイズ 件/秒 更新サイズ(MB/秒) CPU(%)
small 400 B 944.7 105850.9 11.91178 84.7
mild 1 KB 774.1 51669.6 5.81456 76.2
normal 4 KB 611.7 16346.8 1.83957 67.1
extent 10 KB 862.8 4635.9 0.52170 22.2
large 40 KB 520.4 1921.3 0.21622 17.6
more 100 KB 378.4 1056.9 0.11894 18.2
pretty 400 KB 162.0 617.1 0.06945 12.9
extra 1 MB 115.9 345.1 0.03883 7.8
massive 4 MB 1.9 5151.7 0.57974 25.7

  • タイプ変更はダメ

graph

ランダムFETCH性能

全件の1/25を一括取得(ランダムアクセス&1スレッド)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 10627.4 376.3 0.13963 5.6
mild 1 KB 11895.3 134.5 0.12994 2.6
normal 4 KB 3502.8 114.1 0.44487 2.1
extent 10 KB 177.2 902.8 8.80727 5.8
large 40 KB 59.4 673.0 26.28424 14.2
more 100 KB 28.2 566.6 55.32759 33.5
pretty 400 KB 36.3 109.9 42.93177 21.3
extra 1 MB 25.5 62.5 61.07040 31.6
massive 4 MB 17.3 23.0 89.84368 40.7


全件の1/25を一括取得(ランダムアクセス&10スレッド)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 981.5 4075.1 1.51178 36.9
mild 1 KB 1269.0 1260.7 1.21798 18.3
normal 4 KB 560.9 713.1 2.77810 16.5
extent 10 KB 384.6 415.9 4.05772 11.3
large 40 KB 102.0 392.1 15.31270 13.6
more 100 KB 46.0 347.4 33.93127 21.2
pretty 400 KB 27.5 145.3 56.76445 28.6
extra 1 MB 19.0 84.1 82.13776 79.4
massive 4 MB 13.3 30.0 117.19977 102.0


全件の1/25を一括取得(ランダムアクセス&100スレッド)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 116.4 34350.9 12.74350 119.0
mild 1 KB 145.3 11009.9 10.63636 85.5
normal 4 KB 210.4 1900.5 7.40392 54.6
extent 10 KB 93.7 1706.9 16.65177 74.5
large 40 KB 35.9 1112.4 43.44317 101.6
more 100 KB 36.8 434.5 42.43325 108.8
pretty 400 KB 22.6 176.2 68.85518 91.7
extra 1 MB 32.9 48.6 47.46877 113.5
massive 4 MB 25.2 15.8 61.84508 109.4

シーケンシャルFETCH性能

全件の1/25を一括取得(シーケンシャルアクセス&1スレッド)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 25.5 156564.3 58.08214 73.6
mild 1 KB 21.7 73529.1 71.03446 77.3
normal 4 KB 17.5 22747.0 88.61685 72.1
extent 10 KB 15.7 10160.4 99.11655 72.3
large 40 KB 14.4 2762.8 107.89543 70.8
more 100 KB 13.4 1187.7 115.97504 69.8
pretty 400 KB 23.3 171.6 67.04082 38.8
extra 1 MB 19.0 83.9 81.93726 44.8
massive 4 MB 14.9 26.8 104.85996 58.7


全件の1/25を一括取得(シーケンシャルアクセス&10スレッド)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 10.9 363673.8 134.91548 208.2
mild 1 KB 12.3 129949.2 125.54032 218.3
normal 4 KB 13.5 29528.4 115.03576 172.6
extent 10 KB 11.6 13691.5 133.56303 181.3
large 40 KB 9.5 4206.1 164.25823 195.9
more 100 KB 9.0 1760.2 171.87784 195.0
pretty 400 KB 9.0 442.0 172.68584 161.2
extra 1 MB 8.5 187.9 183.49486 170.6
massive 4 MB 7.8 50.9 199.11400 164.6


全件の1/25を一括取得(シーケンシャルアクセス&100スレッド)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 17.3 230365.9 85.46101 187.2
mild 1 KB 22.9 69570.0 67.20970 159.4
normal 4 KB 26.9 14815.0 57.71576 124.8
extent 10 KB 27.3 5844.5 57.01403 103.3
large 40 KB 18.9 2111.3 82.45134 141.1
more 100 KB 17.6 907.7 88.63475 126.1
pretty 400 KB 20.1 198.6 77.61066 133.8
extra 1 MB 21.3 74.8 73.08055 174.2
massive 4 MB 21.6 18.5 72.33571 130.7
件数固定ランダムFETCH性能(あまり意味は無かった)

2500件を一括取得(ランダムアクセス&1スレッド)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 0.0 162728.6 60.36895 65.0
mild 1 KB 0.0 136948.7 132.30239 109.5
normal 4 KB 0.0 60113.4 234.18772 96.1
extent 10 KB 0.1 21325.2 208.03054 68.2
large 40 KB 0.2 8941.6 349.18872 82.2
more 100 KB 0.6 4085.6 398.94688 83.3
pretty 400 KB 48.6 51.3 20.05748 9.7
extra 1 MB 67.8 36.8 35.99759 16.8
massive 4 MB 114.1 21.9 85.58613 39.2


  • 100KB超えると並列度もシーケンシャルアクセスも関係なくなる(I/Oが支配する世界)

Count per seconds


上のグラフと観点が違うだけ。

  • 40KB〜100KB(400KB未満の何処か迄)はバランスが良い
  • 100KBから上はI/Oが支配する世界

MB per seconds