Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Db tech showcase2015 how to replicate between clusters

1,375 views

Published on

話す前提だから、コレだけ見ても伝わらないだろうな・・・

Published in: Technology

Db tech showcase2015 how to replicate between clusters

  1. 1. MongoDB クラスター間レプリケーション MongoDB JP代表
 窪田 博昭 @crumbjp
  2. 2. Who are you ? MongoDBJP 代表 MongoDB歴4年 emin.co.jp 2014年10月∼
  3. 3. ブログ活動
  4. 4. 仕事の話
  5. 5. Emotion Intelligence 日本有数のMongoDBユーザ企業 ECのCV率を上げるサービスZenclerkを運営 Web閲覧中のユーザの行動を逐次解析し感情 を読み取る 月間10億PV程度を扱っている
  6. 6. Zenclerk
  7. 7. Zenclerk
  8. 8. Zenclerk 毎月 PB 単位のデータを扱う 10TB単位のデータをMongoDBに保存 MainDB は 5 shard 構成(そんなにお高くないサーバ)
  9. 9. 困った
  10. 10. 困った それなりに複雑なシステムはステージング環境 が欲しいが、本番DBに向けてしまうと色々困る 機械学習で稼ぐビジネスなのに本番DBにカジュ アルにクエリーするとシステムが高負荷でダウ ンして危険 何らかの調査でtypoしたフィールドのクエリー 投げられて死ぬ
  11. 11. Zenclerk
  12. 12. それってStagingDB
  13. 13. DummyデータでStaging ! 大きなデータがあるから発生する問題が多い 本番と同じデータが無いと機械学習が巧く行 く筈が無い (作った本人含めて)誰も使わない 全然意味なかった・・・
  14. 14. でもMongoDBって・・・
  15. 15. MongoDBのレプリケーション ! ReplicaSet以外のデータ同期の仕組みは無い ReadOnlyでは不便極まりない 1日一回Secondaryを切り離して使う? フレッシュなデータが使いたいので却下された Sharding環境でそんな面倒な運用無理!
  16. 16. でも困ってるんだよ・・・
  17. 17. つい出来心で・・・ ! ある日ReplicaSetのoplogを生読みすればクエ リーベースのレプリケーションが組める事に 気付く 深い事考えずに『出来るわ!やろっか?』 『お願い!』という会話をしてしまう。 スーパー後悔・・・
  18. 18. 仕方が無い・・・ 面倒すぎて、1ヶ月放置した・・・ 『まだ∼?』『ゴメン!』を繰り返す。。 いい加減信用がヤバくなったので本腰入れた 即日nodeで書いたが速度がイマイチで mongo shellで書直し、色々問題直して賞味 1週間くらいかかった
  19. 19. 出来た!!
  20. 20. https://github.com/zenclerk/monmo_repl 書き込み側のレイテンシーをクリアすれば 3TB/month までは間違く動く
 そこから先は頑張り次第
  21. 21. 技術的な説明
  22. 22. ReplicaSet Primary Secondary
  23. 23. 作戦 monmo_repl
  24. 24. 性能1 MongoDBのレプリケーション周りはチューニ ングされており、とにかくoplogに追い着くの が大変 Bulkオペレーション必須 ns(collection)単位に分解して処理する
  25. 25. 性能2 シビアなので選択肢が少ない c++ driver → 流石にちょっと・・ node native driver → 少し遅かった mongo shell → 低機能だが高速
  26. 26. 性能3 mongo shell mongod, mongos の mongo client を直接使う (本体だから)node native driver より チューニングが進んでいるっぽい Tailable cursorの不随意closeが検知できな い・・・つらい・・・
  27. 27. oplogの注意点1 Tailable cursorは終端まで移動させるのに分単位 の時間が必要 レプリプログラムを再起動しても直ちに同期 を再開できない cursorは不随意に閉じる事がある oplogに負けてcursorの先端まで追いつめられる と上記のループに嵌って抜け出せない
  28. 28. oplogの注意点2 oplogにはクエリーがそのまま保存されている訳 ではない 更新、削除系のクエリーは_id指定に展開される 例えばdb.remove({}) はドキュメント数のoplog にバラされ処理が膨れあがる レプリ先に独自に作ったドキュメントは範囲 更新などの影響を受けない
  29. 29. oplogの注意点3 レプリ元と先の用途の違いを考慮 別々に運用したい場合関連オペレーション を塞き止める DB名、コレクション名を変えたい場合が ある データを選別して塞き止めたい(負荷が辛いが)
  30. 30. Shardingでもイケる Mongos Shard3Shard1 Shard2 monmo_repl monmo_repl monmo_repl Staging replica
  31. 31. MMS backup agent
  32. 32. Shardingでの工夫 Shardingのmigrationに伴うinsert/deleteは識別 して弾く
  33. 33. 嬉しい誤算
  34. 34. Shardingでの嵌り所 Shardingのauto migrationはデータ量(chunk 数)の均一化をしてくれる 書き込み量の均一化は考慮してくれない 書き込み量が均一化されていないと特定 Shardのデータが膨れるのでmigrationを大量に 誘発してしまう
  35. 35. printShardingStatus() 一見巧く分散しているように見えるが 、ほぼ全て の書き込みがshard1に集中している事がある shardkey の境界を含むchunkに書き込みが集中す るのでそれを保持しているshardに負荷が集中する
  36. 36. Sharidngとchunk chunk no min max shard 1 $minKey key: ’b’, _id: 100 shard1 2 key: ’b’, _id: 101 key: ’b’, _id: 500 shard2 3 key: ’b’, _id: 501 key: ’b’, _id: 900 shard2 4 key: ’b’, _id: 901 $maxKey shard1 chunk2, 3 には新規insert は絶対に入らない shard1 に殆どの書き込みが集中する
  37. 37. 各shardの負荷を可視化 INFO, TS: Timestamp(1433592288, 132), DF: 1, C: 5000, {"loglv":100,"dry":false,"repllog":false} DUMP, BULK: xxxxxxxxx.yyyyyyyy01, {"i":0,"u":3124,"d":0,"m":0,"b":3124} DUMP, BULK: xxxxxxxxx.yyyyyyyy02, {"i":620,"u":1440,"d":0,"m":0,"b":2060} DUMP, BULK: xxxxxxxxx.yyyyyyyy03, {"i":11,"u":46,"d":0,"m":0,"b":57} DUMP, BULK: xxxxxxxxx.yyyyyyyy04, {"i":66,"u":0,"d":0,"m":0,"b":66} DUMP, BULK: xxxxxxxxx.yyyyyyyy05, {"i":6,"u":0,"d":0,"m":0,"b":6} DUMP, BULK: xxxxxxxxx.yyyyyyyy06, {"i":10,"u":0,"d":0,"m":0,"b":10} DUMP, BULK: xxxxxxxxx.yyyyyyyy07, {"i":6,"u":0,"d":0,"m":0,"b":6} DUMP, BULK: xxxxxxxxx.yyyyyyyy08, {"i":44,"u":0,"d":0,"m":0,"b":44} DUMP, BULK: xxxxxxxxx.yyyyyyyy09, {"i":0,"u":210,"d":0,"m":0,"b":210} DUMP, BULK: xxxxxxxxx.yyyyyyyy10, {"i":102,"u":0,"d":0,"m":0,"b":102} DUMP, BULK: xxxxxxxxx.yyyyyyyy11, {"i":200,"u":0,"d":0,"m":0,"b":200} DUMP, BULK: xxxxxxxxx.yyyyyyyy12, {"i":22,"u":0,"d":0,"m":0,"b":22} INFO, TS: Timestamp(1433592309, 59), DF: 1, C: 4927, {"loglv":100,"dry":false,"repllog":false} DUMP, BULK: xxxxxxxxx.yyyyyyyy01, {"i":33,"u":877,"d":0,"m":0,"b":910} DUMP, BULK: xxxxxxxxx.yyyyyyyy02, {"i":705,"u":1631,"d":0,"m":0,"b":2336} DUMP, BULK: xxxxxxxxx.yyyyyyyy03, {"i":81,"u":1488,"d":0,"m":0,"b":1569} DUMP, BULK: xxxxxxxxx.yyyyyyyy07, {"i":384,"u":0,"d":0,"m":0,"b":384} Shard1のレプリケーションログ Shard2のレプリケーションログ
  38. 38. 手で調整 問題のあるコレクションが解れば、shardkey の境界を含んだchunkを移動すれば良い monmo_replが仕掛けてあると調整の結果が リアルタイムで見える! chunk移動もスクリプト化しておくと楽(ま だ公開できない出来・・・)
  39. 39. もうMongoDB怖くないよね

×