MongoDB sharding
  C10Kとの戦い
Shardingおさらい



     -2 -
Simple case
                     client host
httpd    httpd   httpd   httpd   httpd   httpd   httpd

mongos
server

client




mongod
            shard1                  shard2



                                         -3 -
Simple case
                     client host
httpd    Give mehttpd httpd
         httpd  DATA_A !       httpd   httpd   httpd

mongos
server

client




mongod
            shard1                 shard2



                                       -4 -
Simple case
                     client host
httpd    Give mehttpd httpd
         httpd  DATA_A !       httpd   httpd   httpd

mongos
server                    Where is the DATA_A ?

client




mongod
            shard1                 shard2



                                       -5 -
Simple case
                     client host
httpd    Give mehttpd httpd
         httpd  DATA_A !        httpd   httpd   httpd

mongos
server

client               Shard1 is saving it !




mongod
            shard1                 shard2



                                         -6 -
Simple case
                     client host
httpd    Give mehttpd httpd
         httpd  DATA_A !       httpd   httpd   httpd

mongos
server

client



                 Give me DATA_A !




mongod
            shard1                 shard2



                                       -7 -
Simple case
                     client host
httpd    Give mehttpd httpd
         httpd  DATA_A !       httpd   httpd   httpd

mongos
server

client




           This is DATA_A.
mongod
            shard1                 shard2



                                       -8 -
Simple case
                     client host
httpd    httpd   httpd   httpd   httpd   httpd   httpd

mongos
server
     This is DATA_A.
client




mongod
            shard1                  shard2



                                         -9 -
Connection pool



      -10 -
Connection pool
                     client host
httpd    httpd   httpd   httpd   httpd   httpd   httpd

mongos
server

client




                         Used connection is pooled !


mongod
            shard1                  shard2



                                         -11 -
Connection pool
                     client host
httpd    httpd   httpd   httpd   httpd httpdDATA_A !
                                     Give me  httpd

mongos
server

client




                         Used connection is pooled !


mongod
            shard1                 shard2



                                        -12 -
Connection pool
                     client host
httpd    httpd   httpd   httpd   httpd httpdDATA_A !
                                     Give me  httpd

mongos
server

client           shard1のコネクションが
                     再利用できそう




mongod
            shard1                 shard2



                                        -13 -
Connection pool
                     client host
httpd    httpd   httpd   httpd   httpd httpdDATA_A !
                                     Give me  httpd

mongos
server

client



                   Give me DATA_A !




mongod
            shard1                 shard2



                                        -14 -
Connection pool
                     client host
httpd    httpd   httpd   httpd   httpd httpdDATA_A !
                                     Give me  httpd

mongos
server

client




           This is DATA_A.
mongod
            shard1                 shard2



                                        -15 -
Connection pool
                     client host
httpd    httpd   httpd   httpd   httpd   httpd   httpd
       This is DATA_A.
mongos
server

client




mongod
            shard1                  shard2



                                         -16 -
New connection



      -17 -
Busy case
                     client host
httpd    Give mehttpd httpd
         httpd  DATA_A !       httpd    httpd   httpd

mongos
server

client



                 Give me DATA_A !




mongod
            shard1                  shard2



                                        -18 -
Busy case
                     client host
httpd    httpd   httpd   httpd   httpd httpdDATA_A !
                                     Give me  httpd

mongos
server

client               shard1 へのコネクションは既にあるが
                            今は利用中で使えない!
                      なので新たに1本コネクションを張る




mongod
            shard1                  shard2



                                        -19 -
Busy case
                     client host
httpd    httpd   httpd   httpd   httpd   httpd   httpd

mongos
server

client




mongod
            shard1                  shard2



                                         -20 -
recapitulation

■ mongosの役割
  ●   mongsはクエリーをプロキシし問題を解決してくれる。
  ●   スター型接続になるのでC10K対策にもなる。
  ●   mongos - mongod(shard)間のコネクションをプールし性能向上
  ●   プールするコネクション数は最大同時クエリー数(+α)
         α = mongodの生死チェックの為のコネクションも別途張る



           




                       -21 -
