SlideShare a Scribd company logo
1




     ゆめみ社内勉強会

SSDとTokyoTyrantやMySQLの
        性能検証
2




             経緯
• 今後、ソーシャルアプリ開発でSSDや
  TokyoTyrantなどを使いたい

• メーカーさんのおかげで、SSD搭載サーバの
  評価機を2週間借りられることになった

• 是非検証したい!
3




            目的
• SSD搭載サーバは30万円くらいプラスになる
  ので、費用対効果を知りたい

• SSDとHDDの性能や特徴について調査する
• 特に、TokyoTyrantなどのミドルウェアとの相
  性について調査する
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




             TokyoTyrant を使った検証




※ http://alpha.mixi.co.jp/blog/?cat=11&paged=4 などから転載
6




          TokyoTyrantとは
• TokyoTyrant(以降、TTと略)最近巷で話題の KVS
  – 1万~数万QPS(Query Per Second)くらい出るという噂
    • memcached に匹敵する数値
  – 今回のソーシャルアプリでも導入予定
• 内部では TokyoCabinet が使われている
  – ちなみに TokyoCabinetは、 kumofs でも使われている

• 一体、SSDでどれほどのパフォーマンスが出せるのか
  実に楽しみである
ちょっと蛇足補足                                         7


           Hashデータベースの基本・1
  例えば、1億個のデータから「devil」という値を探したい

                         1億個


                          ・・・




                 どこにあるのかわからない



               最初から順番に探すと時間がかかる
                 (平均5千万回検査が必要)

            それでは遅すぎるので

    「データ」→「ハッシュ値」→「データの場所」という流れで探すのがHashデータベース
ちょっと蛇足補足                                          8


           Hashデータベースの基本・2
     「ハッシュ関数が適切」で「目次が十分大きい」ならば、ほとんどデータのハッシュ値が重
     複しないという特性を利用する
     事前に全領域を確保する必要があるので、無闇に大きくすると「空間効率」が悪い。
     小さすぎるとハッシュ値の重複が増えるので、「時間効率」が悪い。(トレードオフの関係)

              mikio   penguin   devil
 ハッシュ値
 による目次




  1つ1つの
   データ
9




         TTやサーバの設定
• 最初は以下の設定
  – bnum(bucket num): 1千万
  – ulog(update log): /var 以下に出力
     • つまり、ulogは別デバイスへ出力(1ファイル 256MB)
       – ものすごい勢いでログが増えるので、cronで定期的に削除
  – 後はデフォルト設定

• Filesystem
  – ext3: noatime, (writebackは最初付けてない)
10




              検証方法
•   最初TTの全データを削除
•   N件のデータを投入
•   “cc”並列で readのみ writeのみを○○分間実行
•   最後の△分間のQuery数を集計して平均で評価
•   その他
    – Keyの分布は最初偏りを持たせるために「正規分布」で
      行っていたが後半は「random」で行った
      • その方が意味のある検証になるとわかったので
      • Keyは 40byte
    – サーバのリソース状況は取っていたけど、基本IO以外は
      すかすか なので、割愛します
• 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くらい出ていた
• 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が大きい方が良い・・・謎!普通逆。
• 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
                                                          並列数
• 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




          ちょっと考察
• どういうことが起こっているのかわからない
 – readで3万QPS弱出たと思えば、1.5万だったり
 – writeで5千QPS出たと思えば、500だったり
 – 何がパラメータなのか?どうすれば安定して1万QPS出るの
   か?
• SSDにせよ、HDDにせよ、世間的公称値(1万程度?)に全
  然届いていない
 – このままじゃ「使えない」という結論になりかねない
 – 何かものすごい勘違いをしている可能性がある



• 目的変更
 – 「どうすれば良いパフォーマンスが出るのか」
16




       いくつかの対策を試す
• Filesystemをwritebackにしてみる
  –噂
    • 2~3倍になることがある
  – 当時の結果
    • ほとんど変わらず … orz


• I/Oサブシステムの設定をいじる
  – cfq, noop, deadline、どれも大差なし
17




           そういえば・・・
• 最初にデータを投入するときは、SSDもHDDも非
  同期putとはいえ3.5万QPSくらい出ている
 – DISK IO自体にはそれくらいの性能があるはず


• もう少し調べてみると「性能に波がある」原因は
  「pdflush」というプロセスがBlockしているようだ
 – pdflush は、DiskCache を flushするやつらしい


• そういえば、「キャッシュ」はどうなっている?
18




 キャッシュに関連するパラメータ
• TTの 「xmsiz」
  – デフォルト: 64MB
  – ファイルの先頭からTT内でメモリ上に保持するサ
    イズ


