mongo sharding

60
Sharding 詳詳 詳詳詳詳詳詳詳詳詳詳詳 doroykujin

Upload: takahiro-inoue

Post on 15-Jan-2015

48.145 views

Category:

Documents


2 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Mongo sharding

Sharding 詳解

〜機能と仕組みの理解〜doroykujin

Page 2: Mongo sharding

自己紹介• doryokujin (25 歳 )

• 諭吉大学院 数学科 卒業できました

• MongoDB JP 主催者

• 芸者東京エンターテインメント (GTE) データマイニングエンジニア

Page 3: Mongo sharding

発表の目的• Mongo Sharding への理解を深めてほしい– 1. Mongo Sharding の特徴を知ってほしい– 2. なかなか知り得ない機能詳細や意外な振る

舞いがあることを知って欲しい– 3. 使用上における問題点をきちんと把握して

おいて欲しい– 4. Mongo Sharding を試すきっかけになって

欲しい

Page 4: Mongo sharding

発表の内容• 「 Scaling MongoDB」

の内容を 7 割方網羅– Mongo Sharding に焦点

を絞って書かれた本

– この本を読むこと Sharding への理解がかなり深まる

• 併せてドキュメントの内容も盛り込んでいる

Page 5: Mongo sharding

アジェンダ• 1. Mongo Sharding の 3 つのコンセプ

トを紹介→ 概要の理解

• 2. Mongo Sharding の機能・振る舞いを4 つのキーワードから紹介→ 個々の機能の深い理解

Page 6: Mongo sharding

最終的に言いたいこと• Shard Key の設定は非常に重要、慎重に

– Shard の偏りを極力減らす事は重要

– Shard Key によって偏り具合が大きく異なる

• Sharding 環境におけるクエリは振る舞いが怪しい部分があるので要注意(重複問題)

– 正しい count() が行われない

– unique のはずのキーが重複して存在

Page 7: Mongo sharding

Mongo Sharding 3 つのコンセプト

Page 8: Mongo sharding

Sharding とは?• 定義: DB 上のデータを複数のサーバーに

分割して運用すること• メリット:個々のサーバーの– 負荷の軽減– 使用領域を軽減– パフォーマンス向上– 扱えるデータサイズの向上

Page 9: Mongo sharding

Mongo Sharding Concept

• MongoDB の掲げる 3 つのコンセプト

– 「 Make the cluster “invisible” 」

– 「 Make the cluster always available for reads and writes 」

– 「 Let the cluster grow easily 」

Page 10: Mongo sharding

Mongo Sharding Concept 1

• Make the cluster “invisible”

– 全ての接続を mongos サーバーが仲介することによってクライアントはクラスタ全体の情報を意識することなく扱える

– クライアントは Sharding していない状況と同じようにクエリを発行し、結果を得ることができるより高速に)

Page 11: Mongo sharding

Mongo Sharding Concept 2

• Make the cluster always available for reads and writes

– Auto-Failover で MongoDB のダウン時間を減らせ、常にデータにアクセスできる状態

– データの自動分割や Auto-balancing によって常に安定した状態を保ち続けられる

Page 12: Mongo sharding

Mongo Sharding Concept 3

• Let the cluster grow easily

– Shard の追加・撤退が容易にできる– 新しい Shard の追加に対して自動的にデータ

の移行・均一化が図れる( Migration, Auto-Balancing )

Page 13: Mongo sharding

Mongo Sharding を理解するための 4つのキーワード

Page 14: Mongo sharding

Mongo Sharding を理解するための 4つのキーワード

• Shard Key:

– コレクションを分割する際のキー

• Balancing, Migration:

– Shard 間のデータの均等な分散を維持する仕組み

• mongos, config, mongod:

– Sharding を構成する 3 種類のサーバー

• Sharding クエリ :

– Sharding 環境におけるクエリの振舞と問題点

Page 15: Mongo sharding

1. Shard Key

Page 16: Mongo sharding

Shard Key :概略• データの分割は何らかのキーに従って行う• それを Shard Key と呼ぶ• Shard Key は Collection 内のどれか 1 つのキー

から選択• 各 Shard 内のデータは Chunk と呼ばれるデータ

単位で分割・移動・削除などが行われる• Shard 間の偏りとは、 Chunk の数が一部に偏る事• Shard が偏るのはよろしくない

Page 17: Mongo sharding

Chunk に関して• Chunk は、特定のコレクションの連続した範囲

のデータ集合• データがどの Chunk に属するかは、 Shard

Key の値によって決まる• Chunk はデータサイズが 200MB (デフォル

ト)を超えると自動で等分割が行われる• 分割されるごとに Shard 内の Chunk 数が増

加• Shard Key は型の混在が可能。MongoDB は

全ての型を通して順序が決まっている

