Successfully reported this slideshow.
Your SlideShare is downloading. ×

Mongo sharding

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 60 Ad

More Related Content

More from Takahiro Inoue (20)

Advertisement

Mongo sharding

  1. 1. Sharding詳解<br />〜機能と仕組みの理解〜<br />doroykujin<br />
  2. 2. 自己紹介<br />doryokujin (25歳)<br />諭吉大学院数学科卒業できました<br />MongoDB JP 主催者<br />芸者東京エンターテインメント(GTE) データマイニングエンジニア<br />
  3. 3. 発表の目的<br />Mongo Shardingへの理解を深めてほしい<br />1. Mongo Shardingの特徴を知ってほしい<br />2. なかなか知り得ない機能詳細や意外な振る舞いがあることを知って欲しい<br />3. 使用上における問題点をきちんと把握しておいて欲しい<br />4. Mongo Shardingを試すきっかけになって欲しい<br />
  4. 4. 発表の内容<br />「Scaling MongoDB」の内容を7割方網羅<br />Mongo Shardingに焦点を絞って書かれた本<br />この本を読むことShardingへの理解がかなり深まる<br />併せてドキュメントの内容も盛り込んでいる<br />
  5. 5. アジェンダ<br />1. Mongo Shardingの3つのコンセプトを紹介<br />-> 概要の理解<br />2. Mongo Shardingの機能・振る舞いを4つのキーワードから紹介<br />-> 個々の機能の深い理解<br />
  6. 6. 最終的に言いたいこと<br />Shard Key の設定は非常に重要、慎重に<br />Shard の偏りを極力減らす事は重要<br />Shard Key によって偏り具合が大きく異なる<br />Sharding環境におけるクエリは振る舞いが怪しい部分があるので要注意(重複問題)<br />正しい count() が行われない<br />unique のはずのキーが重複して存在<br />
  7. 7. Mongo Sharding 3つのコンセプト<br />
  8. 8. Shardingとは?<br />定義:DB上のデータを複数のサーバーに分割して運用すること<br />メリット:個々のサーバーの<br />負荷の軽減<br />使用領域を軽減<br />パフォーマンス向上<br />扱えるデータサイズの向上<br />
  9. 9. Mongo Sharding Concept<br />MongoDBの掲げる3つのコンセプト<br />「Make the cluster “invisible”」<br />「Make the cluster always available for reads and writes」<br />「Let the cluster grow easily」<br />
  10. 10. Mongo Sharding Concept 1<br />Make the cluster “invisible”<br />全ての接続をmongosサーバーが仲介することによってクライアントはクラスタ全体の情報を意識することなく扱える<br />クライアントはShardingしていない状況と同じようにクエリを発行し、結果を得ることができるより高速に)<br />
  11. 11. Mongo Sharding Concept 2<br />Make the cluster always available for reads and writes<br />Auto-Failover でMongoDBのダウン時間を減らせ、常にデータにアクセスできる状態<br />データの自動分割や Auto-balancing によって常に安定した状態を保ち続けられる<br />
  12. 12. Mongo Sharding Concept 3<br />Let the cluster grow easily<br />Shardの追加・撤退が容易にできる<br />新しいShardの追加に対して自動的にデータの移行・均一化が図れる(Migration, Auto-Balancing)<br />
  13. 13. Mongo Shardingを理解するための4つのキーワード<br />
  14. 14. Mongo Shardingを理解するための4つのキーワード<br />Shard Key: <br />コレクションを分割する際のキー<br />Balancing, Migration: <br />Shard 間のデータの均等な分散を維持する仕組み<br />mongos, config, mongod: <br />Shardingを構成する3種類のサーバー<br />Shardingクエリ:<br />Sharding環境におけるクエリの振舞と問題点<br />
  15. 15. 1. Shard Key<br />
  16. 16. Shard Key:概略<br />データの分割は何らかのキーに従って行う<br />それを Shard Key と呼ぶ<br />Shard Key は Collection 内のどれか1つのキーから選択<br />各 Shard 内のデータは Chunk と呼ばれるデータ単位で分割・移動・削除などが行われる<br />Shard 間の偏りとは、Chunkの数が一部に偏る事<br />Shard が偏るのはよろしくない<br />
  17. 17. Chunk に関して<br />Chunkは、特定のコレクションの連続した範囲のデータ集合<br />データがどの Chunk に属するかは、Shard Key の値によって決まる<br />Chunk はデータサイズが200MB(デフォルト)を超えると自動で等分割が行われる<br />分割されるごとにShard 内の Chunk 数が増加<br />Shard Key は型の混在が可能。MongoDBは全ての型を通して順序が決まっている<br />
  18. 18. データが挿入されていく度に<br />Chunk が分割されていくとして<br />その様子をみてみる<br />http://www.10gen.com/static/presentations/scaling-jp.pdf<br />
  19. 19.
  20. 20.
  21. 21. これがChunkと呼ばれるデータの<br />集合単位。連続した範囲のデータ<br />集合。新しいデータは Shard Key<br />の値がChunkの範囲内にある所に<br />入る。200MBを超える度に分割が<br />起こる。(デフォルト)<br />
  22. 22. Chunk に関する注意点<br />各々の Chunk の持つ範囲は絶対に重複しない。1つのデータに対してただ1つの Chunk が対応。範囲は [ a, b ) で、左を含み右を含まない<br />Shard Key は変更できない。やり直したい場合は対象の Collection を削除してから<br />ShardKeyの値を持たないドキュメントは保存できない。ただし null は可能<br />
  23. 23. 2. Balancing, Migration<br />
  24. 24. Auto-balancing, Migration<br />Auto-balancing<br />ある特定の Shard に Chunkが集中した場合、自動で他の Shard への移行(=Migration)<br />トリガーは Shard 内における最大 Chunk 数と最小 Chunk 数の差が10以上になったとき<br />デフォルトで最大 200MB/Chunk なのでデータサイズの差が2GB以上になったとき<br />最大 Shard からランダムに5つの Chunk が選ばれ、最小 Shard への Migration が行われる<br />
  25. 25. Migrationにおける問題<br />※ Migrationには多大なコストがかかる<br />configサーバーへの負担<br />ネットワーク帯域の圧迫<br />メモリ領域の圧迫(Chunkをメモリにコピーするので)<br />パフォーマンスの低下<br />正しいクエリの結果を返さない(後述)<br />低速。完了に非常に時間がかかる<br />
  26. 26. 1. (再)Shard Key<br />
  27. 27. Shard Key 選択の重要性<br />Migration は極力起こらないように<br />つまり Shard 間に Chunk の偏りがない<br />Shard 間に偏り少なくなる Shard Key を選択<br />一度選択したShardKeyは変更できないので慎重に<br />
  28. 28. Shard Key: 悪い例①<br />Low-Cardinality Shard Key<br />「密度」の低い Shard Key<br />主にカテゴリデータなどの”離散”データ<br />例:大陸名<br />(-∞, America], (America, Asia], (Asia, Australia],…<br />理由:<br />Chunk の分割ができない<br />N 個のカテゴリ数なら N 個の Chunk しかできない<br />N 個以上の Shard サーバーは意味がない<br />
  29. 29. Shard Key: 悪い例②<br />Ascending Shard Key<br />Shard Key の値が増えていくのみのデータ<br />Time, ObjectId, Incremental Unique Id<br />例:<br />[-∞, +∞ ) <br />-> [ -∞, 12945 ), [12945, +∞ ) <br />-> [ -∞, 12945 ), [12945, 12948 ), [ 12948, +∞ ) <br />理由:<br />( $CurrentMax, +∞ ] の Chunk だけがひたすら分割<br />明らかに Shard 間で不均一がおこる<br />
  30. 30. ShardKey: 悪い例③<br />Random Shard Key<br />Shard Key の値が Random に決まる場合<br />例:MD5 hash<br />理由:<br />Chunk は均等分散するが非常に大きな範囲を持った Chunk が存在する可能性<br />その Chunk の Migration はRAMを圧迫する<br />Random Shard Key に対する Index も非効率<br />
  31. 31. Shard Key: 良い例<br />Coarsely Ascending Key + Search Key<br />緩く増加していくキー + 検索でよく使われるキー<br />例:アクセス解析 { month:1, user: 1}<br />( (“2011-04”,”doryokujin”), (“2011-04”, “gohan”) ), <br />( (“2011-04”,”gohan”), (“2011-04”, “taberu”) ),… <br />理由:<br />左のキーは一定期間固定で、右のキーはほぼ均等に分布してくれる<br />時間がたつと左のキーの値が増え、元の(解析対象としない、古い)値の Chunk は分割されなくなり、 Migration が起こりにくくなる<br />
  32. 32. 良い Shard Key のイメージ<br />長い時間が経って Shard の偏りが起き始める頃に、片方のキーが増加して Shard をリフレッシュしてくれる<br />shard2<br />shard3<br />shard4<br />shard5<br />shard6<br />shard1<br />name<br />2011/04<br />2011/05<br />month<br />
  33. 33. 3. mongos, config, mongod<br />
  34. 34. Shardingを構成するサーバー群<br />Cluster<br />Shard Servers (Data)<br />config Servers<br />(Shard Configration)<br />shard3<br />shard1<br />shard2<br />[ a, f )<br />[ k, n)<br />[ o, t )<br />Chunk<br />[ f, k )<br />[ n, o )<br />[ t, } )<br />mongos Servers (Routers)<br />
  35. 35. サーバー間の関係<br />http://www.mongodb.org/display/DOCS/Sharding+Introduction<br />
  36. 36. mongosサーバー<br />該当データのある Shard にのみ<br />クエリの送出・データの取得を行う<br />cinfigサーバーから Shard <br />に関する情報を取得する<br />クライアントのアクセスは<br />必ずmongosに対して行う<br />
  37. 37. mongosサーバーの役割<br />クライアントは全ての読み書きをmongosに対して行う<br />mongosはどの Chunk がどの Shard にあるかを把握している<br />ただし永続的な情報を保存するわけではない。configサーバーがそれを持つ<br />[ ダウン ]:Shard にアクセス不能になるので、完全に機能停止することに<br />
  38. 38. configサーバー<br />“特殊な” mongodサーバー<br />change chunkSize<br />disable Balancing<br />shard に関する(永続的な)<br />メタ情報を保持<br />
  39. 39. configサーバーの役割<br />shards, mongos process, sysadminに関するメタ情報を保持<br />複数起動可能。ただしテスト環境は1つ、本番環境でも3つで十分(3で最適化)<br />独自のプロトコルで同期を行う。手動でReplicationの設定をしてはいけない<br />[ ダウン ]:Shardの設定変更が不可能になる。読み書きは継続<br />
  40. 40. config Collection<br />> use config<br />switched to db config<br />> show collections<br />changelog# 過去の Migration に関する詳細なログ<br />chunks # 全てのChunk の情報<br />collections # Shardingしている全ての Collection の情報<br />databases # 全DBに関してShardingの有無などの情報<br />lockpings<br />locks<br />mongos# mongosに関する情報<br />settings # chunkSizeの設定情報、balancer機能の切替<br />shards # Shard に関する情報<br />system.indexes<br />version<br />> db.settings.update({"_id" : "balancer"}, {"$set" : {"stopped" : true }}, true)<br />
  41. 41. 4. Shardingクエリ<br />
  42. 42. mongosへのクエリタイプ<br />Targeted<br />Shard Key が指定されることによって、必要なデータがあるshardにのみアクセス。最小限。<br />Global<br />Shard Key が指定されず、mongosプロセスはシステム内の(ほぼ)すべての Shard にアクセス<br />
  43. 43. Shard Key を用いての find()<br />targeted <br />db.adminCommand({"shardCollection" : ”mongo.users", key : {”name" : 1}}<br />shard3<br />shard1<br />[ a, f )<br />[ o, t )<br />{“name”: “inoue” }<br />[ f, k )<br />[ t, } )<br />mongos<br />{“name”: “tanaka” }<br />指定された Shard Key (“name” key)を含む Chunkの<br />あるShard にのみクエリの発行・データの取得を行う<br />shard2<br />db.shardCollection.find({“shardKey”: “xxx”})<br />[ k, n)<br />[ n, o )<br />
  44. 44. Non Shard Key を用いての find()<br />global<br />shard1<br />db.adminCommand({"shardCollection" : ”mongo.users", key : {”name" : 1}}<br />[ a, f )<br />[ f, k )<br />mongos<br />{“pref”: “Tokyo” }<br />mongosは Shard Key 以外 (“pref” key)の情報を<br />知り得ないので全ての Shard にアクセスする。<br />ただしインデックスを利用できる。<br />shard3<br />shard2<br />[ o, t )<br />db.shardCollection.find({“nonShardKey”: “xxx”})<br />[ k, n)<br />[ t, } )<br />[ n, o )<br />
  45. 45. Shard Key を用いての<br />single-update()<br />targeted <br />db.adminCommand({"shardCollection" : ”mongo.users", key : {”name" : 1}}<br />shard3<br />shard1<br />[ a, f )<br />[ o, t )<br />update<br />{“name”: “inoue” }<br />[ f, k )<br />[ t, } )<br />mongos<br />{“name”: “tanaka” }<br />指定されたshard key(“name” key)を含むchunkのある<br />shardにのみクエリの送出・データの取得を行う<br />shard2<br />db.shardCollection.update({“shardKey”: “x”},{$set{key:value}})<br />[ k, n)<br />[ n, o )<br />update<br />
  46. 46. Non Shard Key を用いての<br />sort()<br />global <br />shard1内でsort<br />shard1<br />[ a, f )<br />shard1,2,3の結果<br />を merge sort<br />[ f, k )<br />shard2内でsort<br />{“pref”: “Tokyo” }<br />mongos<br />sort() が呼ばれた場合は、各 Shard における<br />検索結果のドキュメント集合に対してsortを行い、<br />さらにmongosが全Shard で merge sort<br />shard3内でsort<br />shard3<br />shard2<br />[ o, t )<br />db.shardCollection.find().sort({“nonShardKey”: 1})<br />[ k, n)<br />[ t, } )<br />[ n, o )<br />
  47. 47. Non Shard Key を用いての<br />count()<br />global <br />shard1内でcount<br />shard1<br />[ a, f )<br />shard1,2,3の<br />結果で count<br />[ f, k )<br />shard2内でcount<br />{“pref”: “Tokyo” }<br />mongos<br />count() が呼ばれた場合は、各 Shard における<br />検索結果のドキュメント集合に対して count を<br />行い、さらにmongosが全 Shard の結果で total<br />shard3内でcount<br />shard3<br />shard2<br />[ o, t )<br />db.shardCollection.count ({“nonShardKey”: 1})<br />[ k, n)<br />[ t, } )<br />[ n, o )<br />
  48. 48. Non Shard Key を用いての<br />mapreduce()<br />global <br />mapreduce<br />shard1<br />[ a, f )<br />shard1,2,3の結果<br />で ”re”-reduce<br />[ f, k )<br />mapreduce<br />mongos<br />emit( “pref”: 1 )<br />mapreduce() が呼ばれた場合は、各 Shard における<br />検索結果のドキュメント集合に対してmapreduceを<br />行い、さらにmongosが全 Shard の結果で reduce<br />shard3<br />mapreduce<br />shard2<br />[ o, t )<br />[ k, n)<br />db.runCommand ({mapreduce: shardedCollection,…})<br />[ t, } )<br />[ n, o )<br />
  49. 49. { x : 1 } Shard Key と仮定。<br />targetedでは Shard へのアクセスは最小限<br />globalは、システム内の(ほぼ)すべての Shard にアクセス<br />
  50. 50. Shard Key を使用しない場合に問題のあるクエリ<br />Sharding環境で Shard Key を使用しないクエリは、必ずしも正しく実行されるとは限らない<br />「Chunk Migration 中の count()」<br />「同時書き込み発生時の single-update()」<br />「同時書き込み発生時の unique index」<br />「tmp_collectionが削除されないmapreduce()」<br />
  51. 51. Chunk Migration 中の count()<br />Chunk Migration 中は処理が完了するまで、移動元・移動先に同じ Chunk が存在する<br />完全にコピーが完了し、configサーバーが更新されて完了となる<br />その間に count() コマンドが実行された場合、この Chunk のデータは重複してカウントしてしまう可能性がある。<br />結果:真値より大きくなる<br />
  52. 52. Chunk Migration 中の count()<br />shard2<br />shard2<br />shard1<br />shard2<br />shard1<br />shard1<br />X<br />X<br />count X<br />mongos<br />count X<br />重複カウント<br />X<br />移行中…<br />X<br />
  53. 53. 同時書き込み発生時のunique Index<br />MongoDBは書き込みに対してロックを行わない(複数の書き込みに対してアトミックでない)<br />unique な Index として設定したキー(Shard Keyでは無い) が異なる Shard 間で存在する可能性がある<br />“_id” でさえも重複する可能性がある<br />結果:Shard Key 以外のユニーク性が保証されない<br />
  54. 54. 同時書き込み発生時のunique Index<br />{"_id" : ObjectId("4d2a2f7c56d1bb09196fe7d0"),<br />”name" : ”doryokujin",<br />"email" : “doryokujin@example.com” }<br />shard 1<br />shard2<br />shard3<br />X<br />update<br />mongos<br />{"_id" : ObjectId("4d2a2e9f74de15b8306fe7d0"),<br />”name" : ”doryokujin",<br />"email" : ”inoue@example.com"<br />update<br />Y<br />mongos<br />shardKey={“email”:1} とは別に<br />unique Index={“name”:1} である Key で<br />の update が同時に行われた場合、unique<br />キーなのに重複する可能性がある<br />Z<br />
  55. 55. 同時書き込み発生時のsingle-update<br />同様にnonShardなキーで同時にsingle- updateを行う際にも問題が<br />アトミックな操作が保証されないのでエラーとなる<br />Non Shard Key に対しては必ずmulti-updateを行う<br />結果:single-update に対してエラー<br />
  56. 56. 「tmp_collectionが削除されないmapreduce()」<br />Shard の中から1つの「代表」が選ばれ、各Shard でmapreduceが実行された結果に対してもう一度 reduce を行う<br />計算はオプションを指定しない限り、tmp_collectionが作られる<br />Sharding環境では計算終了後に一時的に作成したtmp_collectionが自動で削除されない<br />結果:不要な Collection が増えていく<br />v.1.8で改善。手動で削除して対処<br />
  57. 57. Shardingクエリは要注意<br />このようにSharding環境におけるクエリには十分な注意が必要<br />同時書き込みに対してアトミックでないことが影響<br />Chunk Migration 中の Chunkは重複して数えられる可能性がある<br />
  58. 58. Mongo Shardingを理解するための4つのキーワード<br />Shard Key: <br />コレクションを分割する際のキー<br />Balancing, Migration: <br />Shard 間のデータの均等な分散を維持する仕組み<br />mongos, config, mongod: <br />Shardingを構成する3種類のサーバー<br />Shardingクエリ:<br />Sharding環境におけるクエリの振舞と問題点<br />
  59. 59. 最終的に言いたいこと<br />Shard Key の設定は非常に重要、慎重に<br />Shard の偏りを極力減らす事は重要<br />Shard Key によって偏り具合が大きく異なる<br />Sharding環境におけるクエリは振る舞いが怪しい部分があるので要注意<br />正しいcount()が行われない<br />uniqueのはずのキーが重複して存在<br />
  60. 60. ありがとうございました…<br />

×