More Related Content
Similar to SSDとTokyoTyrantやMySQLの性能検証 (20)
SSDとTokyoTyrantやMySQLの性能検証
- 1. 1
ゆめみ社内勉強会
SSDとTokyoTyrantやMySQLの
性能検証
- 2. 2
経緯
• 今後、ソーシャルアプリ開発でSSDや
TokyoTyrantなどを使いたい
• メーカーさんのおかげで、SSD搭載サーバの
評価機を2週間借りられることになった
• 是非検証したい!
- 3. 3
目的
• SSD搭載サーバは30万円くらいプラスになる
ので、費用対効果を知りたい
• SSDとHDDの性能や特徴について調査する
• 特に、TokyoTyrantなどのミドルウェアとの相
性について調査する
- 4. 4
サーバスペック・検証環境
• サーバスペック
– CPU: 「Xeon E5502 @ 1.87GHz」 ×2(Dual)×2
– DISK
• SSD RAID1 46GB (OS、ログ等用)
• SSD RAID1 46GB (データ用)
• HDD(10000RPM) RAID1 67GB(データ用)
– OS: CentOS 5 (設定はほとんどいじっていない)
– Memory: 8GB
• 負荷をかけるクライアント
– 最初は(a)でやっていたが、後半は(b)でやった(bの方がスコアが良
かったので)
• (a) Remote(スイッチ1つ隔てた)のVMWare
• (b) localhost(サーバ自身から)
- 5. 5
TokyoTyrant を使った検証
※ http://alpha.mixi.co.jp/blog/?cat=11&paged=4 などから転載
- 6. 6
TokyoTyrantとは
• TokyoTyrant(以降、TTと略)最近巷で話題の KVS
– 1万~数万QPS(Query Per Second)くらい出るという噂
• memcached に匹敵する数値
– 今回のソーシャルアプリでも導入予定
• 内部では TokyoCabinet が使われている
– ちなみに TokyoCabinetは、 kumofs でも使われている
• 一体、SSDでどれほどのパフォーマンスが出せるのか
実に楽しみである
- 7. ちょっと蛇足補足 7
Hashデータベースの基本・1
例えば、1億個のデータから「devil」という値を探したい
1億個
・・・
どこにあるのかわからない
最初から順番に探すと時間がかかる
(平均5千万回検査が必要)
それでは遅すぎるので
「データ」→「ハッシュ値」→「データの場所」という流れで探すのがHashデータベース
- 8. ちょっと蛇足補足 8
Hashデータベースの基本・2
「ハッシュ関数が適切」で「目次が十分大きい」ならば、ほとんどデータのハッシュ値が重
複しないという特性を利用する
事前に全領域を確保する必要があるので、無闇に大きくすると「空間効率」が悪い。
小さすぎるとハッシュ値の重複が増えるので、「時間効率」が悪い。(トレードオフの関係)
mikio penguin devil
ハッシュ値
による目次
1つ1つの
データ
- 9. 9
TTやサーバの設定
• 最初は以下の設定
– bnum(bucket num): 1千万
– ulog(update log): /var 以下に出力
• つまり、ulogは別デバイスへ出力(1ファイル 256MB)
– ものすごい勢いでログが増えるので、cronで定期的に削除
– 後はデフォルト設定
• Filesystem
– ext3: noatime, (writebackは最初付けてない)
- 10. 10
検証方法
• 最初TTの全データを削除
• N件のデータを投入
• “cc”並列で readのみ writeのみを○○分間実行
• 最後の△分間のQuery数を集計して平均で評価
• その他
– Keyの分布は最初偏りを持たせるために「正規分布」で
行っていたが後半は「random」で行った
• その方が意味のある検証になるとわかったので
• Keyは 40byte
– サーバのリソース状況は取っていたけど、基本IO以外は
すかすか なので、割愛します
- 11. • SSD 11
•N=500万
• 5分中最後の2分を集計
• remoteから検証
• Key分散: 正規分布 まずはざっくりと
並列数が10が一番性能が出ている。50とかで性能が下
Valueのバイト数が 大きくなると、
がるのはBnechmarkツールの問題が大きいだろう。
write に大きな影響が出るようだ。
read/sec write/sec
12,000 6,000
10,000 5,000
8,000 4,000
write/sec
read/sec
6,000 3,000
4,000 2,000
2,000 1,000
0 0
100 1000 100 1000
1 2,343 1,230 1 1,921 791
10 10,408 9,003 10 4,821 942
50 3,814 3,442 50 2,383 834
100 777 1,060 100 2,080 558
のバイト数 のバイト数
Valueのバイト数
並列数 Valueのバイト数 並列数
っていうか、結果が悪い。目標数万QPSなのに。。
っていうか、結果が悪い。目標数万QPSなのに。。
いうか、結果が悪い。目標数万QPSなのに
上手く負荷がかけられていないのか?
ちなみにデータ投入では、非同期
put(putnr だが、3.5 QPSくらい出ていた
putnr) 3.5万
put(putnr)だが、3.5万QPSくらい出ていた
- 12. • SSD 12
•value: 200Byte(以降同じ)
• 10分中最後の5分を集計
• remoteから検証
• Key分散: 正規分布 Keyの数による変化?
•並列数が10が一番性能が出ている。今後は10でいいかな。
N=5000万のWriteのみ急激に悪くなる。。謎!
N=5000万のWriteのみ急激に悪くなる。。謎!
万のWriteのみ急激に悪くなる。。
bnum=1
bnum=1千万だが、あまり性能が落ちない不思議・・?
•bnum=1千万だが、あまり性能が落ちない不思議・・?
並列数とKeyRange毎の
並列数と 毎のRead性能
毎の 性能 並列数とKeyRange毎の
並列数と 毎のWrite性能
毎の 性能
12,000 ←大差なし→
大差なし→ 6,000
10,000 5,000
8,000 4,000
write/sec
read /sec
6,000 3,000
4,000 2,000
2,000 1,000
0 0
10 15 20 並列数 10 15 20 並列数
5,000,000 10,487 10,459 9,695 5,000,000 2,910 3,288 2,741
20,000,000 10,869 10,626 9,709 20,000,000 3,371 2,792 2,648
50,000,000 10,831 10,703 9,729 50,000,000 591 547 547
100,000,000 10,818 9,869 100,000,000 4,764 3,847 3,920
Key数 Key数
5000万件でファイルサイズは約13GB
5000万件でファイルサイズは約13GB
万件でファイルサイズは約 Nが大きい方が良い・・・謎!普通逆。
- 13. • SSD 13
• N=500万件
•5分中最後の2分を集計
• localから検証
• Key分散: 正規分布 localhost から検証
• やはり並列数が10が一番性能が出ている。今後は10でいいかな。
• Writeが極めて低くなっている。ベンチマークの状態を見ると、数秒間5000/secだった
数秒間5000/secだった
数秒間5000/secだっ
り50/secだったりと非常に波がある
50/secだったりと非常に波があることが観測されている(pdflush問題)
だったりと非常に波がある
• Localからの方がよく負荷がかかるようである → 今後は local で実行する
並列数とRW性能
並列数と 性能
30,000 1,000
900
25,000
800
700
20,000
600
write/sec
read/sec
15,000 500
400
10,000
300
200
5,000
100
0 0
1 10 20 30 50 100
Read 10,818 27,794 21,338 20,827 19,368 14,339
Write 879 867 863 917 785 860
並列数
- 14. • SSD 14
•10分中最後の5分を集計
•Key分散: 正規分布
• 並列数:10
• N=5000万、bnum=1億 Keyの分散とMGET性能
• Key の分散を大きくしても結果は変わらず・・なぜ?
• MGETは、かなり性能が良い(100個取得するのに、10分の1の応答速度 -> 約10倍)
• HDD版実施: read=1000qps以下、 write=400qps以下
性能
Read性能 性能
write性能
160,000 450
140,000 400
350
120,000
300
100,000
write/sec
read/esc
250
80,000
200
60,000
150
40,000 100
20,000 50
0 0
200000 1000000 200000 1000000
1 15,516 17,916 1 369 404
100 149,215 148,702 100 333 377
アクセスするKeyの標準偏差
アクセスする の標準偏差 アクセスするKeyの標準偏差
アクセスする の標準偏差
mget数 mget数
分散: 小さい ← → 大きい ※意味なし 分散: 小さい ← → 大きい
writeが地を這うようになってきた・・・
writeが地を這うようになってきた・・・ orz
- 15. 15
ちょっと考察
• どういうことが起こっているのかわからない
– readで3万QPS弱出たと思えば、1.5万だったり
– writeで5千QPS出たと思えば、500だったり
– 何がパラメータなのか?どうすれば安定して1万QPS出るの
か?
• SSDにせよ、HDDにせよ、世間的公称値(1万程度?)に全
然届いていない
– このままじゃ「使えない」という結論になりかねない
– 何かものすごい勘違いをしている可能性がある
• 目的変更
– 「どうすれば良いパフォーマンスが出るのか」
- 16. 16
いくつかの対策を試す
• Filesystemをwritebackにしてみる
–噂
• 2~3倍になることがある
– 当時の結果
• ほとんど変わらず … orz
• I/Oサブシステムの設定をいじる
– cfq, noop, deadline、どれも大差なし
- 17. 17
そういえば・・・
• 最初にデータを投入するときは、SSDもHDDも非
同期putとはいえ3.5万QPSくらい出ている
– DISK IO自体にはそれくらいの性能があるはず
• もう少し調べてみると「性能に波がある」原因は
「pdflush」というプロセスがBlockしているようだ
– pdflush は、DiskCache を flushするやつらしい
• そういえば、「キャッシュ」はどうなっている?
- 18. 18
キャッシュに関連するパラメータ
• TTの 「xmsiz」
– デフォルト: 64MB
– ファイルの先頭からTT内でメモリ上に保持するサ
イズ
• OSのFileCache
– TTのデータファイルは1ファイルである
• 結構OSのCacheに載っているようだ
- 19. 19
キャッシュに注目して検証みる
• TTの「xmsiz=2GB」に変更
• 各キャッシュがあるとき、ない時で検証
– OSのキャッシュの操作
• 載せる: cat [TTファイル] > /dev/null する
• 載せない: 別の巨大なファイルを cat [file] > /dev/null する
– TTのキャッシュの操作
• 載せる: 起動時にデータを投入する
• 載せいない: TTを再起動する
• 結果
– TTのキャッシュやOSのキャッシュにデータが載っていると
きは10倍~100倍くらい動作が速くなっている感じがある
きっとポイントはこれだ・・・
- 20. 20
仮説
• キャッシュで100倍近く変わるというのは、下記の
ような式を思い出させる
平均処理時間=αX + (1-α)Y
α: CacheHit率
X: Cacheにある時の応答時間
Y:Cacheにない時の応答時間
• 仮にYがXの100倍くらいだとすれば、説明がつき
そう
– 実際、MemoryとDISKの差はそれくらいあるだろうし
- 21. 21
仮説の検証
• 検証方法
– なるべくTTとOSにキャッシュをさせた状態で検証する
– キャッシュに載り切らないデータに対して、Randomに
アクセスすれば、CacheHit率をコントロールできる
最大8GB
cache disk 平均CacheHit率=8/13=61%
例えば13GB
– 今回Memory8GBで、Key数5000万件で13GBのデー
タなので、Key数=500万~1.5億の範囲で測定
- 22. • 30分中最後の10分を集計 22
検証結果
• localから検証
• Key分散: ランダム
• 並列数: 10
• bnum=3憶、xmsiz=2GB
• Memoryに載っている時は、SSD,HDDともに2.5万QPS以上
• Memoryに載らなくなってくると、急激に落ちる。が、SSDのReadはかなり頑張っている
• HDD:SSD だと、 Readが約10~20倍、Writeが約5倍
この辺がwrite時のCacheMax と性能
Cacheと性能
30,000
この辺がread時のCacheMax
25,000
20,000
QPS
15,000
10,000
5,000
0
500万 2000万 5000万 1億 1.5億
SSD Read 27,653 26,754 18,684 11,536 8,937
HDD Read 27,586 26,811 1,581 696 486
SSD Write 25,741 14,192 1,026 548 430
HDD Write 26,383 6,817 182 115 87
ファイルサイズ 1.3GB 5.2GB 13GB 26GB 39GB
- 23. 23
仮説のモデルは正しいのか?
• 平均応答時間が以下のモデルであると仮定して実験
結果から各パラメータを計算してプロットしたグラフ
平均処理時間=αX + (1-α)Y
α: CacheHit率 SSD read
X: Cacheにある時の応答時間
Y:Cacheにない時の応答時間 HDD read
SSD Write(赤)
HDD Write(緑)
N(百万件)
なんとなく従っているように見える?
もう少し中間の点をとってみて検証すれば良いだろうが、まあもう良し
とする
- 24. 24
何故Writeが先に悪くなるのか?
• 仮説1:xmsizが関係している
– → xmsizの分だけ OSのCacheが少なくなっている
こんなイメージ
readの時はどこかにあれば良い(約8GB分使える)。
(xmsiz分はosに読み取りの依頼をしないのでoscacheか
らはなくなり、他のデータが入ることができる)
xmsiz oscache
writeの時は 両方に書き込みをする.
(ユニークなデータは、8GB-2GB=6GB分)
• 仮説2: ulog の分 oscacheを使っている
- 26. 26
検証方法
• MySQL Benchを使用
• 設定
– テーブルはInnoDB
– InnoDB Buffer Pool: 1GB
– OS の FileCacheはOffにした
メモリに載る最大データ量は1GBになる
- 27. 27
並列数とTPS
Engine: InnoDB
bin-logあり
scale=10 (100万件)
1Thread辺りのアクセス回数 =10万 並列数とTPS
並列数と
3000
2500
2000
TPS
1500
1000
500
0
1 10 50 100
HDD 1142 2466 2316 1932
SSD 1169 2533 2327 1936
並列数
どの辺りの並列数が一番負荷がかかるか→10
10くらい
10
- 28. 28
Engine: InnoDB
結果
bin-logなし
並列数=10
1Thread辺りのアクセス回数 =10万
この辺までは ほぼ OnMemoryなので差がない
TPC-B Select Only
6,000 6,000
5,000 5,000
4,000 4,000
TPS
TPS
3,000 3,000
2,000 2,000
1,000 1,000
0 0
10 20 30 50 70 90 100 150 200 250 10 20 30 50 70 90 100 150 200 250
HDD 5,072 5,090 5,057 4,894 3,762 1,421 993 431 332 349 HDD 5,046 5,069 5,040 4,766 4,166 1,335 950 413 322 340
SSD 4,823 5,032 4,967 4,830 4,102 2,238 1,748 950 891 865 SSD 4,951 4,991 4,939 4,663 4,253 2,110 1,703 913 853 822
Scale(×10万件)
×10万件 Scale(×10万件)
×10万件
読み書きともに約2.5倍程度SSDの方が良い結果
- 30. 30
まとめ1:ソーシャルアプリ的TTの結論
• 1万QPSを超えたければ、以下のようにする
– SSDを使うより、メモリをたくさん積んだマシンを用意する
– メモリ内におさまるデータ量で運用する
• 全体がオーバーしていても短時間でアクセスされるデータが、
98%くらいOnMemoryで2%くらいDISKなら、10000QPSくらいは確保できそう
• リスクと対策
– メモリ内に未フラッシュのデータが大量に残っているのは危険
• 障害発生時にデータが失われる
• でも、開発中のソーシャルアプリへの適用なら問題はないのでOK
– 一応、レプリケーションはしているし
– TTはデータ量はScaleOutで解決しない
• kumofsを使う!
• 未検証項目
– writebackの効果(writeback OFF で再検証したら良さそう)
– 最適なxmsizやその他TTパラメータ
- 31. 31
まとめ2:SSD 対 HDD
• TTの場合、およそ巷の噂通りSSDの方が良い
– Readで10~20倍程度
– Writeで~5倍程度
– ただし、OnMemoryから外れると1万QPSとか無理
• MySQLの場合、もっと複雑な要因はありそうだが
– およそ、SSDが2.5倍程度良い
- 33. 33
Inside: TT(or TC):設定値
データレイアウト
128Byte固定
xmsiz:
xmsiz 先頭か
ら何バイトTT内 bnum × 4(or 8)byte
にCacheするか
(default=64MB) 2^fpow (default: fpow=10)
fpow個
fpow
1レコードは (2^apow apow)Byteの整数倍
apow
(default apow=4)
Hash値が衝突したら後は2分木探索でレコー
ドを探す。→ o(logN)で探索可能(左右のバラ
ンスも工夫している)。
フラグメント防止のために連続したFreeSpaceを回収する
HashDBだと8くらいがオススメらしい
dfunit(default=0 つまりOFF)。
dfunit
OPTS:
OPTS “l”=(64bitのアドレス指定), “d”=deflate圧縮 など
“d”は使えそう
図は作者のBlogより
- 34. 34
Inside: TT(or TC):値の探索イメージ
図は作者のBlogより