Page 18: Mongo sharding

http://www.10gen.com/static/presentations/scaling-jp.pdf

データが挿入されていく度にChunk が分割されていくとしてその様子をみてみる

Page 19: Mongo sharding
Page 20: Mongo sharding
Page 21: Mongo sharding

これが Chunk と呼ばれるデータの集合単位。連続した範囲のデータ集合。新しいデータは Shard Keyの値が Chunk の範囲内にある所に入る。 200MB を超える度に分割が起こる。(デフォルト)

Page 22: Mongo sharding

Chunk に関する注意点

• 各々の Chunk の持つ範囲は絶対に重複しない。1 つのデータに対してただ 1 つの Chunk が対応。範囲は [ a, b ) で、左を含み右を含まない

• Shard Key は変更できない。やり直したい場合は対象の Collection を削除してから

• ShardKey の値を持たないドキュメントは保存できない。ただし null は可能

Page 23: Mongo sharding

2. Balancing, Migration

Page 24: Mongo sharding

Auto-balancing, Migration• Auto-balancing

– ある特定の Shard に Chunk が集中した場合、自動で他の Shard への移行( =Migration )

– トリガーは Shard 内における最大 Chunk 数と最小 Chunk 数の差が 10以上になったとき

• デフォルトで最大 200MB/Chunk なのでデータサイズの差が 2GB以上になったとき

– 最大 Shard からランダムに 5 つの Chunk が選ばれ、最小 Shard への Migration が行われる

Page 25: Mongo sharding

Migration における問題• ※ Migration には多大なコストがかかる– config サーバーへの負担–ネットワーク帯域の圧迫– メモリ領域の圧迫( Chunk をメモリにコピーするので)

– パフォーマンスの低下– 正しいクエリの結果を返さない(後述)–低速。完了に非常に時間がかかる

Page 26: Mongo sharding

1. (再) Shard Key

Page 27: Mongo sharding

Shard Key 選択の重要性• Migration は極力起こらないように

• つまり Shard 間に Chunk の偏りがない

• Shard 間に偏り少なくなる Shard Key を選択

• 一度選択した ShardKey は変更できないので慎重に

Page 28: Mongo sharding

Shard Key: 悪い例①• Low-Cardinality Shard Key

– 「密度」の低い Shard Key

– 主にカテゴリデータなどの”離散”データ– 例:大陸名

• (-∞, America], (America, Asia], (Asia, Australia],…

– 理由:• Chunk の分割ができない

• N 個のカテゴリ数なら N 個の Chunk しかできない

• N 個以上の Shard サーバーは意味がない

Page 29: Mongo sharding

Shard Key: 悪い例②• Ascending Shard Key

– Shard Key の値が増えていくのみのデータ– Time, ObjectId, Incremental Unique Id

– 例:• [-∞, +∞ )

• → [ -∞, 12945 ), [12945, +∞ )

• → [ -∞, 12945 ), [12945, 12948 ), [ 12948, +∞ )

– 理由:• ( $CurrentMax, +∞ ] の Chunk だけがひたすら分割• 明らかに Shard 間で不均一がおこる

Page 30: Mongo sharding

ShardKey: 悪い例③• Random Shard Key

– Shard Key の値が Random に決まる場合–例: MD5 hash

– 理由:• Chunk は均等分散するが非常に大きな範囲を

持った Chunk が存在する可能性

• その Chunk の Migration は RAM を圧迫する

• Random Shard Key に対する Index も非効率

Page 31: Mongo sharding

Shard Key: 良い例• Coarsely Ascending Key + Search Key

– 緩く増加していくキー + 検索でよく使われるキー– 例:アクセス解析 { month:1, user: 1}

• ( (“2011-04”,”doryokujin”), (“2011-04”, “gohan”) ),

( (“2011-04”,”gohan”), (“2011-04”, “taberu”) ),…

– 理由:• 左のキーは一定期間固定で、右のキーはほぼ均等に分布し

てくれる

• 時間がたつと左のキーの値が増え、元の(解析対象としない、古い)値の Chunk は分割されなくなり、 Migration が起こりにくくなる

Page 32: Mongo sharding

良い Shard Key のイメージ• 長い時間が経って Shard の偏りが起き始

める頃に、片方のキーが増加して Shard をリフレッシュしてくれる

shard1 shard2 shard3 shard4 shard5 shard6

2011/04 2011/05

name

month

Page 33: Mongo sharding

3. mongos, config, mongod

Page 34: Mongo sharding

Sharding を構成するサーバー群

config Servers(Shard Configration)

mongos Servers (Routers)

Shard Servers (Data)

[ a, f )

[ f, k )

[ k, n)

[ n, o )

[ o, t )

[ t, } )

shard1 shard2 shard3

Chunk

Cluster

