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

中年engineerの独り言 - crumbjp

LinuxとApacheの憂鬱

MongoDB 2.4 の性能 徹底評価(Memory vs DISK)

大体欲しいデータは揃ったのと、MongoDBの気持ちが解ってきたのでMongoDB2.4の性能調査は今回で最後の予定


実は前回MongoDB 2.4 の性能 徹底評価(レコード長による評価)のFETCHバイト数(1.5GB)
実は今回のOn-memoryデータ vs DISKリードに繋げる事を意図した大きさだった。
システムの2GBメモリに収まるだろう。と・・・

しかし、、測れど測れど、意図した通りの結果にならない・・・
それで気付いた。
インデックスの大きさを勘違いしていたのだ。

MongoDBのインデックスは単なるコレクションでは無いようだ!

1億件の数値型インデックスは2.3GBにもなる。
という訳で、1億件のコレクションのインデックスはそもそもメモリーに入らない。。

 1ドキュメント辺り25〜26byte
 インデックス数値型8バイト+ドキュメントへのポインタ8バイト+メタ情報?
 _idインデックスは更に若干大きくなる。
 追記:
     メタじゃくてbtree実装だった。
     btreeの実装見てると、ほぼほぼ仕方が無い。(正しい実装)
     bsonの下位互換性を維持する為の部分に無駄があるね。
    

1.5G + 2.3GB はシステムのメモリサイズをはるかに超え、1クエリー中にもインデックスを舐めてく内に端からPageFaultして行く。。と。。

そら遅いわ・・・

今回は新たに件数やFETCHサイズを見直して測り直した。

条件

データ総量

データ総量を前回の1/10=4GB程度にした。
少し寂しいデータ量だが2GBしかないメモリでは1億件を自由自在に扱うのは無理だ・・・

名前 参考サイズ 件数 総データ量
small 400 B 1000万 約4GB
mild 1 KB 400万 約4GB
normal 4 KB 100万 約4GB
extent 10 KB 40万 約4GB
large 40 KB 10万 約4GB
more 100 KB 4万 約4GB
pretty 400 KB 1万 約4GB
extra 1 MB 4000 約4GB
massive 4 MB 1000 約4GB

ちなみに1000万件のドキュメントでの各インデックスサイズは以下の通り。

  • _idインデックスサイズは約266MB
  • 数値型のインデックスサイズは約239MB

総インデックスサイズは500MB程度でメモリーを圧迫する程でも無い。

フェッチ量

今回のクエリは全て、総データの1/10(400MB程度)をフェッチする。
上記インデックスサイズと合わせても900MB程度、十分メモリに乗る算段だ。

結果:(全体的な傾向)

例によって結果から、、

基本は
出来るだけメモリー積んで、効率良く使え!
という事。

  1. 解りやすくグループ分け出来た。性能も概ねこの順番。
    • On-Memory
    • Disk
      • シーケンシャルアクセス
      • ランダムアクセス
  2. On-Memory >>> Disk
  3. クエリーの並列度は適度が良い(10並列で既にCPU使用率が良い感じ)
    • 1 <<< 100 < 10
  4. スループット観点では4KB-400KBの間がいい感じ
  5. 件数観点では小さい程早い傾向
On-Memoryデータの場合
  • Randomアクセス、Sequentialアクセスの差が無い
  • グラフ上の逆転現象もそうだが計測誤差が大きい。
  • 実は乗り切ってなくて稀にメモリに乗切るのか?(まあ気にならない位速いからこれ以上追及しない)
Diskアクセスの場合
  • Sequential >>> Random
    • ドキュメントサイズが4KBを大きく超えると差が小さくなる
  • 並列度を上げていくとどちらもディスクI/Oの限界(60MB/s程度)で頭打ち
ランダムFETCH性能
  1. オンメモリデータ結果がシーケンシャルアクセスより成績が良い
    • が、、オンメモリではデータ領域での配置はそもそも関係ない。計測誤差だろう。
  2. 小さい(大量の)ドキュメントのディスクアクセスの結果が、前回の結果より10倍以上程度早い。
    • 前回はインデックスサイズが大きすぎて、一旦メモリに載せたインデックスがクエリー中にページフォルトしていた可能性が高い。
    • インデックスがメモリに乗らなきゃ話にならないという事
  3. メモリは偉大
    • 実に2桁違う!
    • 40KB付近を境にドキュメントサイズが大きくなると性能差が縮んでいく
      • スループット(MB/s)が突然数倍(60MB/s程度まで)改善する
      • フェッチ数が少ないので一番ネックになるであろうHDDのヘッドの先頭合わせの回数が減る。
      • 1ドキュメントが大きいとシーケンシャル読みになり効率が良い。
      • 更にカーネル側で256KBの先読みも働くので無駄が減る(別の処理中も裏で読んでてくれる)。
  4. 期待値
    • ディスクデータでは数千〜数万件/s のオーダーまで
    • オンメモリデータでは数十万件〜?/s のオーダーまで期待できる