• OSのFileCache
  – TTのデータファイルは1ファイルである
    • 結構OSのCacheに載っているようだ
19




 キャッシュに注目して検証みる
• TTの「xmsiz=2GB」に変更
• 各キャッシュがあるとき、ない時で検証
 – OSのキャッシュの操作
   • 載せる: cat [TTファイル] > /dev/null する
   • 載せない: 別の巨大なファイルを cat [file] > /dev/null する
 – TTのキャッシュの操作
   • 載せる: 起動時にデータを投入する
   • 載せいない: TTを再起動する
• 結果
 – TTのキャッシュやOSのキャッシュにデータが載っていると
   きは10倍~100倍くらい動作が速くなっている感じがある

           きっとポイントはこれだ・・・
20




               仮説
• キャッシュで100倍近く変わるというのは、下記の
  ような式を思い出させる
         平均処理時間=αX + (1-α)Y

         α: CacheHit率
         X: Cacheにある時の応答時間
         Y:Cacheにない時の応答時間

• 仮にYがXの100倍くらいだとすれば、説明がつき
  そう
 – 実際、MemoryとDISKの差はそれくらいあるだろうし
21




              仮説の検証
• 検証方法
 – なるべくTTとOSにキャッシュをさせた状態で検証する
 – キャッシュに載り切らないデータに対して、Randomに
   アクセスすれば、CacheHit率をコントロールできる
     最大8GB


     cache     disk    平均CacheHit率=8/13=61%


             例えば13GB


 – 今回Memory8GBで、Key数5000万件で13GBのデー
   タなので、Key数=500万~1.5億の範囲で測定
• 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




     仮説のモデルは正しいのか?


• 平均応答時間が以下のモデルであると仮定して実験
結果から各パラメータを計算してプロットしたグラフ



 平均処理時間=αX + (1-α)Y

 α: CacheHit率                                          SSD read

 X: Cacheにある時の応答時間
 Y:Cacheにない時の応答時間                           HDD read




                             SSD Write(赤)
                             HDD Write(緑)
                                                                  N(百万件)

                            なんとなく従っているように見える?
                            もう少し中間の点をとってみて検証すれば良いだろうが、まあもう良し
                            とする
24




 何故Writeが先に悪くなるのか?
• 仮説1:xmsizが関係している
  – → xmsizの分だけ OSのCacheが少なくなっている
  こんなイメージ
      readの時はどこかにあれば良い(約8GB分使える)。
      (xmsiz分はosに読み取りの依頼をしないのでoscacheか
      らはなくなり、他のデータが入ることができる)

               xmsiz      oscache


            writeの時は 両方に書き込みをする.
            (ユニークなデータは、8GB-2GB=6GB分)


• 仮説2: ulog の分 oscacheを使っている
25




MySQLと
MySQLとmysqlbench
   を使った検証
26




              検証方法
• MySQL Benchを使用
• 設定
 – テーブルはInnoDB
 – InnoDB Buffer Pool: 1GB
 – OS の FileCacheはOffにした


         メモリに載る最大データ量は1GBになる
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




 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の方が良い結果
29




まとめ
30




 まとめ1:ソーシャルアプリ的TTの結論
• 1万QPSを超えたければ、以下のようにする
  – SSDを使うより、メモリをたくさん積んだマシンを用意する
  – メモリ内におさまるデータ量で運用する
     • 全体がオーバーしていても短時間でアクセスされるデータが、
       98%くらいOnMemoryで2%くらいDISKなら、10000QPSくらいは確保できそう


• リスクと対策
  – メモリ内に未フラッシュのデータが大量に残っているのは危険
     • 障害発生時にデータが失われる
     • でも、開発中のソーシャルアプリへの適用なら問題はないのでOK
        – 一応、レプリケーションはしているし
  – TTはデータ量はScaleOutで解決しない
     • kumofsを使う!


• 未検証項目
  – writebackの効果(writeback OFF で再検証したら良さそう)
  – 最適なxmsizやその他TTパラメータ
31




      まとめ2:SSD 対 HDD
• TTの場合、およそ巷の噂通りSSDの方が良い
 – Readで10~20倍程度
 – Writeで~5倍程度
 – ただし、OnMemoryから外れると1万QPSとか無理


• MySQLの場合、もっと複雑な要因はありそうだが
 – およそ、SSDが2.5倍程度良い
32




TTの中身の話
TTの中身の話
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




    Inside: TT(or TC):値の探索イメージ




図は作者のBlogより

More Related Content

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を使っている
  • 25. 25 MySQLと MySQLとmysqlbench を使った検証
  • 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より