Page 35: Mongo sharding

サーバー間の関係

http://www.mongodb.org/display/DOCS/Sharding+Introduction

Page 36: Mongo sharding

mongos サーバー

クライアントのアクセスは必ず mongos に対して行う

該当データのある Shard にのみクエリの送出・データの取得を行う

cinfig サーバーから Shard に関する情報を取得する

Page 37: Mongo sharding

mongos サーバーの役割• クライアントは全ての読み書きを

mongos に対して行う• mongos はどの Chunk がどの Shard

にあるかを把握している• ただし永続的な情報を保存するわけでは

ない。 config サーバーがそれを持つ• [ ダウン ] : Shard にアクセス不能にな

るので、完全に機能停止することに

Page 38: Mongo sharding

config サーバー

“ 特殊な” mongod サーバー

shard に関する (永続的な )メタ情報を保持

change chunkSizedisable Balancing

Page 39: Mongo sharding

config サーバーの役割

• shards, mongos process, sysadmin に関するメタ情報を保持

• 複数起動可能。ただしテスト環境は 1 つ、本番環境でも 3 つで十分( 3 で最適化)

• 独自のプロトコルで同期を行う。手動でReplication の設定をしてはいけない

• [ ダウン ] : Shard の設定変更が不可能になる。読み書きは継続

Page 40: Mongo sharding

config Collection> use configswitched to db config

> show collections changelog # 過去の Migration に関する詳細なログ chunks # 全ての Chunk の情報 collections # Sharding している全ての Collection の情報 databases # 全 DB に関して Sharding の有無などの情報 lockpingslocksmongos # mongos に関する情報settings # chunkSize の設定情報、 balancer 機能の切替shards # Shard に関する情報system.indexesversion

> db.settings.update({"_id" : "balancer"}, {"$set" : {"stopped" : true }}, true)

Page 41: Mongo sharding

4. Sharding クエリ

Page 42: Mongo sharding

mongos へのクエリタイプ• Targeted– Shard Key が指定されることによって、必要

なデータがある shard にのみアクセス。最小限。

• Global– Shard Key が指定されず、 mongos プロセ

スはシステム内の ( ほぼ ) すべての Shard にアクセス

Page 43: Mongo sharding

Shard Key を用いての find()

{“name”: “inoue” }

[ k, n)

[ n, o )

shard2mongos

[ a, f )

[ f, k )

shard1

{“name”: “tanaka” }

[ o, t )

[ t, } )

shard3

指定された Shard Key (“name” key) を含む Chunk のある Shard にのみクエリの発行・データの取得を行う

db.adminCommand({"shardCollection" : ”mongo.users", key : {”name" : 1}}

db.shardCollection.find({“shardKey”: “xxx”})

targeted

Page 44: Mongo sharding

db.shardCollection.find({“nonShardKey”: “xxx”})

[ k, n)

[ n, o )

shard2mongos

[ a, f )

[ f, k )

shard1

{“pref”: “Tokyo” }

[ o, t )

[ t, } )

shard3

mongos は Shard Key 以外 (“pref” key) の情報を知り得ないので全ての Shard にアクセスする。

ただしインデックスを利用できる。

db.adminCommand({"shardCollection" : ”mongo.users", key : {”name" : 1}}

Non Shard Key を用いての find()global

Page 45: Mongo sharding

db.shardCollection.update({“shardKey”: “x”},{$set{key:value}})

{“name”: “inoue” }

[ k, n)

[ n, o )

shard2mongos

[ a, f )

[ f, k )

shard1

{“name”: “tanaka” }

[ o, t )

[ t, } )

shard3

指定された shard key(“name” key) を含む chunk のあるshard にのみクエリの送出・データの取得を行う

db.adminCommand({"shardCollection" : ”mongo.users", key : {”name" : 1}}

update

update

Shard Key を用いての single-update()

targeted

Page 46: Mongo sharding

db.shardCollection.find().sort({“nonShardKey”: 1})

[ k, n)

[ n, o )

shard2

[ a, f )

[ f, k )

shard1

[ o, t )

[ t, } )

shard3

sort() が呼ばれた場合は、各 Shard における検索結果のドキュメント集合に対して sort を行い、さらに mongos が全 Shard で merge sort

shard1 内で sort

shard2 内で sort

shard3 内で sort

shard1,2,3 の結果を merge sort

{“pref”: “Tokyo” } mongos

Non Shard Key を用いての sort()

global

Page 47: Mongo sharding

db.shardCollection.count ({“nonShardKey”: 1})

[ k, n)

[ n, o )

shard2

[ a, f )

[ f, k )

shard1

[ o, t )

[ t, } )

shard3

count() が呼ばれた場合は、各 Shard における検索結果のドキュメント集合に対して count を

行い、さらに mongos が全 Shard の結果で total

