Mongo dbを知ろう

52
をををを をををををををををを © CROOZ,Inc 1

Transcript of Mongo dbを知ろう

Page 1: Mongo dbを知ろう

を知ろう概要から動作原理まで

© CROOZ,Inc 1

Page 2: Mongo dbを知ろう

アジェンダ

• mongoDBとは

• クラスタ構成概要

• 内部的動作原理

• その他の仕様と機能

• MySQLとのスピード比較

© CROOZ,Inc 2

Page 3: Mongo dbを知ろう

mongoDBとは特徴から説く

© CROOZ,Inc 3

Page 4: Mongo dbを知ろう

mongoDB

オンメモリで動作するスキーマフリーなドキュメンド指向NOSQLデータベース。

© CROOZ,Inc 4

Page 5: Mongo dbを知ろう

mongoDBの背景

• 2009年よりMongoDB社(元 10gen)が提供。

• 累計調達資金 2億 3100万ドル。

• mongoDBのダウンロード数は 500万回に達する。

• mongoDB技術者の求人数は redisや Cassandraを抜いてトップを君臨。

• キーワードの検索数は HTML5に次ぐ 2番目に多い。

© CROOZ,Inc 5

※一部情報は TechCrunchから引用

Page 6: Mongo dbを知ろう

MongoDBの特徴

• ドキュメンド指向– レコードではなく、 JSONオブジェクトが格納される。

• スキーマフリー– 動的なスキーマ、リレーションの概念なし。

• Memory-Mapped File– メモリ上で動作する前提の設計で高いパフォーマンスを叩き出す。

• レプリケーション、シャーディング構成– クラスタ構成により、自動的なフェイルオーバー、シャーディングを実現。

© CROOZ,Inc 6

Page 7: Mongo dbを知ろう

ドキュメンド指向①

RDB mongoDB

Database (データベース ) Database (データベース )

Table (テーブル ) Collection (コレクション )

© CROOZ,Inc 7

KVSではなく DB!

テーブルレベルまで、基本的な構造は RDBを踏襲。

Page 8: Mongo dbを知ろう

ドキュメンド指向②

Profile collection:{ name: “Alice”, age: 20, hobby: { “outdoor”: [ “motorcycle”, … ], “indoor”: [ “reading”, ], }}

© CROOZ,Inc 8

レコードの代わりに、 JSONライクなオブジェクトが格納される。

オブジェクトの構造は理解され、検索や参照に利用できる。

この例でアウトドアの趣味にアクセスするときは、 hobby.outdoorでアクセスできる。

こうしたサブオブジェクトやデータに対しインデックスの作成など、 DBの機能がフルで利用できる。

NOTE:  内部的には JSONが BSONという JSONのバイナリ版が格納され、  パフォーマンスの向上と容量削減に貢献している。

Page 9: Mongo dbを知ろう

スキーマフリー①

• 動的なスキーマデザイン– レコードのようにテーブルごとにカラムが決まることはない。– 同じコレクションにあるドキュメンドの構造が違ってでも可。– 更新ごとにドキュメンドの構造を変更できる。– create系 APIが存在しない。

• リレーションの概念なし– 集約出来る情報は関連テーブルに分散するのではなく、同じドキュメンドのサブドキュメンドとして集約する。

– どうしても分割管理したい場合 (例:マスター )は DBRefというドキュメンド間のハイパーリンクを利用する。

© CROOZ,Inc 9

Page 10: Mongo dbを知ろう

スキーマフリー②

books

book_id

book_title

© CROOZ,Inc 10

RDBでのタグシステムの実装例

book_tag_map

tag_id

book_id

book_tags

tag_id

tag_text

• bookと tagに関連する操作は 3つのテーブルを舐める必要がある。• ランダムアクセスは最低でも3回発生する。

Page 11: Mongo dbを知ろう

スキーマフリー③

© CROOZ,Inc 11

MongoDBでのタグシステムの実装例

• tagsは bookのドキュメンドの一要素として格納。• tags配列に対してインデックスを作成し、検索に利用できる。• book自身の tagを参照する場合検索は必要ない。• 同一ドキュメンドのためディスク上では連続なので、ランダムアクセスは1回。