ちゃんと使えば十二分早い。というかめちゃくちゃ速い。

4KB未満の小さいデータは小さい程メモリに載せないと遅くなる。(数千件/s程度なら気にしなくてよいが)
40KB以上のデータはディスク運用してもそれなりに動く。

シーケンシャルFETCH性能

データファイル上の配置まで気にするのは面倒だが、条件を満たせば劇的に早くなる

  1. ディスクアクセスの時だけの話
    • データの大半がメモリーに乗るなら考えなくて良い
    • 逆に積極的にディスクを使うなら考慮する価値大あり
  2. 効けば数十倍の性能差
  3. ディスクI/Oの限界がある為並列度が高い場合は効果が薄くなる
グラフ


graph

graph

ランダムFETCH性能

ディスクデータ

データ領域をランダムアクセスする条件&1スレッド
(ワーストケース)400Bが数千件では悲しい・・・

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 267.070 3744.3 1.37 5.0
mild 1 KB 53.307 7503.6 7.22 7.7
normal 4 KB 39.584 2526.2 9.83 7.0
extent 10 KB 21.776 1836.8 17.91 10.8
large 40 KB 7.488 1335.3 52.14 34.1
more 100 KB 5.378 743.7 72.61 58.3
pretty 400 KB 6.076 164.5 64.28 46.9
extra 1 MB 6.857 58.3 56.96 25.3
massive 4 MB 3.357 29.7 116.35 56.8


データ領域をランダムアクセスする条件&10スレッド
並列度が上がると効率が上がってくる(CPU使用率に注目)

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 59.598 16778.9 6.16 31.4
mild 1 KB 18.924 21137.0 20.33 40.6
normal 4 KB 13.247 7548.6 29.37 21.5
extent 10 KB 10.856 3684.3 35.92 23.0
large 40 KB 6.148 1626.5 63.51 32.3
more 100 KB 5.863 682.2 66.61 35.8
pretty 400 KB 4.901 204.0 79.69 42.0
extra 1 MB 3.339 119.7 116.98 108.4
massive 4 MB 2.228 44.8 175.26 128.7


データ領域をランダムアクセスする条件&100スレッド
大体スループットの頭打ちのラインが解る。連続読み出来ないサイズ(1ページ4KB以下)で明暗くっきり

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 15.387 64987.6 23.86 116.0
mild 1 KB 11.311 35361.8 34.02 133.9
normal 4 KB 12.405 8061.2 31.37 130.5
extent 10 KB 5.293 7556.6 73.68 130.1
large 40 KB 6.601 1514.7 59.14 240.9
more 100 KB 6.420 623.0 60.83 191.7
pretty 400 KB 3.143 318.0 124.24 141.2
extra 1 MB 6.100 65.5 64.03 92.1
massive 4 MB 8.352 11.9 46.76 151.0

モリーデータ

どのケースも申し分ない速さ。1 nodeでこれなら大抵困らない。
データ領域をランダムアクセスする条件&1スレッド

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 3.827 261260.9 95.92 95.6
mild 1 KB 2.703 147981.3 142.39 85.8
normal 4 KB 1.655 60396.9 235.06 79.7
extent 10 KB 1.374 29094.5 283.71 74.1
large 40 KB 1.134 8815.6 344.23 84.6
more 100 KB 0.933 4283.4 418.24 95.3
pretty 400 KB 1.024 976.0 381.27 86.8
extra 1 MB 1.729 231.3 225.91 51.4
massive 4 MB 1.341 74.5 291.07 53.6


データ領域をランダムアクセスする条件&10スレッド

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 1.392 718117.8 263.66 266.4
mild 1 KB 0.850 470329.8 452.57 244.5
normal 4 KB 0.582 171724.2 668.34 212.9
extent 10 KB 0.479 83474.0 813.98 194.0
large 40 KB 0.459 21782.3 850.56 200.3
more 100 KB 0.468 8540.5 833.91 190.0
pretty 400 KB 0.432 2312.3 903.23 189.6
extra 1 MB 0.516 774.6 756.44 158.7
massive 4 MB 0.700 142.8 557.91 98.5