shard1 内で count

shard2 内で count

shard3 内で count

shard1,2,3 の結果で count

{“pref”: “Tokyo” } mongos

Non Shard Key を用いての count()

global

Page 48: Mongo sharding

db.runCommand ({mapreduce: shardedCollection,…})

[ k, n)

[ n, o )

shard2mongos

[ a, f )

[ f, k )

shard1

[ o, t )

[ t, } )

shard3

mapreduce

mapreduce

shard1,2,3 の結果で ” re”-reduce

mapreduce

Non Shard Key を用いての mapreduce()

emit( “pref”: 1 )

mapreduce() が呼ばれた場合は、各 Shard における検索結果のドキュメント集合に対して mapreduce を行い、さらに mongos が全 Shard の結果で reduce

global

Page 49: Mongo sharding

{ x : 1 } Shard Key と仮定。targeted では Shard へのアクセスは最小限global は、システム内の ( ほぼ ) すべての Shard にアクセス

Page 50: Mongo sharding

Shard Key を使用しない場合に問題のあるクエリ

• Sharding 環境で Shard Key を使用しないクエリは、必ずしも正しく実行されるとは限らない– 「 Chunk Migration 中の count() 」– 「同時書き込み発生時の single-update() 」– 「同時書き込み発生時の unique index 」– 「 tmp_collection が削除されない

mapreduce() 」

Page 51: Mongo sharding

Chunk Migration 中の count()

• Chunk Migration 中は処理が完了するまで、移動元・移動先に同じ Chunk が存在する

• 完全にコピーが完了し、 config サーバーが更新されて完了となる

• その間に count() コマンドが実行された場合、この Chunk のデータは重複してカウントしてしまう可能性がある。

• 結果:真値より大きくなる

Page 52: Mongo sharding

mongos

shard2shard1

X

shard2shard1

X

shard2shard1

X

X

移行中…

count X

count X

Chunk Migration 中の count()

重複カウント

Page 53: Mongo sharding

同時書き込み発生時のunique Index

• MongoDB は書き込みに対してロックを行わない(複数の書き込みに対してアトミックでない)

• unique な Index として設定したキー(Shard Key では無い ) が異なる Shard 間で存在する可能性がある

• “_id” でさえも重複する可能性がある• 結果: Shard Key 以外のユニーク性が保証されない

Page 54: Mongo sharding

mongos

shardKey={“email”:1} とは別に unique Index={“name”:1} である Key での update が同時に行われた場合、 unique

キーなのに重複する可能性がある

shard 1

X

shard2

shard3

Y

Z

mongos

{"_id" : ObjectId("4d2a2f7c56d1bb09196fe7d0"), ”name" : ”doryokujin", "email" : “[email protected]” }

{"_id" : ObjectId("4d2a2e9f74de15b8306fe7d0"), ”name" : ”doryokujin", "email" : ”[email protected]"

update

update

同時書き込み発生時のunique Index

Page 55: Mongo sharding

同時書き込み発生時のsingle-update

• 同様に nonShard なキーで同時に single- update を行う際にも問題が

• アトミックな操作が保証されないのでエラーとなる

• Non Shard Key に対しては必ず multi-update を行う

• 結果: single-update に対してエラー

Page 56: Mongo sharding

「 tmp_collection が削除されないmapreduce() 」

• Shard の中から 1 つの「代表」が選ばれ、各Shard で mapreduce が実行された結果に対してもう一度 reduce を行う

• 計算はオプションを指定しない限り、 tmp_collection が作られる

• Sharding 環境では計算終了後に一時的に作成した tmp_collection が自動で削除されない

• 結果:不要な Collection が増えていく• v.1.8 で改善。手動で削除して対処

Page 57: Mongo sharding

Sharding クエリは要注意

• このように Sharding 環境におけるクエリには十分な注意が必要

• 同時書き込みに対してアトミックでないことが影響

• Chunk Migration 中の Chunk は重複して数えられる可能性がある

Page 58: Mongo sharding

Mongo Sharding を理解するための 4つのキーワード

• Shard Key:

– コレクションを分割する際のキー

• Balancing, Migration:

– Shard 間のデータの均等な分散を維持する仕組み

• mongos, config, mongod:

– Sharding を構成する 3 種類のサーバー

• Sharding クエリ :

– Sharding 環境におけるクエリの振舞と問題点

Page 59: Mongo sharding

最終的に言いたいこと• Shard Key の設定は非常に重要、慎重に

– Shard の偏りを極力減らす事は重要

– Shard Key によって偏り具合が大きく異なる

• Sharding 環境におけるクエリは振る舞いが怪しい部分があるので要注意

– 正しい count() が行われない

– unique のはずのキーが重複して存在

Page 60: Mongo sharding

ありがとうございました…