Books collection:{ _id: 1, title: “MongoDB”, tags: [“10gen”, “database”, “open-source”], …}

Page 12: Mongo dbを知ろう

Memory-Mapped File

• Mongoではディスク上のリソースをMemory-Mapped Fileの仕組みを利用して、メモリ上にマッピングする。

• クライアントは通常メモリ上のデータを操作する。

• Memcacheなどのメモリキャッシュシステムの機能を原理的に併せ持つ。

© CROOZ,Inc 12

NOTE:詳細は後述

Page 13: Mongo dbを知ろう

Table

MongoDBとは②

© CROOZ,Inc 13

上述の特徴を踏まえて、Mongoの運用思想とは。

Table

Table

ORマッピング

オブジェクト Memcache

RDBMSではデータの集約、整形を経て、プログラムが扱いやすい形にし上で、キャッシュシステムに格納しクライアントに提供する。

Mongoの設計思想でははじめからプログラムと親和性の高いオブジェクトをそのまま格納する。メモリ上で動作するという特徴上、キャッシュシステムも基本的には必要ない。

Page 14: Mongo dbを知ろう

クラスタ構成レプリケーションとシャーディング

© CROOZ,Inc 14

Page 15: Mongo dbを知ろう

クラスタ構成

• Mongoではレプリケーション、シャーディングの機能をそれぞれ提供している。

• レプリケーション構成において、一般的な条件下では障害からの自動フェイルオーバーが可能。

• シャーディング構成において、自動バランシング機能を備え、動的にノードの追加や除去に対応。

• 両者を組み合わせることで負荷分散された冗長構成のクラスタが出来上がる。

• クライアントからはクラスタ全体を一つの論理 DBにみなすことができる。

© CROOZ,Inc 15

Page 16: Mongo dbを知ろう

クラスタ構成図

© CROOZ,Inc 16

セカンダリサーバー (Secondary)

仲裁サーバー (Arbiter)

メタデータ―サーバー (Config)

ルーティングサーバー (Mongos)

Config Servers

Mongos Server

Replica Set

Replica Set

Data Servers

プライマリサーバー (Primary)

Page 17: Mongo dbを知ろう

クラスタ構成要素

• primaryサーバ―– アクセスを一手に受けて、セカンダリに同期していく。– フェイルオーバー時はセカンダリサーバーの中から投票によって選ばれる。

• secondaryサーバ―– デフォルトではデータに対して参照を含めアクセス不可。– フェイルオーバー時は投票によって最も同期が進んでると判断すれば、プライマリになる。

• arbiterサーバー– データを保持しないので同期もしないが、レプリカセット全体の同期状況を追跡していく。– 障害時に保持している同期状況で投票するために存在する。

• configサーバー– シャーディング構成の構成情報やシャード状況を保持する。– 構成が変更された時に、情報の提供と周知を担当する。

• mongosサーバー– クライアントにとっての窓口で、シャーディング構成のルーターのようなサーバー。– 接続時に configサーバーにシャーディング構成を問い合わせてキャッシュし、– この情報を手掛かりにデータをルーティングしていく。– Mongosサーバーはバックエンドを持たないただのプロセス。

© CROOZ,Inc 17

Page 18: Mongo dbを知ろう

レプリケーションと自動フェイルオーバー

© CROOZ,Inc 18

primary secondary secondary

同期

同期

• 一つのレプリケーション構成はレプリカセットと呼ぶ。• レプリカセットは一つの primaryと複数の secondaryで構成される。• クライアントが操作できるのは primaryのみで、 primaryから oplogというオペレーションログで secondaryに同期していく。

primary secondary

同期障害

primary

• primaryが障害の場合、 secondaryの中から投票で新しい primaryが選ばれる。• 障害発生した primaryが復帰後は secondaryとして新 primaryから同期を受ける。• oplog内にスタックされたオペレーションで最新まで同期できない場合、自動フェイルオーバーは失敗となって、手動フォローが必要になる。

Page 19: Mongo dbを知ろう

Primary 選挙と過半数票

© CROOZ,Inc 19

レプリカセットの primaryが障害した場合、レプリカセット内の残りの構成要素がそれぞれ同期が進んでいると判断した secondaryに投票する。障害要素を含む全構成要素の過半数票を獲得した secondaryが晴れて新しい primaryになる。

