Advertisement

More Related Content

Slideshows for you(20)

Advertisement

Mongo dbを知ろう

  1. を知ろう 概要から動作原理まで © CROOZ,Inc 1
  2. アジェンダ • mongoDBとは • クラスタ構成概要 • 内部的動作原理 • その他の仕様と機能 • MySQLとのスピード比較 © CROOZ,Inc 2
  3. 特徴から説く mongoDBとは © CROOZ,Inc 3
  4. mongoDB オンメモリで動作する スキーマフリーな ドキュメンド指向 NOSQLデータベース。 © CROOZ,Inc 4
  5. mongoDBの背景 • 2009年よりMongoDB社(元10gen)が提供。 • 累計調達資金2億3100万ドル。 • mongoDBのダウンロード数は500万回に達する。 • mongoDB技術者の求人数はredisやCassandraを抜いて トップを君臨。 • キーワードの検索数はHTML5に次ぐ2番目に多い。 ※一部情報はTechCrunchから引用 © CROOZ,Inc 5
  6. MongoDBの特徴 • ドキュメンド指向 – レコードではなく、JSONオブジェクトが格納される。 • スキーマフリー – 動的なスキーマ、リレーションの概念なし。 • Memory-Mapped File – メモリ上で動作する前提の設計で高いパフォーマンスを叩き出す。 • レプリケーション、シャーディング構成 – クラスタ構成により、自動的なフェイルオーバー、シャーディングを 実現。 © CROOZ,Inc 6
  7. ドキュメンド指向① KVSではなくDB! テーブルレベルまで、基本的な構造はRDBを踏襲。 RDB mongoDB Database (データベース) Database (データベース) Table (テーブル) Collection (コレクション) © CROOZ,Inc 7
  8. ドキュメンド指向② Profile collection: { name: “Alice”, age: 20, hobby: { “outdoor”: [ “motorcycle”, … ], “indoor”: [ “reading”, ], } } レコードの代わりに、JSONライクなオブジェクト が格納される。 オブジェクトの構造は理解され、検索や参照に利 用できる。 この例でアウトドアの趣味にアクセスするときは、 hobby.outdoor でアクセスできる。 こうしたサブオブジェクトやデータに対しイン デックスの作成など、DBの機能がフルで利用でき る。 NOTE: 内部的にはJSONがBSONというJSONのバイナリ版が格納され、 パフォーマンスの向上と容量削減に貢献している。 © CROOZ,Inc 8
  9. スキーマフリー① • 動的なスキーマデザイン – – – – レコードのようにテーブルごとにカラムが決まることはない。 同じコレクションにあるドキュメンドの構造が違ってでも可。 更新ごとにドキュメンドの構造を変更できる。 create系APIが存在しない。 • リレーションの概念なし – 集約出来る情報は関連テーブルに分散するのではなく、同じドキュメ ンドのサブドキュメンドとして集約する。 – どうしても分割管理したい場合(例:マスター)はDBRefというドキュメ ンド間のハイパーリンクを利用する。 © CROOZ,Inc 9
  10. スキーマフリー② RDBでのタグシステムの実装例 books book_id book_title • • book_tag_m ap tag_id book_id book_tags tag_id tag_text bookとtagに関連する操作は3つのテーブルを舐める必要がある。 ランダムアクセスは最低でも3回発生する。 © CROOZ,Inc 10
  11. スキーマフリー③ MongoDBでのタグシステムの実装例 Books collection: { _id: 1, title: “MongoDB”, tags: [“10gen”, “database”, “open-source”], … } • • • • tagsはbookのドキュメンドの一要素として格納。 tags配列に対してインデックスを作成し、検索に利用できる。 book自身のtagを参照する場合検索は必要ない。 同一ドキュメンドのためディスク上では連続なので、ランダムアクセスは1回。 © CROOZ,Inc 11
  12. Memory-Mapped File • Mongoではディスク上のリソースをMemory-Mapped Fileの仕組みを利用して、メモリ上にマッピングする。 • クライアントは通常メモリ上のデータを操作する。 • Memcacheなどのメモリキャッシュシステムの機能を原 理的に併せ持つ。 NOTE:詳細は後述 © CROOZ,Inc 12
  13. MongoDBとは② 上述の特徴を踏まえて、Mongoの運用思想とは。 Table Table ORマッピン グ オブジェクト Memcach e Table RDBMSではデータの集約、整形を経て、プログラムが扱いやすい形にし上で、 キャッシュシステムに格納しクライアントに提供する。 Mongoの設計思想でははじめからプログラムと親和性の高いオブジェクトをそのまま格 納する。メモリ上で動作するという特徴上、キャッシュシステムも基本的には必要ない。 © CROOZ,Inc 13
  14. レプリケーションとシャーディング クラスタ構成 © CROOZ,Inc 14
  15. クラスタ構成 • Mongoではレプリケーション、シャーディングの機能をそれぞれ提 供している。 • レプリケーション構成において、一般的な条件下では障害からの自 動フェイルオーバーが可能。 • シャーディング構成において、自動バランシング機能を備え、動的 にノードの追加や除去に対応。 • 両者を組み合わせることで負荷分散された冗長構成のクラスタが出 来上がる。 • クライアントからはクラスタ全体を一つの論理DBにみなすことが できる。 © CROOZ,Inc 15
  16. クラスタ構成図 Mongos Server Config Servers プライマリサーバー (Primary) セカンダリサーバー (Secondary) Data Servers 仲裁サーバー (Arbiter) メタデータ―サーバー (Config) ルーティングサーバー (Mongos) Replica Set © CROOZ,Inc Replica Set 16
  17. クラスタ構成要素 • primaryサーバ― – – アクセスを一手に受けて、セカンダリに同期していく。 フェイルオーバー時はセカンダリサーバーの中から投票によって選ばれる。 • secondaryサーバ― – – • arbiterサーバー – – • データを保持しないので同期もしないが、レプリカセット全体の同期状況を追跡していく。 障害時に保持している同期状況で投票するために存在する。 configサーバー – – • デフォルトではデータに対して参照を含めアクセス不可。 フェイルオーバー時は投票によって最も同期が進んでると判断すれば、プライマリになる。 シャーディング構成の構成情報やシャード状況を保持する。 構成が変更された時に、情報の提供と周知を担当する。 mongosサーバー – – – – © CROOZ,Inc クライアントにとっての窓口で、シャーディング構成のルーターのようなサーバー。 接続時にconfigサーバーにシャーディング構成を問い合わせてキャッシュし、 この情報を手掛かりにデータをルーティングしていく。 Mongosサーバーはバックエンドを持たないただのプロセス。 17
  18. レプリケーションと自動フェイルオーバー 同期 同期 primary • • • secondary 一つのレプリケーション構成はレプリカセットと呼ぶ。 レプリカセットは一つのprimaryと複数のsecondaryで構成される。 クライアントが操作できるのはprimaryのみで、primaryからoplogというオペレーションログで secondaryに同期していく。 同期 障害 primary • • • secondary primary secondary primaryが障害の場合、secondaryの中から投票で新しいprimaryが選ばれる。 障害発生したprimaryが復帰後はsecondaryとして新primaryから同期を受ける。 oplog内にスタックされたオペレーションで最新まで同期できない場合、自動フェイルオーバー は失敗となって、手動フォローが必要になる。 © CROOZ,Inc 18
  19. Primary選挙と過半数票 レプリカセットのprimaryが障害した場合、レプリカセット内の残りの構成要素がそれぞれ同期が進 んでいると判断したsecondaryに投票する。 障害要素を含む全構成要素の過半数票を獲得したsecondaryが晴れて新しいprimaryになる。 同期 primary secondary 上記primary、secondary各1の構成では、primary障害後残りのsecondaryが自分自身の1票しかもら えず、1票より多い票数(過半数票)を獲得できず、primary選抜が失敗し自動フェイルオーバーも失敗 となる。 複数のsecondaryを用意し対処しても、障害サーバーの数が合計数の半分になった時点で、同様に残 りのサーバーが過半数票を獲得できない。 同期 primary 監視 secondary arbiter この現象を解決するのがarbiterサーバー。 レプリカセット内の同期状況を監視し、障害時は投票するだけの人。 原理的に負荷やトラフィックが小さい。 © CROOZ,Inc 19
  20. 優先読み込み(ReadPreference) レプリカセットに対して参照リクエスト投げるとき、参照先をある程 度指定することができる。 • プライマリ – すべての読み込みはプライマリに対して行う。(default) • プライマリ優先 – プライマリが接続不可などの状況でのみセカンダリを選択する。 • セカンダリ – 全セカンダリ中ping返答が15ms秒以内のメンバーからランダムに選択する。 • セカンダリ優先 – 「セカンダリ」で使えるメンバーがなかった場合にのみプライマリを選択する。 • 最も近い – Ping返答が一番近いメンバーを選択。メンバーの種類は気にしない。 • タグセット絞込み – 上記中「プライマリ」以外、タグセットで候補の選択範囲を絞る事ができる。 © CROOZ,Inc 20
  21. レプリケーションまとめ • Primary, Secondary, Arbiterサーバーで構成する。 • データサーバーの数に応じてArbiterを用意し無駄をなす。 • 障害時は自動的にシステムの可動性を維持する。 • システム動作状態での復旧が可能。 • レプリカセットに対する読み込み先は細かく制御できる。 © CROOZ,Inc 21
  22. シャーディングの概要 • シャードは全自動で行われる。シャードアルゴリズムの 変更やカスタマイズは不可。 • システム動作状態でのシャード構成の変更が可能。 • 基本的にアプリケーションレベルでシャードを意識する 必要がない。 © CROOZ,Inc 22
  23. シャーディングの仕組み mongos {key: 150} Primary shard chunk0 chunk3 • • • • • 0 ~ 100 301 ~ Shard Shard chunk 1 101 ~ 200 chunk 2 201 ~ 301 データはドキュメンド単位ではなく、chunkというデータの箱単位でシャー ドされる。 インデックス作成と同じ要領でコレクション別のシャードキーを作成。こ のキーは変更不可。 シャードキーに対してはRangeBasedPaginationのアルゴリズムでchunkに 分割し、このchunkを各シャードに分散する。 振り分けられないデータは全部プライマリシャードサーバーでに行く。 プライマリシャードはコレクション別でシステムが勝手に割り振る。 © CROOZ,Inc 23
  24. Chunckの分割と移動 mongos Primary shard chunk 0 chunk 3 chunk 4 chunk 5 • • • • 0 ~ 100 301 ~ 400 Shard Shard chunk 1 101 ~ 200 chunk 2 201 ~ 301 401 ~ 500 501 ~ 大きくなりすぎたchunkは分割される。 Chunkが特定のサーバーに偏った場合は移動される。 Chunkの移動と分割はパフォーマンスに与えるインパクトは大きい。 Chunkの移動や分割中には一部リクエストは正しい情報を返せなくなる。 (count等) © CROOZ,Inc 24
  25. シャーディングの偏り対策 • ランダム性のあるデータをシャードキーにする。 • 複合キーをシャードキーにする。 • Chunkを事前に分割しておく。 • Chunkのサイズを小さく設定する。 • 定期的に手動でchunkを作成、分割してやる。 • Hashベースのシャードキーを利用する。 © CROOZ,Inc 25
  26. Hashベースシャードキー シャーディングのために作られた特殊なインデックス。 • 利点: – シャードのアルゴリズムにあわせているので、非常にうまい具 合に分散される。 – 自動で事前chunk分割してくれる。 • 欠点: – 複合キーは利用不可。ピンポイント検索では不利。 © CROOZ,Inc 26
  27. シャーディング構成要素の障害時の挙動 • configサーバー障害 – 一部障害の場合 • configサーバーのメタデータが読み取り専用になる。 • DBに対する通常操作、mongosの立ち上げができるが、シャーディング構成 の変更やChunkの移動や分割ができなくなる。 • データの大量インサードがあった場合、偏ったシャーディング結果になる か、インサード失敗になる。 – 全部障害の場合 • 一部障害の挙動に加え、mongosの追加や再起動ができなくなる。(精確に は立ち上げ後落ちる) • 一部シャーディング構成状態を確認するコマンドが利用できなくなる。 • Mongosサーバー障害 – 単一mongosの障害はシステム自体にインパクトを与えない。 – クライアントにとってはシングルポイントになるため、プロセスの自動再起動 や、接続先切り替えの仕組みで回避できる。 © CROOZ,Inc 27
  28. シャーディングのまとめ • 全自動なため、アプリケーションで面倒を見る必要がな い。 • シャード構成にのみ存在する問題や仕様がいろいろある ので、ある程度意識してリクエストを投げる必要がある。 • 適切なシャードキーの選択が肝、慣れるまでチューニン グで苦労する可能性大。 © CROOZ,Inc 28
  29. クラスタの物理構成例 とりあえず、クラスタ構成要素の特徴をまとめよう。 • Primary, Secondaryサーバー – 高負荷、高ディスクIO、高トラフィック。 – 実運用レベルではすべて物理サーバーが無難。 • Arbiterサーバー – 低負荷、低ディスクIO、低トラフィック。 – データサーバーと分けていれば相乗り可。 • Configサーバー – 低負荷、低ディスクIO、低トラフィック。 – config同士が分けていれば相乗り可だが。 • Mongosサーバー – 低負荷?、ディスクIOなし、高トラフィック。 – トラフィックが気にしなければどこでもいい。 © CROOZ,Inc 29
  30. クラスタ内でケチる構成 Arbiter1 Config1 Config2 Mongos • • • • • Shard1 Arbiter2 Mongos Shard1 Shard2 Shard2 Config3 メインのデータサーバーはそれぞれ物理サーバーを用意。 残り負荷の低いサーバーは一プロセスごとまとめて物理サーバーを用意。 Arbiterサーバーは複数プロセス相乗りでも可。 あまり勧めないが、Configをデータサーバーに相乗りさせても可。 基本的にArbiter, Config, Mongosが一プロセスずつ同時に止まっても、シス テムに直ちに影響を与えない。 © CROOZ,Inc 30
  31. クラスタ外でケチる構成 AppServer AppServer AppServer Mongos Mongos Mongos SomeServer Arbiter1 Config1 AppServer Mongos • • • Arbiter2 Shard1 Shard2 Shard2 SomeServer Config1 Shard1 Config2 mongosはAppサーバーに置いて、localhostから接続する。 その他の低負荷サーバーは一プロセスずつ適当なサーバーに相乗りさせる。 Appサーバーに余裕が有る場合、mongos以外の低負荷プロセスに相乗りさ せても可。 © CROOZ,Inc 31
  32. mmap()を利用した実装とジャーナリング 内部的な動作原理 © CROOZ,Inc 32
  33. 内部的動作原理 Mongoのコアはmmap()で実装している。 60秒ごとの更新 ディスク • • • • メモリ マッピング Mongoプロセス起動時にディスクにあるリソースを全部仮想メモリにマッ ピングする。 マッピング時点ではデータはメモリに乗らない。 一旦マッピングするとOSの機能でメモリとディスクが関連付けられて、メ モリへの更新は任意のタイミングでディスクにフラッシュできる。 Mongoではデフォルトで60秒ごとディスクにフラッシュする。 © CROOZ,Inc 33
  34. Memory-Mapped Fileから見るMongoの特性 • 利点: – 通常はメモリ上で動作するため、動作が早い。(特に書き込み) – よく利用するデータは自然と物理メモリに来るので、メモリ キャッシュシステムのような役割もこなす。 – 大量な書き込みでも相対的にディスクIOが小さい。 • 欠点: – 32bitシステムでは使いものにならない。 – 仮想メモリ扱いなので、ページアウトが発生する。(page fault) – Mongoがアクティブに動く環境では他のプロセスをガンガンス ワップアウトさせてしまう。 – 永続化は60秒ごとの更新なので、最悪60秒のデータが飛ぶ。 • 結論: – メモリをいっぱい積みましょう! © CROOZ,Inc 34
  35. ジャーナリングシステム概要 消える60秒間のデータのために! • 単一プロセスの対障害能力を向上する目的で作られたシ ステム。 • 先行書き込みログの仕組みでパフォーマンスを維持しな がら実現。 © CROOZ,Inc 35
  36. ジャーナリングシステムの動作原理① ディスク メモリ 60sごとの更新 DB Data Shared View Memory-Mapped File map 100msごとの書き込み Journaling File • • • Write OP Private View DBのデータはSharedViewというビューにマッピングされた後、 SharedViewをPrivateViewに第二のマッピングを行う。 リクエストに対しライトオペレーションはSharedViewではなくPrivateView に送られ、書き込み終了後SharedViewに反映する。 100msごとにPrivateViewに送られたライトオペレーションだけをディスク のジャーナリングファイルに書き込む。 © CROOZ,Inc 36
  37. ジャーナリングシステムの動作原理② ディスク メモリ データをフラッシュ DB Data Shared View Memory-Mapped File remap Journaling File • • • • Private View 障害復帰後、JournalingFileからSharedView宛にライトオペレーションを再 生し、メモリ上のデータを復旧させる。 SharedViewからディスクに最新データをフラッシュする。 SharedViewからPrivateViewに最新データをにリマップする。 これで復旧完了、リクエストを受け付ける。 © CROOZ,Inc 37
  38. クラスタ構成でのジャーナリング Mongoではレプリケーション構成でもジャーナリングの利 用を推奨している。理由は以下: • レプリケーション全体の障害に対応できる。 • より素早く確実なリカバリが出来る。 • 障害後はmongoプロセスを単純に再起動することで対応 できる。 © CROOZ,Inc 38
  39. ジャーナリングシステムのまとめ • 利点: – 障害耐性向上。最大60sのデータロスが100msにできる。 – レプリケーション構成での自動フェイルオーバー能力向上。 – 永続性保証書き込みの敷居が下がる。(詳細後述) • 欠点: – 同じビューがメモリ上2つ存在するため、メモリ消費量が倍! – 一回の更新で2回のメモリ操作が発生する。 – ジャーナリングファイル書き込み分のディスクIOが発生する。 • 結論: – 特別な理由がなければ利用した方がいい。 © CROOZ,Inc 39
  40. 特徴的な仕様とその他の機能を紹介 その他の仕様と機能 © CROOZ,Inc 40
  41. 特徴的な仕様①: Fire-and-Forgetの精神 • 書き込みリクエストに対し、mongoは実際のディスク書 き込みを確認しない。 • この仕様でメモリ動作の優位性を保ち高いパフォーマン スを維持する。 • ディスク書き込みを保証してほしい場合、多くのドライ バはfsyncパラメータをサポートする。 © CROOZ,Inc 41
  42. 特徴的な仕様②: fsync • Mongoではfsyncは管理コマンド。メモリをディスクに 直ちにフラッシュさせる。 • 各言語のドライバでは書き込み系APIのオプション。 – 指定すると該当オペレーションのディスク書き込みを保証する。 – ただし、ジャーナリングありとなしで挙動が違う。 – ジャーナリングなし: • メモリへの書き込み後、直ちにディスク書き込みが行われる – ジャーナリングあり: • メモリへの書き込み後、ジャーナリングファイル書き出しの最大 100ms間隔を待つ。 – ジャーナリングありではより低負荷で永続保証書き込みできる。 – でも、用法用量を守って正しく使うべき。 © CROOZ,Inc 42
  43. 特徴的な仕様②: 書き込み確認(WriteConcern) 送り出したリクエストが心配で心配で仕方ない方に • Fire-And-Forgetの精神をより細かくコントロールするための機能が 書き込み確認。 • リクエストに対しどの段階まで成功とみなすかを表すリクエストの オプション。 • 主な確認レベル: – – – – – © CROOZ,Inc {w:-1} 完全に確認なし。 {w: 0} インフラレベルのエラー(ネットワークやMongoの死活など)のみ確認。 {w: 1} SharedViewへの書き込みを確認。不正データなどが検出できる。(default) {w:$n} ($n>1) レプリカセット内で$n個のノードへの書き込みを確認。 {w:$tags} $tagsで指定した特定のレプリカセットへの書き込みを確認。 43
  44. その他の機能 • MapReduce – ビッグ・データの解析機能をデフォルトで搭載。 • 固定長コレクション(Capped) – サイズやドキュメンド数が予め決まった特殊なコレクション。 – 挿入に対して非常に高いパフォーマンスを持つ。 – シャードできない。 • 二次元地理空間インデックス – 2D座標インデックスによる距離的な検索ができる。 – 平面モデルと球面モデルをサポート。 – このインデックスはシャードキーに指定できない。 © CROOZ,Inc 44
  45. 参考程度に MYSQLとのスピード比較 © CROOZ,Inc 45
  46. MySQLとのスピード比較 パフォーマンスのスケール感をつかむために、 簡単にMySQLとベンチを取ってみた。 • マシーンはその辺にあるノートPC。 • MySQLはデフォルト状態。MongoDBはシャード構成上にシャードしない コレクションを作成し利用。 • 両方PHPドライバを利用。 • 比較用の値は平均値。 • 書き込み系でメモリベースは20万回計測、ディスクベースは1万回計測。 • Selectは20万件中ランダム1件を1万回計測。 • 適当なベンチなため、参考程度。 © CROOZ,Inc 46
  47. MySQLとのスピード比較 Insert Update Select(key ) Select Delete MongoDB 0.00024 0.00044 0.00014 0.03283 0.00068 MySQL 0.03839 0.04059 0.00009 0.03236 0.04127 • 書き込み系のスピードが圧倒的であることがわかる。 • Selectではインデックスなしは同じ程度、インデックスありは遅い 結果となり、おそらく搭載メモリ量の影響でしょう。 © CROOZ,Inc 47
  48. 書き込み確認別の比較 w:1 fsync Journaling 0.00024 0.04499 noJournaling 0.00020 0.10565 • デフォルト設定でもジャーナリングがもたらすパフォーマンス低下 が思ったより小さい。 • ジャーナルあり状態のfsyncは仕組み上比較的に早い。 © CROOZ,Inc 48
  49. 導入側の観点から まとめ © CROOZ,Inc 49
  50. 管理者の観点から • クラスタ構成の完成度が高いため、大きなシステムでも 相対的に構築、運営しやすい。 • 真新しいシステムなので、当然相応の導入コストがかか る。 • シャーディング関連のノウハウが蓄積されるまで苦労す る可能性大。 © CROOZ,Inc 50
  51. 開発者の観点から • 早い。 • レプリケーションとシャーディングはアプリレベルで面 倒を見る必要がない。 • データが取り回しやすくなり、実装が単純になる。 • スキーマの設計思想がまるっきり違うので、発想の転換 が必要。 • シャーディングでは実装レベルで注意すべきことが多い。 © CROOZ,Inc 51
  52. 使ってみましょう! © CROOZ,Inc 52
Advertisement