データ領域をランダムアクセスする条件&100スレッド

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 1.676 596360.1 218.96 224.2
mild 1 KB 1.095 365097.0 351.31 196.2
normal 4 KB 0.770 129718.8 504.85 137.5
extent 10 KB 0.599 166757.8 649.01 195.1
large 40 KB 0.536 74556.7 727.02 165.8
more 100 KB 0.431 9269.1 905.05 183.0
pretty 400 KB 0.471 2120.6 828.36 176.0
extra 1 MB 0.518 770.9 752.91 132.9
massive 4 MB 0.517 193.0 754.18 148.6

シーケンシャルFETCH性能

ディスクデータ

全体的にディスクの構造上の特徴が良く出ている。
データ領域をシーケンシャルアクセスする条件&1スレッド
ランダムアクセス時の性能と比べて劇的に速い

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 6.964 143593.3 52.72 71.3
mild 1 KB 7.344 54461.1 52.40 50.2
normal 4 KB 5.195 19247.3 74.90 58.8
extent 10 KB 4.203 9515.5 92.78 70.6
large 40 KB 4.919 2032.7 79.37 64.8
more 100 KB 3.986 1003.2 97.96 55.9
pretty 400 KB 5.956 167.8 65.58 38.2
extra 1 MB 5.997 66.6 65.12 32.3
massive 4 MB 3.550 28.1 110.00 40.8


データ領域をシーケンシャルアクセスする条件&10スレッド
この辺で頭打ち。(CPU的にもいい感じ)オンメモリとまでは行かないが十分頑張ってる!
大きなドキュメントでは効果が薄い

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 3.636 274952.4 100.95 207.8
mild 1 KB 2.969 134720.4 129.63 177.8
normal 4 KB 2.965 33723.5 131.25 179.4
extent 10 KB 2.435 16425.5 160.17 172.0
large 40 KB 2.572 3887.2 151.78 175.3
more 100 KB 1.987 2012.1 196.46 155.4
pretty 400 KB 3.193 313.1 122.32 183.1
extra 1 MB 3.902 102.5 100.10 199.3
massive 4 MB 4.124 24.2 94.71 214.1

データ領域をシーケンシャルアクセスする条件&100スレッド
並列度を上げ過ぎると逆に劣化する。同時に複数の場所のデータを読むから効率落ちるのか?

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 5.700 175418.3 64.40 189.2
mild 1 KB 4.843 82583.6 79.46 202.7
normal 4 KB 4.326 23114.4 89.96 149.5
extent 10 KB 5.273 7585.3 73.96 158.3
large 40 KB 5.494 1819.8 71.06 169.2
more 100 KB 4.898 816.6 79.73 221.3
pretty 400 KB 4.289 233.1 91.06 176.0
extra 1 MB 5.309 75.3 73.56 193.7
massive 4 MB 4.374 22.8 89.30 58.7

モリーデータ

メモリはシーケンシャルもランダムも関係ない
データ領域をシーケンシャルアクセスする条件&1スレッド

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 3.284 304474.8 111.79 90.1
mild 1 KB 2.058 194329.5 186.99 83.5
normal 4 KB 1.884 53054.8 206.48 65.2
extent 10 KB 1.196 33424.5 325.93 73.5
large 40 KB 1.036 9649.1 376.78 85.8
more 100 KB 1.096 3649.1 356.30 90.3
pretty 400 KB 1.776 563.0 219.91 54.6
extra 1 MB 2.231 179.2 175.03 41.6
massive 4 MB 1.626 61.4 240.13 54.0


データ領域をシーケンシャルアクセスする条件&10スレッド

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 1.096 912165.7 334.91 239.8
mild 1 KB 0.844 473511.7 455.64 216.6
normal 4 KB 0.751 133068.6 517.89 199.6
extent 10 KB 0.660 60592.1 590.85 172.6
large 40 KB 0.552 18089.5 706.36 184.5
more 100 KB 0.594 6728.7 657.00 164.8
pretty 400 KB 0.635 1572.7 614.35 168.2
extra 1 MB 0.639 625.0 610.38 137.5
massive 4 MB 0.643 155.3 606.99 124.3

データ領域をシーケンシャルアクセスする条件&100スレッド

ドキュメントサイズ 件/秒 サイズ(MB/秒) CPU(%)
small 400 B 1.438 695143.4 255.23 201.5
mild 1 KB 1.416 282358.2 271.70 155.2
normal 4 KB 0.913 109409.4 425.81 134.5
extent 10 KB 0.758 52701.8 513.91 126.4
large 40 KB 0.705 14171.2 553.36 155.7
more 100 KB 0.606 6590.5 643.51 161.4
pretty 400 KB 0.667 1498.9 585.49 140.8
extra 1 MB 0.734 544.7 531.97 130.7
massive 4 MB 0.561 178.1 695.87 140.7