secondary

同期

primary

上記 primary、 secondary 各1の構成では、 primary 障害後残りの secondaryが自分自身の1票しかもらえず、1票より多い票数 ( 過半数票 )を獲得できず、 primary 選抜が失敗し自動フェイルオーバーも失敗となる。複数の secondaryを用意し対処しても、障害サーバーの数が合計数の半分になった時点で、同様に残りのサーバーが過半数票を獲得できない。

primary secondary arbiter

同期監視

この現象を解決するのが arbiterサーバー。レプリカセット内の同期状況を監視し、障害時は投票するだけの人。原理的に負荷やトラフィックが小さい。

Page 20: Mongo dbを知ろう

優先読み込み( ReadPreference)

レプリカセットに対して参照リクエスト投げるとき、参照先をある程度指定することができる。

• プライマリ– すべての読み込みはプライマリに対して行う。( default)

• プライマリ優先– プライマリが接続不可などの状況でのみセカンダリを選択する。

• セカンダリ– 全セカンダリ中 ping 返答が 15ms 秒以内のメンバーからランダムに選択する。

• セカンダリ優先– 「セカンダリ」で使えるメンバーがなかった場合にのみプライマリを選択する。

• 最も近い– Ping 返答が一番近いメンバーを選択。メンバーの種類は気にしない。

• タグセット絞込み– 上記中「プライマリ」以外、タグセットで候補の選択範囲を絞る事ができる。

© CROOZ,Inc 20

Page 21: Mongo dbを知ろう

レプリケーションまとめ

• Primary, Secondary, Arbiterサーバーで構成する。

• データサーバーの数に応じて Arbiterを用意し無駄をなす。

• 障害時は自動的にシステムの可動性を維持する。

• システム動作状態での復旧が可能。

• レプリカセットに対する読み込み先は細かく制御できる。

© CROOZ,Inc 21

Page 22: Mongo dbを知ろう

シャーディングの概要

• シャードは全自動で行われる。シャードアルゴリズムの変更やカスタマイズは不可。

• システム動作状態でのシャード構成の変更が可能。

• 基本的にアプリケーションレベルでシャードを意識する必要がない。

© CROOZ,Inc 22

Page 23: Mongo dbを知ろう

シャーディングの仕組み

© CROOZ,Inc 23

mongos

Primary shard Shard Shard

chunk0

0 ~ 100

chunk1

101 ~ 200

chunk2

201 ~ 301

{key: 150}

• データはドキュメンド単位ではなく、 chunkというデータの箱単位でシャードされる。

• インデックス作成と同じ要領でコレクション別のシャードキーを作成。このキーは変更不可。

• シャードキーに対しては RangeBasedPaginationのアルゴリズムでchunkに分割し、この chunkを各シャードに分散する。

• 振り分けられないデータは全部プライマリシャードサーバーでに行く。• プライマリシャードはコレクション別でシステムが勝手に割り振る。

chunk3

301 ~

Page 24: Mongo dbを知ろう

Chunckの分割と移動

© CROOZ,Inc 24

mongos

Primary shard Shard Shard

chunk0

0 ~ 100 chunk1

101 ~ 200

chunk2

201 ~ 301chunk

3301 ~ 400

chunk4

401 ~ 500chunk

5501 ~

• 大きくなりすぎた chunkは分割される。• Chunkが特定のサーバーに偏った場合は移動される。• Chunkの移動と分割はパフォーマンスに与えるインパクトは大きい。• Chunkの移動や分割中には一部リクエストは正しい情報を返せなくなる。( count 等)

Page 25: Mongo dbを知ろう

シャーディングの偏り対策

• ランダム性のあるデータをシャードキーにする。

• 複合キーをシャードキーにする。

• Chunkを事前に分割しておく。

• Chunkのサイズを小さく設定する。

• 定期的に手動で chunkを作成、分割してやる。

• Hashベースのシャードキーを利用する。

© CROOZ,Inc 25

Page 26: Mongo dbを知ろう

Hashベースシャードキー

シャーディングのために作られた特殊なインデックス。

