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

More Related Content

What's hot

MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法Tetsutaro Watanabe
 
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)Uptime Technologies LLC (JP)
 
はじめてのElasticsearchクラスタ
はじめてのElasticsearchクラスタはじめてのElasticsearchクラスタ
はじめてのElasticsearchクラスタSatoyuki Tsukano
 
MongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキストMongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキストAkihiro Kuwano
 
ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方Yoshiyasu SAEKI
 
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムMySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムKouhei Sutou
 
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~NTT DATA OSS Professional Services
 
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけRDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけRecruit Technologies
 
1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...
1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...
1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...NTT DATA Technology & Innovation
 
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
ソーシャルゲームにおけるMongoDB適用事例 - Animal Land
ソーシャルゲームにおけるMongoDB適用事例 - Animal LandソーシャルゲームにおけるMongoDB適用事例 - Animal Land
ソーシャルゲームにおけるMongoDB適用事例 - Animal LandMasakazu Matsushita
 
CloudFront経由でのCORS利用
CloudFront経由でのCORS利用CloudFront経由でのCORS利用
CloudFront経由でのCORS利用Yuta Imai
 
Apache Hadoop YARNとマルチテナントにおけるリソース管理
Apache Hadoop YARNとマルチテナントにおけるリソース管理Apache Hadoop YARNとマルチテナントにおけるリソース管理
Apache Hadoop YARNとマルチテナントにおけるリソース管理Cloudera Japan
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれKumazaki Hiroki
 

What's hot (20)

MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法MongoDBが遅いときの切り分け方法
MongoDBが遅いときの切り分け方法
 
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
 
はじめてのElasticsearchクラスタ
はじめてのElasticsearchクラスタはじめてのElasticsearchクラスタ
はじめてのElasticsearchクラスタ
 
MongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキストMongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキスト
 
RDF Semantic Graph「RDF 超入門」
RDF Semantic Graph「RDF 超入門」RDF Semantic Graph「RDF 超入門」
RDF Semantic Graph「RDF 超入門」
 
ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方
 
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムMySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
 
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけRDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
 
WiredTigerを詳しく説明
WiredTigerを詳しく説明WiredTigerを詳しく説明
WiredTigerを詳しく説明
 
NetflixにおけるPresto/Spark活用事例
NetflixにおけるPresto/Spark活用事例NetflixにおけるPresto/Spark活用事例
NetflixにおけるPresto/Spark活用事例
 