recapitulation

■ mongosの役割
  ●   mongsはクエリーをプロキシし問題を解決してくれる。
  ●   スター型接続になるのでC10K対策にもなる。
  ●   mongos - mongod(shard)間のコネクションをプールし性能向上
  ●   プールするコネクション数は最大同時クエリー数(+α)
         α = mongodの生死チェックの為のコネクションも別途張る




               いい感じジャン!  

                       -22 -
戦いが始まる...



   -23 -
お客が増えたら?



   -24 -
There are alot of clients
                     client host
httpd    httpd   httpd    httpd   httpd   httpd   httpd

mongos
server

client




                         mongod
            shard1                   shard2



                                          -25 -
レプリカ無いと怖いよね...



      -26 -
Keep availability !
                     client host
httpd    httpd   httpd    httpd   httpd   httpd   httpd

mongos
server

client




mongod      mongod       mongod
            shard1                   shard2



                                          -27 -
やっぱshard足んね...



      -28 -
Enough ?
                     client host
httpd    httpd   httpd    httpd   httpd   httpd    httpd

mongos
server

client




mongod      mongod       mongod
            shard1                   shard2       shard3   shard4   shard5



                                          -29 -
How to operate sharding
 そもそもshardingを組むという事はそれなりの規模のデータやトラフィックを扱っている
 のでC10K対策は避けては通れない。

■Shardingシステムは
 接続数の爆発との戦い!!!
■mongod最大コネクション数 = 20000
  ●   制限値を超える接続は拒否されるので一発レッド(サービス停止)
  ●   一見充分な値だが現在のWEBでは簡単に超え得る
      –   PHP on apache(MAX_CLIENT=500) × 4台 がフル稼働で超える計算
      –   実際は5000クライアント程度でも簡単に超える。※後述
  ●       最近のLinuxのTCPバッファデフォルトサイズから考える
      read (rmem) = 16k , write (wmem) = 85k
          101k × 20000 = 2G強
      妥当な設計ではあるが安心はできない

                                      -30 -
コネクション数爆発



    -31 -
Connection inflation
                   client host
httpd Give me DATA_A !

mongos
server

client




mongod
          shard1                 shard2



                                     -32 -
Connection inflation
                   client host
httpd Give me DATA_A !

mongos
server

client




           Give me DATA_A !



mongod
          shard1                 shard2



                                     -33 -
Connection inflation
                  client host