• 利点:– シャードのアルゴリズムにあわせているので、非常にうまい具合に分散される。

– 自動で事前 chunk分割してくれる。

• 欠点:– 複合キーは利用不可。ピンポイント検索では不利。

© CROOZ,Inc 26

Page 27: Mongo dbを知ろう

シャーディング構成要素の障害時の挙動

• configサーバー障害– 一部障害の場合

• configサーバーのメタデータが読み取り専用になる。• DBに対する通常操作、mongosの立ち上げができるが、シャーディング構成の変更や Chunkの移動や分割ができなくなる。

• データの大量インサードがあった場合、偏ったシャーディング結果になるか、インサード失敗になる。

– 全部障害の場合• 一部障害の挙動に加え、mongosの追加や再起動ができなくなる。(精確には立ち上げ後落ちる)

• 一部シャーディング構成状態を確認するコマンドが利用できなくなる。

• Mongosサーバー障害– 単一mongosの障害はシステム自体にインパクトを与えない。– クライアントにとってはシングルポイントになるため、プロセスの自動再起動や、接続先切り替えの仕組みで回避できる。

© CROOZ,Inc 27

Page 28: Mongo dbを知ろう

シャーディングのまとめ

• 全自動なため、アプリケーションで面倒を見る必要がない。

• シャード構成にのみ存在する問題や仕様がいろいろあるので、ある程度意識してリクエストを投げる必要がある。

• 適切なシャードキーの選択が肝、慣れるまでチューニングで苦労する可能性大。

© CROOZ,Inc 28

Page 29: Mongo dbを知ろう

クラスタの物理構成例

• Primary, Secondaryサーバー– 高負荷、高ディスク IO、高トラフィック。– 実運用レベルではすべて物理サーバーが無難。

• Arbiterサーバー– 低負荷、低ディスク IO、低トラフィック。– データサーバーと分けていれば相乗り可。

• Configサーバー– 低負荷、低ディスク IO、低トラフィック。 – config同士が分けていれば相乗り可だが。

• Mongosサーバー– 低負荷?、ディスク IOなし、高トラフィック。 – トラフィックが気にしなければどこでもいい。

© CROOZ,Inc 29

とりあえず、クラスタ構成要素の特徴をまとめよう。

Page 30: Mongo dbを知ろう

クラスタ内でケチる構成

© CROOZ,Inc 30

Shard1 Shard1

Shard2Shard2

• メインのデータサーバーはそれぞれ物理サーバーを用意。• 残り負荷の低いサーバーは一プロセスごとまとめて物理サーバーを用意。• Arbiterサーバーは複数プロセス相乗りでも可。• あまり勧めないが、 Configをデータサーバーに相乗りさせても可。• 基本的に Arbiter, Config, Mongosが一プロセスずつ同時に止まっても、システムに直ちに影響を与えない。

Config3Mongos

Arbiter1

Config2

Arbiter2

Mongos

Config1

Page 31: Mongo dbを知ろう

AppServer

Mongos

AppServer

Mongos

クラスタ外でケチる構成

© CROOZ,Inc 31

Shard1 Shard1

Shard2 Shard2

• mongosは Appサーバーに置いて、 localhostから接続する。• その他の低負荷サーバーは一プロセスずつ適当なサーバーに相乗りさせる。• Appサーバーに余裕が有る場合、mongos 以外の低負荷プロセスに相乗りさせても可。

AppServer

SomeServer

Config1

Arbiter1

SomeServer

Config2

Arbiter2

AppServer

Mongos

Mongos

Config1

Page 32: Mongo dbを知ろう

内部的な動作原理mmap()を利用した実装とジャーナリング

© CROOZ,Inc 32

Page 33: Mongo dbを知ろう

内部的動作原理

© CROOZ,Inc 33

Mongoのコアはmmap()で実装している。

ディスク

メモリ

マッピング

• Mongoプロセス起動時にディスクにあるリソースを全部仮想メモリにマッピングする。

• マッピング時点ではデータはメモリに乗らない。• 一旦マッピングすると OSの機能でメモリとディスクが関連付けられて、メモリへの更新は任意のタイミングでディスクにフラッシュできる。

• Mongoではデフォルトで 60 秒ごとディスクにフラッシュする。