1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...
1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...
1日5分でPostgreSQLに詳しくなるアプリの開発 ~PostgRESTを使ってみた~(第38回PostgreSQLアンカンファレンス@オンライン 発...
 
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
ソーシャルゲームにおけるMongoDB適用事例 - Animal Land
ソーシャルゲームにおけるMongoDB適用事例 - Animal LandソーシャルゲームにおけるMongoDB適用事例 - Animal Land
ソーシャルゲームにおけるMongoDB適用事例 - Animal Land
 
CloudFront経由でのCORS利用
CloudFront経由でのCORS利用CloudFront経由でのCORS利用
CloudFront経由でのCORS利用
 
Apache Hadoop YARNとマルチテナントにおけるリソース管理
Apache Hadoop YARNとマルチテナントにおけるリソース管理Apache Hadoop YARNとマルチテナントにおけるリソース管理
Apache Hadoop YARNとマルチテナントにおけるリソース管理
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 

More from Takahiro Inoue

Treasure Data × Wave Analytics EC Demo
Treasure Data × Wave Analytics EC DemoTreasure Data × Wave Analytics EC Demo
Treasure Data × Wave Analytics EC DemoTakahiro Inoue
 
トレジャーデータとtableau実現する自動レポーティング
トレジャーデータとtableau実現する自動レポーティングトレジャーデータとtableau実現する自動レポーティング
トレジャーデータとtableau実現する自動レポーティングTakahiro Inoue
 
Tableauが魅せる Data Visualization の世界
Tableauが魅せる Data Visualization の世界Tableauが魅せる Data Visualization の世界
Tableauが魅せる Data Visualization の世界Takahiro Inoue
 
トレジャーデータのバッチクエリとアドホッククエリを理解する
トレジャーデータのバッチクエリとアドホッククエリを理解するトレジャーデータのバッチクエリとアドホッククエリを理解する
トレジャーデータのバッチクエリとアドホッククエリを理解するTakahiro Inoue
 
20140708 オンラインゲームソリューション
20140708 オンラインゲームソリューション20140708 オンラインゲームソリューション
20140708 オンラインゲームソリューションTakahiro Inoue
 
トレジャーデータ流,データ分析の始め方
トレジャーデータ流,データ分析の始め方トレジャーデータ流,データ分析の始め方
トレジャーデータ流,データ分析の始め方Takahiro Inoue
 
オンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータオンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータTakahiro Inoue
 
事例で学ぶトレジャーデータ 20140612
事例で学ぶトレジャーデータ 20140612事例で学ぶトレジャーデータ 20140612
事例で学ぶトレジャーデータ 20140612Takahiro Inoue
 
トレジャーデータ株式会社について(for all Data_Enthusiast!!)
トレジャーデータ株式会社について(for all Data_Enthusiast!!)トレジャーデータ株式会社について(for all Data_Enthusiast!!)
トレジャーデータ株式会社について(for all Data_Enthusiast!!)Takahiro Inoue
 
この Visualization がすごい2014 〜データ世界を彩るツール6選〜
この Visualization がすごい2014 〜データ世界を彩るツール6選〜この Visualization がすごい2014 〜データ世界を彩るツール6選〜
この Visualization がすごい2014 〜データ世界を彩るツール6選〜Takahiro Inoue
 
Treasure Data Intro for Data Enthusiast!!
Treasure Data Intro for Data Enthusiast!!Treasure Data Intro for Data Enthusiast!!
Treasure Data Intro for Data Enthusiast!!Takahiro Inoue
 
Hadoop and the Data Scientist
Hadoop and the Data ScientistHadoop and the Data Scientist
Hadoop and the Data ScientistTakahiro Inoue
 
MongoDB: Intro & Application for Big Data
MongoDB: Intro & Application  for Big DataMongoDB: Intro & Application  for Big Data
MongoDB: Intro & Application for Big DataTakahiro Inoue
 
An Introduction to Fluent & MongoDB Plugins
An Introduction to Fluent & MongoDB PluginsAn Introduction to Fluent & MongoDB Plugins
An Introduction to Fluent & MongoDB PluginsTakahiro Inoue
 
An Introduction to Tinkerpop
An Introduction to TinkerpopAn Introduction to Tinkerpop
An Introduction to TinkerpopTakahiro Inoue
 
An Introduction to Neo4j
An Introduction to Neo4jAn Introduction to Neo4j
An Introduction to Neo4jTakahiro Inoue
 
The Definition of GraphDB
The Definition of GraphDBThe Definition of GraphDB
The Definition of GraphDBTakahiro Inoue
 
Large-Scale Graph Processing〜Introduction〜(完全版)
Large-Scale Graph Processing〜Introduction〜(完全版)Large-Scale Graph Processing〜Introduction〜(完全版)
Large-Scale Graph Processing〜Introduction〜(完全版)Takahiro Inoue
 
Large-Scale Graph Processing〜Introduction〜(LT版)
Large-Scale Graph Processing〜Introduction〜(LT版)Large-Scale Graph Processing〜Introduction〜(LT版)
Large-Scale Graph Processing〜Introduction〜(LT版)Takahiro Inoue
 

More from Takahiro Inoue (20)

Treasure Data × Wave Analytics EC Demo
Treasure Data × Wave Analytics EC DemoTreasure Data × Wave Analytics EC Demo
Treasure Data × Wave Analytics EC Demo
 
トレジャーデータとtableau実現する自動レポーティング
トレジャーデータとtableau実現する自動レポーティングトレジャーデータとtableau実現する自動レポーティング
トレジャーデータとtableau実現する自動レポーティング
 
Tableauが魅せる Data Visualization の世界
Tableauが魅せる Data Visualization の世界Tableauが魅せる Data Visualization の世界
Tableauが魅せる Data Visualization の世界
 
トレジャーデータのバッチクエリとアドホッククエリを理解する
トレジャーデータのバッチクエリとアドホッククエリを理解するトレジャーデータのバッチクエリとアドホッククエリを理解する
トレジャーデータのバッチクエリとアドホッククエリを理解する
 
20140708 オンラインゲームソリューション
20140708 オンラインゲームソリューション20140708 オンラインゲームソリューション
20140708 オンラインゲームソリューション
 
トレジャーデータ流,データ分析の始め方
トレジャーデータ流,データ分析の始め方トレジャーデータ流,データ分析の始め方
トレジャーデータ流,データ分析の始め方
 
オンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータオンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータ
 
事例で学ぶトレジャーデータ 20140612
事例で学ぶトレジャーデータ 20140612事例で学ぶトレジャーデータ 20140612
事例で学ぶトレジャーデータ 20140612
 
トレジャーデータ株式会社について(for all Data_Enthusiast!!)
トレジャーデータ株式会社について(for all Data_Enthusiast!!)トレジャーデータ株式会社について(for all Data_Enthusiast!!)
トレジャーデータ株式会社について(for all Data_Enthusiast!!)
 
この Visualization がすごい2014 〜データ世界を彩るツール6選〜
この Visualization がすごい2014 〜データ世界を彩るツール6選〜この Visualization がすごい2014 〜データ世界を彩るツール6選〜
この Visualization がすごい2014 〜データ世界を彩るツール6選〜
 
Treasure Data Intro for Data Enthusiast!!
Treasure Data Intro for Data Enthusiast!!Treasure Data Intro for Data Enthusiast!!
Treasure Data Intro for Data Enthusiast!!
 
Hadoop and the Data Scientist
Hadoop and the Data ScientistHadoop and the Data Scientist
Hadoop and the Data Scientist
 
MongoDB: Intro & Application for Big Data
MongoDB: Intro & Application  for Big DataMongoDB: Intro & Application  for Big Data
MongoDB: Intro & Application for Big Data
 
An Introduction to Fluent & MongoDB Plugins
An Introduction to Fluent & MongoDB PluginsAn Introduction to Fluent & MongoDB Plugins
An Introduction to Fluent & MongoDB Plugins
 
An Introduction to Tinkerpop
An Introduction to TinkerpopAn Introduction to Tinkerpop
An Introduction to Tinkerpop
 
An Introduction to Neo4j
An Introduction to Neo4jAn Introduction to Neo4j
An Introduction to Neo4j
 
The Definition of GraphDB
The Definition of GraphDBThe Definition of GraphDB
The Definition of GraphDB
 
Large-Scale Graph Processing〜Introduction〜(完全版)
Large-Scale Graph Processing〜Introduction〜(完全版)Large-Scale Graph Processing〜Introduction〜(完全版)
Large-Scale Graph Processing〜Introduction〜(完全版)
 
Large-Scale Graph Processing〜Introduction〜(LT版)
Large-Scale Graph Processing〜Introduction〜(LT版)Large-Scale Graph Processing〜Introduction〜(LT版)
Large-Scale Graph Processing〜Introduction〜(LT版)
 
Advanced MongoDB #1
Advanced MongoDB #1Advanced MongoDB #1
Advanced MongoDB #1
 

Mongo sharding

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