httpd
          Time out (TT;
mongos
server

client




         Give me DATA_A !



mongod
         shard1                 shard2



                                    -34 -
Connection inflation
                  client host
httpd
                  Give me DATA_A !!!
mongos
server

client       前回使ったshard1へのコネクションはまだ使えない
              なので新たに1本コネクションを張る必要がある



         Give me DATA_A !



mongod
         shard1                 shard2



                                    -35 -
Connection inflation
                  client host
httpd
                  Give me DATA_A !!!
mongos
server

client




                     Give me DATA_A !
         Give me DATA_A !



mongod
         shard1                 shard2



                                    -36 -
Connection inflation
                  client host
httpd
                     Time out (TT;
mongos
server

client




                     Give me DATA_A !
         Give me DATA_A !



mongod
         shard1                 shard2



                                     -37 -
Connection inflation
                  client host
httpd             Please give me DATA_A !!!!!!!
                                                  リトライ3回なら
mongos                                             3コネクション消費する
server
                                                   勿論mongodに掛ける負荷も3倍
client

                                                          
                             Give me DATA_A !
                     Give me DATA_A !
         Give me DATA_A !
                                                          
                                                                      
                                                               


mongod                                                                
                                                              
         shard1                 shard2



                                    -38 -
Connection数が爆発
1クライアントでもmongos-mongod間のコネクション数を大量に消費
するケースがある。


どの分散システムにも言えるし接続数に限った話でもないが、



            
  
                               


                              
               -39 -
Connection数が爆発
1クライアントでもmongos-mongod間のコネクション数を大量に消費する
ケースがある。


どの分散システムにも言えるし接続数に限った話でもないが、



エラー時のリトライ禁止! 
 ちょっぴり負荷が掛かり始めたシステムを
 みんなで袋叩きして殺してしまう・・・


リトライして解決なら最初からクライアントが対応してるって。。。




                -40 -
How to operate sharding
■ 危険なケース
 ●   ピーク時間帯に断続的にslow queryが起きている
 ●   クライアントが多く通常時のコネクション数がギリギリだ
 ●   リトライしている
   これらのケースでは障害に至る可能性が特に高い

     また明示的なリトライをせずとも、client - mongos間でTIMEOUTしたクエリーで利
     用したmongos - mongod間コネクションは即座に再利用できない。
   
    接続数を完全に見積もり切る事は困難




                         -41 -
How to operate sharding
■ mongs - mongod コネクションプールの問題
  ●   mongos - mongod間の接続数を制御する手段が無い
      --maxConnsオプションはclient - mongos間のコネクションを扱っている


  ●   mongosは定期的に不必要なコネクションプールを回収するが
   30分以上使われなかったコネクション限定(hardcode)
        瞬間負荷で張ったコネクションを長時間保持し続けてしまう


      結局、本来必要ない接続を張ってしまう。


 最大接続数20000という厳しい制限の元
 この手の無駄はシステムのスケーラビリティを大きく下げる!!


                           -42 -
How to operate sharding
■ 接続数不足の対策
 ●   不必要なクライアントを排除
         安易にapache MAX_CLIENT=1000とかやらない!
     (結局普通のアプリはそんなに食えない)
       通常時mongodの接続数が7000位が安全ギリギリ


 ●   リトライ処理をやめる
      システム保全の方が大事!そもそもリトライが成功する確率も低い。


 ●   slow query抑止のチューニング
     –   table scan禁止 (--notablescan)
     –   M/R 禁止
     –   ピーク時の書き込みを抑止(各種ファイルpreallocateが一番怖い)
     – shard増やす
     – etc...
                                        -43 -
        それでもダメなら、、、


        奥の手だ!


              -44 -
hack




-45 -
-46 -
-47 -
パッチ解説
■ 不要コネクションを回収するタイミングを修正
 ●   1800秒固定→オプションで指定可能
 ●   コネクションプール数の最大値を指定可能
      必要なコネクションは張るが、指定値以上はプールしなくなる


     最小値も指定出来た方が良いんだろうか?
      とりあえず今のところ必要なさそう




                    -48 -
補足

■パッチ
 https://github.com/crumbjp/mongo/commit/b4a424fe0
 2d7b5410db364b2d71f11ce09fd3fc3

■C10K と スター型接続
 http://www.slideshare.net/crumbjp/cockatoo(39p~)




                        -49 -

C10K on Mongo's sharding

  • 1.
    MongoDB sharding C10Kとの戦い
  • 2.
  • 3.
    Simple case client host httpd httpd httpd httpd httpd httpd httpd mongos server client mongod shard1 shard2 -3 -
  • 4.
    Simple case client host httpd Give mehttpd httpd httpd DATA_A ! httpd httpd httpd mongos server client mongod shard1 shard2 -4 -
  • 5.
    Simple case client host httpd Give mehttpd httpd httpd DATA_A ! httpd httpd httpd mongos server Where is the DATA_A ? client mongod shard1 shard2 -5 -
  • 6.
    Simple case client host httpd Give mehttpd httpd httpd DATA_A ! httpd httpd httpd mongos server client Shard1 is saving it ! mongod shard1 shard2 -6 -
  • 7.
    Simple case client host httpd Give mehttpd httpd httpd DATA_A ! httpd httpd httpd mongos server client Give me DATA_A ! mongod shard1 shard2 -7 -
  • 8.
    Simple case client host httpd Give mehttpd httpd httpd DATA_A ! httpd httpd httpd mongos server client This is DATA_A. mongod shard1 shard2 -8 -
  • 9.
    Simple case client host httpd httpd httpd httpd httpd httpd httpd mongos server This is DATA_A. client mongod shard1 shard2 -9 -
  • 10.
  • 11.
    Connection pool client host httpd httpd httpd httpd httpd httpd httpd mongos server client Used connection is pooled ! mongod shard1 shard2 -11 -
  • 12.
    Connection pool client host httpd httpd httpd httpd httpd httpdDATA_A ! Give me httpd mongos server client Used connection is pooled ! mongod shard1 shard2 -12 -
  • 13.
    Connection pool client host httpd httpd httpd httpd httpd httpdDATA_A ! Give me httpd mongos server client shard1のコネクションが 再利用できそう mongod shard1 shard2 -13 -
  • 14.
    Connection pool client host httpd httpd httpd httpd httpd httpdDATA_A ! Give me httpd mongos server client Give me DATA_A ! mongod shard1 shard2 -14 -
  • 15.
    Connection pool client host httpd httpd httpd httpd httpd httpdDATA_A ! Give me httpd mongos server client This is DATA_A. mongod shard1 shard2 -15 -
  • 16.
    Connection pool client host httpd httpd httpd httpd httpd httpd httpd This is DATA_A. mongos server client mongod shard1 shard2 -16 -
  • 17.
    New connection -17 -
  • 18.
    Busy case client host httpd Give mehttpd httpd httpd DATA_A ! httpd httpd httpd mongos server client Give me DATA_A ! mongod shard1 shard2 -18 -
  • 19.
    Busy case client host httpd httpd httpd httpd httpd httpdDATA_A ! Give me httpd mongos server client shard1 へのコネクションは既にあるが 今は利用中で使えない! なので新たに1本コネクションを張る mongod shard1 shard2 -19 -
  • 20.
    Busy case client host httpd httpd httpd httpd httpd httpd httpd mongos server client mongod shard1 shard2 -20 -
  • 21.
    recapitulation ■ mongosの役割 ● mongsはクエリーをプロキシし問題を解決してくれる。 ● スター型接続になるのでC10K対策にもなる。 ● mongos - mongod(shard)間のコネクションをプールし性能向上 ● プールするコネクション数は最大同時クエリー数(+α) α = mongodの生死チェックの為のコネクションも別途張る    -21 -
  • 22.
    recapitulation ■ mongosの役割 ● mongsはクエリーをプロキシし問題を解決してくれる。 ● スター型接続になるのでC10K対策にもなる。 ● mongos - mongod(shard)間のコネクションをプールし性能向上 ● プールするコネクション数は最大同時クエリー数(+α) α = mongodの生死チェックの為のコネクションも別途張る いい感じジャン!   -22 -
  • 23.
  • 24.
  • 25.
    There are alotof clients client host httpd httpd httpd httpd httpd httpd httpd mongos server client mongod shard1 shard2 -25 -
  • 26.
  • 27.
    Keep availability ! client host httpd httpd httpd httpd httpd httpd httpd mongos server client mongod mongod mongod shard1 shard2 -27 -
  • 28.
  • 29.
    Enough ? client host httpd httpd httpd httpd httpd httpd httpd mongos server client mongod mongod mongod shard1 shard2 shard3 shard4 shard5 -29 -
  • 30.
    How to operatesharding そもそもshardingを組むという事はそれなりの規模のデータやトラフィックを扱っている のでC10K対策は避けては通れない。 ■Shardingシステムは 接続数の爆発との戦い!!! ■mongod最大コネクション数 = 20000 ● 制限値を超える接続は拒否されるので一発レッド(サービス停止) ● 一見充分な値だが現在のWEBでは簡単に超え得る – PHP on apache(MAX_CLIENT=500) × 4台 がフル稼働で超える計算 – 実際は5000クライアント程度でも簡単に超える。※後述 ● 最近のLinuxのTCPバッファデフォルトサイズから考える read (rmem) = 16k , write (wmem) = 85k 101k × 20000 = 2G強 妥当な設計ではあるが安心はできない -30 -
  • 31.
  • 32.
    Connection inflation client host httpd Give me DATA_A ! mongos server client mongod shard1 shard2 -32 -
  • 33.
    Connection inflation client host httpd Give me DATA_A ! mongos server client Give me DATA_A ! mongod shard1 shard2 -33 -
  • 34.
    Connection inflation client host httpd Time out (TT; mongos server client Give me DATA_A ! mongod shard1 shard2 -34 -
  • 35.
    Connection inflation client host httpd Give me DATA_A !!! mongos server client 前回使ったshard1へのコネクションはまだ使えない なので新たに1本コネクションを張る必要がある Give me DATA_A ! mongod shard1 shard2 -35 -
  • 36.
    Connection inflation client host httpd Give me DATA_A !!! mongos server client Give me DATA_A ! Give me DATA_A ! mongod shard1 shard2 -36 -
  • 37.
    Connection inflation client host httpd Time out (TT; mongos server client Give me DATA_A ! Give me DATA_A ! mongod shard1 shard2 -37 -
  • 38.
    Connection inflation client host httpd Please give me DATA_A !!!!!!! リトライ3回なら mongos  3コネクション消費する server  勿論mongodに掛ける負荷も3倍 client         Give me DATA_A ! Give me DATA_A ! Give me DATA_A !                                          mongod                                 shard1 shard2 -38 -
  • 39.
  • 40.
  • 41.
    How to operatesharding ■ 危険なケース ● ピーク時間帯に断続的にslow queryが起きている ● クライアントが多く通常時のコネクション数がギリギリだ ● リトライしている   これらのケースでは障害に至る可能性が特に高い また明示的なリトライをせずとも、client - mongos間でTIMEOUTしたクエリーで利 用したmongos - mongod間コネクションは即座に再利用できない。       接続数を完全に見積もり切る事は困難 -41 -
  • 42.
    How to operatesharding ■ mongs - mongod コネクションプールの問題 ● mongos - mongod間の接続数を制御する手段が無い --maxConnsオプションはclient - mongos間のコネクションを扱っている ● mongosは定期的に不必要なコネクションプールを回収するが   30分以上使われなかったコネクション限定(hardcode)   瞬間負荷で張ったコネクションを長時間保持し続けてしまう 結局、本来必要ない接続を張ってしまう。 最大接続数20000という厳しい制限の元 この手の無駄はシステムのスケーラビリティを大きく下げる!! -42 -
  • 43.
    How to operatesharding ■ 接続数不足の対策 ● 不必要なクライアントを排除 安易にapache MAX_CLIENT=1000とかやらない! (結局普通のアプリはそんなに食えない)   通常時mongodの接続数が7000位が安全ギリギリ ● リトライ処理をやめる  システム保全の方が大事!そもそもリトライが成功する確率も低い。 ● slow query抑止のチューニング – table scan禁止 (--notablescan) – M/R 禁止 – ピーク時の書き込みを抑止(各種ファイルpreallocateが一番怖い) – shard増やす – etc... -43 -
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
    パッチ解説 ■ 不要コネクションを回収するタイミングを修正 ● 1800秒固定→オプションで指定可能 ● コネクションプール数の最大値を指定可能  必要なコネクションは張るが、指定値以上はプールしなくなる 最小値も指定出来た方が良いんだろうか?  とりあえず今のところ必要なさそう -48 -
  • 49.
    補足 ■パッチ https://github.com/crumbjp/mongo/commit/b4a424fe0 2d7b5410db364b2d71f11ce09fd3fc3 ■C10Kと スター型接続 http://www.slideshare.net/crumbjp/cockatoo(39p~) -49 -