60 秒ごとの更新

Page 34: Mongo dbを知ろう

Memory-Mapped Fileから見るMongoの特性

• 利点:– 通常はメモリ上で動作するため、動作が早い。 (特に書き込み )

– よく利用するデータは自然と物理メモリに来るので、メモリキャッシュシステムのような役割もこなす。

– 大量な書き込みでも相対的にディスク IOが小さい。• 欠点:

– 32bitシステムでは使いものにならない。– 仮想メモリ扱いなので、ページアウトが発生する。 (page

fault)– Mongoがアクティブに動く環境では他のプロセスをガンガンスワップアウトさせてしまう。

– 永続化は 60 秒ごとの更新なので、最悪 60 秒のデータが飛ぶ。

• 結論:– メモリをいっぱい積みましょう!© CROOZ,Inc 34

Page 35: Mongo dbを知ろう

ジャーナリングシステム概要

• 単一プロセスの対障害能力を向上する目的で作られたシステム。

• 先行書き込みログの仕組みでパフォーマンスを維持しながら実現。

© CROOZ,Inc 35

消える 60 秒間のデータのために!

Page 36: Mongo dbを知ろう

ディスク メモリ

ジャーナリングシステムの動作原理①

© CROOZ,Inc 36

DB Data Shared View

60sごとの更新

Write OP

Private View

Journaling File

100msごとの書き込み

• DBのデータは SharedViewというビューにマッピングされた後、 SharedViewを PrivateViewに第二のマッピングを行う。

• リクエストに対しライトオペレーションは SharedViewではなくPrivateViewに送られ、書き込み終了後 SharedViewに反映する。

• 100msごとに PrivateViewに送られたライトオペレーションだけをディスクのジャーナリングファイルに書き込む。

map

Memory-Mapped File

Page 37: Mongo dbを知ろう

ディスク メモリ

Memory-Mapped File

ジャーナリングシステムの動作原理②

© CROOZ,Inc 37

DB Data Shared View

Private View

Journaling File

WriteOPを

再生

データをフラッシュ

• 障害復帰後、 JournalingFileから SharedView 宛にライトオペレーションを再生し、メモリ上のデータを復旧させる。

• SharedViewからディスクに最新データをフラッシュする。• SharedViewから PrivateViewに最新データをにリマップする。• これで復旧完了、リクエストを受け付ける。

remap

Page 38: Mongo dbを知ろう

クラスタ構成でのジャーナリング

Mongoではレプリケーション構成でもジャーナリングの利用を推奨している。理由は以下:

• レプリケーション全体の障害に対応できる。

• より素早く確実なリカバリが出来る。

• 障害後はmongoプロセスを単純に再起動することで対応できる。

© CROOZ,Inc 38

Page 39: Mongo dbを知ろう

ジャーナリングシステムのまとめ

• 利点:– 障害耐性向上。最大 60sのデータロスが 100msにできる。– レプリケーション構成での自動フェイルオーバー能力向上。– 永続性保証書き込みの敷居が下がる。 (詳細後述 )

• 欠点:– 同じビューがメモリ上2つ存在するため、メモリ消費量が倍!– 一回の更新で 2回のメモリ操作が発生する。– ジャーナリングファイル書き込み分のディスク IOが発生する。

• 結論:– 特別な理由がなければ利用した方がいい。

© CROOZ,Inc 39

Page 40: Mongo dbを知ろう

その他の仕様と機能特徴的な仕様とその他の機能を紹介

© CROOZ,Inc 40

Page 41: Mongo dbを知ろう

特徴的な仕様①:  Fire-and-Forgetの精神

• 書き込みリクエストに対し、mongoは実際のディスク書き込みを確認しない。

• この仕様でメモリ動作の優位性を保ち高いパフォーマンスを維持する。

• ディスク書き込みを保証してほしい場合、多くのドライバは fsyncパラメータをサポートする。

© CROOZ,Inc 41

Page 42: Mongo dbを知ろう

特徴的な仕様②:  fsync

• Mongoでは fsyncは管理コマンド。メモリをディスクに直ちにフラッシュさせる。

• 各言語のドライバでは書き込み系 APIのオプション。– 指定すると該当オペレーションのディスク書き込みを保証する。– ただし、ジャーナリングありとなしで挙動が違う。– ジャーナリングなし:

• メモリへの書き込み後、直ちにディスク書き込みが行われる– ジャーナリングあり:

• メモリへの書き込み後、ジャーナリングファイル書き出しの最大100ms間隔を待つ。

– ジャーナリングありではより低負荷で永続保証書き込みできる。– でも、用法用量を守って正しく使うべき。

© CROOZ,Inc 42

Page 43: Mongo dbを知ろう

特徴的な仕様②: 書き込み確認(WriteConcern)

• Fire-And-Forgetの精神をより細かくコントロールするための機能が書き込み確認。

• リクエストに対しどの段階まで成功とみなすかを表すリクエストのオプション。

• 主な確認レベル:– {w:-1} 完全に確認なし。– {w: 0} インフラレベルのエラー(ネットワークやMongoの死活など)のみ

確認。– {w: 1} SharedView への書き込みを確認。不正データなどが検出できる。

(default)– {w:$n} ($n>1) レプリカセット内で $n 個のノードへの書き込みを確認。– {w:$tags} $tagsで指定した特定のレプリカセットへの書き込みを確認。

© CROOZ,Inc 43

送り出したリクエストが心配で心配で仕方ない方に

Page 44: Mongo dbを知ろう

その他の機能

• MapReduce– ビッグ・データの解析機能をデフォルトで搭載。

• 固定長コレクション( Capped)– サイズやドキュメンド数が予め決まった特殊なコレクション。– 挿入に対して非常に高いパフォーマンスを持つ。– シャードできない。

• 二次元地理空間インデックス– 2D 座標インデックスによる距離的な検索ができる。– 平面モデルと球面モデルをサポート。– このインデックスはシャードキーに指定できない。

© CROOZ,Inc 44

Page 45: Mongo dbを知ろう

MYSQLとのスピード比較参考程度に

© CROOZ,Inc 45

Page 46: Mongo dbを知ろう

MySQLとのスピード比較

• マシーンはその辺にあるノート PC。

• MySQLはデフォルト状態。MongoDBはシャード構成上にシャードしな

いコレクションを作成し利用。

• 両方 PHPドライバを利用。

• 比較用の値は平均値。

• 書き込み系でメモリベースは 20万回計測、ディスクベースは 1万回計測。

• Selectは 20万件中ランダム 1 件を 1万回計測。

• 適当なベンチなため、参考程度。

© CROOZ,Inc 46

パフォーマンスのスケール感をつかむために、簡単にMySQLとベンチを取ってみた。

Page 47: Mongo dbを知ろう

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

© CROOZ,Inc 47

• 書き込み系のスピードが圧倒的であることがわかる。

• Selectではインデックスなしは同じ程度、インデックスありは遅

い結果となり、おそらく搭載メモリ量の影響でしょう。

Page 48: Mongo dbを知ろう

書き込み確認別の比較

© CROOZ,Inc 48

w:1 fsync

Journaling 0.00024 0.04499

noJournaling 0.00020 0.10565

• デフォルト設定でもジャーナリングがもたらすパフォーマンス低

下が思ったより小さい。

• ジャーナルあり状態の fsyncは仕組み上比較的に早い。

Page 49: Mongo dbを知ろう

まとめ導入側の観点から

© CROOZ,Inc 49

Page 50: Mongo dbを知ろう

管理者の観点から

• クラスタ構成の完成度が高いため、大きなシステムでも相対的に構築、運営しやすい。

• 真新しいシステムなので、当然相応の導入コストがかかる。

• シャーディング関連のノウハウが蓄積されるまで苦労する可能性大。

© CROOZ,Inc 50

Page 51: Mongo dbを知ろう

開発者の観点から

• 早い。

• レプリケーションとシャーディングはアプリレベルで面倒を見る必要がない。

• データが取り回しやすくなり、実装が単純になる。

• スキーマの設計思想がまるっきり違うので、発想の転換が必要。

• シャーディングでは実装レベルで注意すべきことが多い。

© CROOZ,Inc 51

Page 52: Mongo dbを知ろう

使ってみましょう!

© CROOZ,Inc 52