SlideShare a Scribd company logo
MongoDB紹介



2012/5/18 matsumura
MongoDBってなんぞ
 - 多機能 but 発展途上
•    ドキュメント指向データベース
     o    最新2.0.5
•    自動シャーディング
     o    Read / Writeがスケールアウト
•    自動フェイルオーバー
     o    Master deadでも自動でフェイルオーバー
•    柔軟なクエリ
     o    SQLで可能なことはJOIN句以外 一通りできる
•    スキーマレス
     o    データによって自由に持つものを決められる


                                     他にも多機能
構成例

              Web	
        Web	
                mongos	
     mongos	
                3processで
最小構成台数                                                 最適化	
 3process	
                    data         data   meta

                mongod	
     mongod	
   Mongod
                                        (config)	
               mongod	
     mongod	
                                        Mongod
                                        (config)	
                mongod	
     mongod	
                                        Mongod
               Replica      Replica     (config)	
                 set	
        set
基本的なデータの持ち方
                                                    MySQLで例えると
 mongod	
                                                     mysqld	

  データベース etcr	
                                                    データベース	
  コレクション 行動履歴	
             コレクション XXマスタ	
                                                     テーブル	
  doc	
     doc	
   doc	
   doc	
   doc	
   doc	
                                                     レコード	
  doc	
     doc	
   doc	
   doc	


  データベース other	

  コレクション 各種ログ	

  doc	
     doc	
   doc
レプリカセット
- MySQL同様

Mongod (Primary)	
               Mongod(Secondary)	
        Mongod(Secondary)	

データベース etcr	
                    データベース etcr	
              データベース etcr	

コレクション 行動履歴	
                    コレクション 行動履歴	
              コレクション 行動履歴	

docA	
   docB	
   docC	
         docA	
   docB	
   docC	
   docA	
   docB	
   docC	

docD	
   docE	
   docF	
         docD	
   docE	
   docF	
   docD	
   docE	
   docF	

                                          再現	
                       再現	
データベース local	
                   データベース local	
             データベース local	

コレクション oplog	
                   コレクション oplog	
             コレクション oplog	
                           同
 操作	
    操作	
     操作	
     期	
    操作	
    操作	
     操作	
      操作	
    操作	
     操作
自動フェイルオーバー
•    Primaryが死ぬ
•    Primaryが死んだことがreplica set内で共有
•    残ったノードで投票を行う
•    ノードごとの優先度設定、最終同期時刻をもとに投票
     を行う
•    過半数より多くの票を集めたノードがPrimaryとなる

•    この間 約20s ∼ 60s
自動シャーディング - phase1

Mongod (Shard A)	
                    Mongod (Shard B)	
データベース etcr	
                         データベース etcr	

コレクション 行動履歴	
                         コレクション 行動履歴	


Chunk ( –無限大 〜 無限大]	
docA	
   docB	
   docC	


                           デフォルト
                            200MB
自動シャーディング - phase2

Mongod (Shard A)	
          Mongod (Shard B)	
データベース etcr	
               データベース etcr	

コレクション 行動履歴	
               コレクション 行動履歴	


Chunk ( –無限大 〜 D]	
 docA	
   docB	
   docC	


Chunk ( D 〜 無限大]	
docD	
    docE	
   docF
自動シャーディング - phase3

Mongod (Shard A)	
                    Mongod (Shard B)	
データベース etcr	
                         データベース etcr	

コレクション 行動履歴	
                         コレクション 行動履歴	


Chunk ( –無限大 〜 D]	
 docA	
     docB	
   docC	



  docC’	
      docC’’	
   docC’’’	




Chunk ( D 〜 無限大]	
docD	
      docE	
   docF
自動シャーディング - phase4

Mongod (Shard A)	
                    Mongod (Shard B)	
 データベース etcr	
                        データベース etcr	

 コレクション 行動履歴	
                        コレクション 行動履歴	


Chunk ( –無限大 〜 C’]	
 docA	
     docB	
   docC	


Chunk (C’ 〜 D]	
  docC’	
      docC’’	
   docC’’’	


Chunk ( D 〜 無限大]	
 docD	
     docE	
   docF
自動シャーディング - phase5

Mongod (Shard A)	
                    Mongod (Shard B)	
 データベース etcr	
                        データベース etcr	

 コレクション 行動履歴	
                        コレクション 行動履歴	


Chunk ( –無限大 〜 C’]	
                  Chunk ( D 〜 無限大]	
 docA	
     docB	
   docC	
           docD	
   docE	
   docF	


Chunk (C’ 〜 D]	
  docC’	
      docC’’	
   docC’’’	
                       水平方向に
                                                         スケールアウト
自動シャーディング - phase6
• Sharding Demo
スキーマレス
•  Create table, Create column family 不要
  o  Insertした時点で作られる
  o  アプリ要件に合わせて柔軟に入れられる
  Item1 = {
      _id: ObjectId('4b0552b0f0da7d1eb6f12xxx'),
      name: 秘薬,
      price: 100,
  }
  Item2 = {
      _id: ObjectId('4b0552b0f0da7d1eb6f12yyy'),
      name: 自分用秘薬,
  }
柔軟なクエリ
• SQL文を持たない
• Demo
• ハッシュでO/Rマッパーのように指定する
 o  フロントjavascriptからクエリオブジェクトを
    送って、サーバーサイドでは検証後、即実行でき
    る
クエリ 周辺の話 (1)
• Index(B-Tree)
  o  配列やオブジェクトに対してもはれる
      § ただし、配列は1つ / indexに制限
  o  メモリに乗るようにintを使うと吉
     // indexをつける
     db.test.ensureIndex({x:1, y:1, z:1})

     ○ db.test.find({x:'a'})
     ○ db.test.find({x:'a', y:'b'})
     ○ db.test.find({x:'a', y:'b'}).sort({z:1})

     // 順序が重要
     × db.test.find({y:'b', x:'a'})
クエリ 周辺の話(2)
• クエリオプティマイザ
 o MySQLのようなコストベースではない
 o 初回のクエリで複数クエリプランを同時実行
 o  最も早かったクエリを利用
 o  データ量に応じて定期的に見直し
 o  explain()
クエリ 周辺の話(3)
• Capped コレクション
 o  あらかじめサイズを決めたコレクション
 o  古いものから順次消えていく
 o  挿入順での検索で高速
 o  Shardingできない
 o  削除不能
 o  Create文を明示的に発行して作成
     § db.createCollection("mycoll", {capped:true,
        size:100000})
クエリ findの話 (1)
•  検索条件は、bsonオブジェクトの先頭に寄せる
1. db.activityHistoryDemo.find({owner_id: 123})
2. db.activityHistoryDemo.find({‘concerned.id’: ‘201’})
                    {
                      owner_id: 123,
                      request: { type: '合成', params: {}},
                      process: {category: 'composit'},
                      memo: ['lv.0 -> lv.15'],
                      concerned: [
                        {io: 'i', type: 'card', id: 100, object: '111', base: true},
                        {io: 'i', type: 'card', id: 201, object: '222'},
                        {io: 'o', type: 'card', id: 100, object: '111'},
                      ]
                    })
クエリ findの話 (2)
•  bsonオブジェクト階層を細分化したほうが早い
db.activityHistoryDemo.find({‘concerned.id’: ‘201’})

                   {
                     owner_id: 123,
                     request: { type: '合成', params: {}},
                     process: {category: 'composit'},
                     memo: ['lv.0 -> lv.15'],
                     concerned: [
                       {io: 'i', type: 'card', id: 100, object: '111', base: true},
                       {io: 'i', type: 'card', id: 201, object: '222'},
                       {io: 'o', type: 'card', id: 100, object: '111'},
                     ]
                   })
クエリ findの話 (3)
•  条件の指定順序
 o  And条件は結果の小さな条件から順次
     §  補集合を無視するので。

  ○ db.sample.find({owner_id: 123, ‘concerned.type’: ‘card’})

  × db.sample.find({‘concerned.type’: ‘card’, owner_id: 123})

 o  Or条件は結果の大きな条件から順次
     §  後続条件は補集合から検索するので。

  ○ db.sample.find({$or: [{‘concerned.type’: ‘card’}, {owner_id: 123}])

  × db.sample.find({$or: [{owner_id: 123}, {‘concerned.type’: ‘card’}])
クエリ findの話 (4)
•  DBRef
  doc = {
    name: 'ryooo',
    card:[
      {'$ref': 'card', '$id' : ObjectId('4b0552b0f0da7d1eb6f12xxx')},
    ]
  }
  doc.card[0].fetch() // ←カードオブジェクトがとれる


  @ruby
  db = Connection.new.db(”etcr ")
  user_card = db["user_card"].save({:name => ”ryooo”, :card_id => 123})

  ref = DBRef.new(”card", user_card.card_id)
  db.dereference(ref)
  #=> カードオブジェクト
クエリ findの話 (5)
•  検索条件に関数も使える(javascript)
 // 極端な話、こんなクエリも書けちゃいます
 db.cards.find(function(){
   row = db.user_summary.findOne({owner_id: this.owner_id})
   return this._id == row.leader_card_id;
 })

•  mongoサーバーサイドに関数を登録できる
 // 関数を登録
 db.system.js.save({_id:’name', value: function (){ //implementation }});
 f = db.system.js.findOne({_id:’name'})

 // 検索で利用(fはサーバー側で実行される)
 Db.cards.find(f)
クエリ findの話 (6)
 Shard keyを利用したクエリ               Shard keyを利用しないクエリ

                      targeted                         global




Mongod (Shard A)	
               Mongod (Shard B)	
 データベース etcr	
                   データベース etcr	

 コレクション 行動履歴	
                   コレクション 行動履歴	


Chunk	
                          Chunk	
 docA	
   docB	
   docC	
         docD	
   docE	
   docF
クエリ insert/updateの話 (1)
•  fire and forget
   o  発火即忘却
       §  結果を確認せずreturnする
       §  結果を知りたければgetlasterrorオプションを指定


•  確実にcommitさせる
   o  データファイルにフラッシュさせる
       §  fsync: true
   o  2台のメンバーに書き込みが完了するまで待機(timeout:5000)
       §  db.getlasterror(2, 5000)
       §  db.getlasterror('majority')
クエリ insert/updateの話 (2)
•  ID値
   o  デフォルトでは、IDは自動で振られる
   o  ObjectId = BSON(
       [4byte timestamp] +
       [3byte hash(hostname)] +
       [2byte pid] +
       [3byte inc])

 // parseすれば時間やサーバーなどもわかる
 object_id = '4b0552b0f0da7d1eb6f12yyy’
 createdDt = new Date(parseInt(object_id.substr(0, 8), 16) * 1000)

 #=> Thu Nov 19 2009 23:14:08 GMT+0900 (JST)
クエリ insert/updateの話 (3)
•  Padding
  o  insert時に、パディング領域を確保している
       §  配列に追加されるなど、ドキュメントサイズが拡大しても高
           速にupdateするため(In-place update)

  o  Padding領域を越える更新
      §  ドキュメントの再配置が発生(遅い)
      §  増加性を持ったコレクションはPaddingサイズ調整が必要


•  Atomicな操作
  o  1つのドキュメントの更新に対して別のクエリをブロック
  o  トランザクションのACIDのA(atomic : all or nothing)ではない。
  o  sharding環境でサポートされない
クエリ removeの話
•  断片化
  o  削除時はドキュメントの再配置を行わないので断片化する

  o  repairコマンド
       §  同容量の空き領域が必要
       §  サーバー単位(sharding環境なら各shardで)

  o  compactコマンド
      §  より少ない空き領域で可能
      §  コレクション単位
      §  paddingも削除するので、増加性を持ったコレクションはデ
          フラグ後にupdateパフォーマンス悪化
困った話 - 1
•  flush前のデータロスト
 o  デフォルトでは60sに1回flushされるまではメモリで保持
     §  最大で60秒間のデータロストの可能性

 o  対策1 (∼ver1.8)
     §  60秒の設定を短縮する
     §  getlasterror()でflushさせる
        •  重くなる
 o  対策2 ジャーナルモード (ver1.8∼)
     §  ジャーナルログ(disc)に100msに1回書き込む
     §  flushと違い、データの更新先などを意識しないため早い
     §  起動時にJournalディレクトリがあれば復元し、正常終了時
         はディレクトリを削除する。
困った話 - 2
•  書き込み時(flush時)はDBロックする
 o  あまり問題にならないほど、書き込みは高速とのこと
     §  ほんまかいな


•  非効率なCPUリソース利用
 o  書き込み処理とMapReduceではシングルコアしか使えない
 o  読み込みは複数コアを使う
みんなが苦労しているのは
•  Shard key の決め方
  o  Chunkの移動があまり起こらないこと
  o  長期の運用でも綺麗に分散すること
  o  Shard keyを使って効率よく検索できること


•  Shard keyは一度決めると変えられない
•  Migration中の残念なパフォーマンスと不整合
Shard keyの考察 (うけうり)
•  [bad] 離散データ
  o  chunk分割できない
      §  例:都道府県コード
•  [bad] 単純インクリメントデータ
  o  最後のchunkのみが分割移動される
      §  例:連番
•  [bad] ランダム値
  o  十分に分散するまでは偏りがあるため、大きなchunkができる
      §  例:ハッシュ
•  [good] 緩やかに増加するキーと検索に利用するキーの組
 み合わせ
  o  検索利用キーでひと月かけて偏りが発生してくるが、ひと月たてば偏
     りがリセットされる
      §  例:yyyymm-owner_id
シンプルな解析PFの例
      Web	
   Web	
                              使ったことないものを
                            仕事で使ってみたいという想い	

        解析用サーバー	




日次増分をMap/
Reduceで集計	
                    認証機能が必要なため。
                    I/Oをjsonで一致させて
                      開発スピードアップ

More Related Content

What's hot (20)

PDF
コード読経会報告書
Masahiko Toyoshi
 
PDF
textsearch_jaで全文検索
Akio Ishida
 
PDF
Javaにおけるデータシリアライズと圧縮
moai kids
 
PPTX
SQLチューニング入門 入門編
Miki Shimogai
 
PDF
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
Takahiro Inoue
 
PPTX
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
Miki Shimogai
 
PDF
Chugokudb study-20150131
Toshi Harada
 
PDF
Shibuya Perl Mongers#12 No Sql Couch Db
Makoto Ohnami
 
PDF
2019年度若手技術者向け講座 インデックス
keki3
 
PPTX
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
NTT DATA Technology & Innovation
 
PDF
kintone dev camp 2016 spring
Akiyoshi Yamazaki
 
PDF
Webで役立つRDBの使い方
Soudai Sone
 
PDF
Rとcdisc@moss10 公開用
Masafumi Okada
 
PDF
2019年度 若手技術者向け講座 NoSQL
keki3
 
PDF
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
kasaharatt
 
PDF
Pgunconf 20121212-postgeres fdw
Toshi Harada
 
PDF
RとCDISC
Masafumi Okada
 
PDF
AutoDock_vina_japanese_ver.3.0
Satoshi Kume
 
PDF
とあるイルカのバーボンハウス
yoku0825
 
コード読経会報告書
Masahiko Toyoshi
 
textsearch_jaで全文検索
Akio Ishida
 
Javaにおけるデータシリアライズと圧縮
moai kids
 
SQLチューニング入門 入門編
Miki Shimogai
 
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
Takahiro Inoue
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
Miki Shimogai
 
Chugokudb study-20150131
Toshi Harada
 
Shibuya Perl Mongers#12 No Sql Couch Db
Makoto Ohnami
 
2019年度若手技術者向け講座 インデックス
keki3
 
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
NTT DATA Technology & Innovation
 
kintone dev camp 2016 spring
Akiyoshi Yamazaki
 
Webで役立つRDBの使い方
Soudai Sone
 
Rとcdisc@moss10 公開用
Masafumi Okada
 
2019年度 若手技術者向け講座 NoSQL
keki3
 
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
kasaharatt
 
Pgunconf 20121212-postgeres fdw
Toshi Harada
 
RとCDISC
Masafumi Okada
 
AutoDock_vina_japanese_ver.3.0
Satoshi Kume
 
とあるイルカのバーボンハウス
yoku0825
 

Similar to Mongodb 紹介 (20)

PDF
MongoDBざっくり解説
知教 本間
 
PDF
Introduction to MongoDB
moai kids
 
PDF
20120831 mongoid
Takeshi AKIMA
 
PPT
Mongodb
Satoru Mikami
 
PDF
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)
Akihiro Kuwano
 
PDF
DB tech showcase: 噂のMongoDBその用途は?
Hiroaki Kubota
 
PDF
mongodbの簡易ストレージ化
Hidetoshi Mori
 
PDF
MongoDBのアレをアレする
Akihiro Kuwano
 
PDF
MongoDB勉強会資料
Hiromune Shishido
 
PDF
MongoDB2.2の新機能
Shoken Fujisaki
 
PDF
ソーシャルゲームにおけるMongoDB適用事例 - Animal Land
Masakazu Matsushita
 
PDF
AmebaのMongoDB活用事例
Akihiro Kuwano
 
KEY
はじめてのCouch db
Eiji Kuroda
 
ODP
Mongo db勉強会
otmb
 
DOC
20110301 Mongo Tokyo
Kenichi Masuda
 
DOC
20110302 Mongo Tokyo
Kenichi Masuda
 
PPTX
Mongo db使ってみよう
Oda Shinsuke
 
PDF
ソーシャルゲームにおけるAWS/MongoDB利用事例
Masakazu Matsushita
 
PDF
MongoDBの使い方
Tatsuto Maetsu
 
MongoDBざっくり解説
知教 本間
 
Introduction to MongoDB
moai kids
 
20120831 mongoid
Takeshi AKIMA
 
Mongodb
Satoru Mikami
 
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)
Akihiro Kuwano
 
DB tech showcase: 噂のMongoDBその用途は?
Hiroaki Kubota
 
mongodbの簡易ストレージ化
Hidetoshi Mori
 
MongoDBのアレをアレする
Akihiro Kuwano
 
MongoDB勉強会資料
Hiromune Shishido
 
MongoDB2.2の新機能
Shoken Fujisaki
 
ソーシャルゲームにおけるMongoDB適用事例 - Animal Land
Masakazu Matsushita
 
AmebaのMongoDB活用事例
Akihiro Kuwano
 
はじめてのCouch db
Eiji Kuroda
 
Mongo db勉強会
otmb
 
20110301 Mongo Tokyo
Kenichi Masuda
 
20110302 Mongo Tokyo
Kenichi Masuda
 
Mongo db使ってみよう
Oda Shinsuke
 
ソーシャルゲームにおけるAWS/MongoDB利用事例
Masakazu Matsushita
 
MongoDBの使い方
Tatsuto Maetsu
 
Ad

Recently uploaded (10)

PDF
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
PDF
SIG-AUDIO 2025 Vol.02 オンラインセミナー SIG-Audioプレゼン資料_オーディオプラグイン開発_塩澤達矢.pdf
IGDA Japan SIG-Audio
 
PDF
ABC2025S LT講演「世界の窓から Androidこんにちは2025」アプリ自動生成の将来?ロボティクスの夢再び?
嶋 是一 (Yoshikazu SHIMA)
 
PDF
生成AIパネルトーク(Interop25Tokyo APPS JAPAN M1-07,M2-07 嶋ポジショントーク)
嶋 是一 (Yoshikazu SHIMA)
 
PDF
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
PDF
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
PDF
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
PDF
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 
PDF
20250630_aws_reinforce_2025_aws_sheild_network_security_director
uedayuki
 
PDF
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
SIG-AUDIO 2025 Vol.02 オンラインセミナー SIG-Audioプレゼン資料_オーディオプラグイン開発_塩澤達矢.pdf
IGDA Japan SIG-Audio
 
ABC2025S LT講演「世界の窓から Androidこんにちは2025」アプリ自動生成の将来?ロボティクスの夢再び?
嶋 是一 (Yoshikazu SHIMA)
 
生成AIパネルトーク(Interop25Tokyo APPS JAPAN M1-07,M2-07 嶋ポジショントーク)
嶋 是一 (Yoshikazu SHIMA)
 
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 
20250630_aws_reinforce_2025_aws_sheild_network_security_director
uedayuki
 
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
Ad

Mongodb 紹介

  • 2. MongoDBってなんぞ - 多機能 but 発展途上 •  ドキュメント指向データベース o  最新2.0.5 •  自動シャーディング o  Read / Writeがスケールアウト •  自動フェイルオーバー o  Master deadでも自動でフェイルオーバー •  柔軟なクエリ o  SQLで可能なことはJOIN句以外 一通りできる •  スキーマレス o  データによって自由に持つものを決められる 他にも多機能
  • 3. 構成例 Web Web mongos mongos 3processで 最小構成台数 最適化 3process data data meta mongod mongod Mongod (config) mongod mongod Mongod (config) mongod mongod Mongod Replica Replica (config) set set
  • 4. 基本的なデータの持ち方 MySQLで例えると mongod mysqld データベース etcr データベース コレクション 行動履歴 コレクション XXマスタ テーブル doc doc doc doc doc doc レコード doc doc doc doc データベース other コレクション 各種ログ doc doc doc
  • 5. レプリカセット - MySQL同様 Mongod (Primary) Mongod(Secondary) Mongod(Secondary) データベース etcr データベース etcr データベース etcr コレクション 行動履歴 コレクション 行動履歴 コレクション 行動履歴 docA docB docC docA docB docC docA docB docC docD docE docF docD docE docF docD docE docF 再現 再現 データベース local データベース local データベース local コレクション oplog コレクション oplog コレクション oplog 同 操作 操作 操作 期 操作 操作 操作 操作 操作 操作
  • 6. 自動フェイルオーバー •  Primaryが死ぬ •  Primaryが死んだことがreplica set内で共有 •  残ったノードで投票を行う •  ノードごとの優先度設定、最終同期時刻をもとに投票 を行う •  過半数より多くの票を集めたノードがPrimaryとなる •  この間 約20s ∼ 60s
  • 7. 自動シャーディング - phase1 Mongod (Shard A) Mongod (Shard B) データベース etcr データベース etcr コレクション 行動履歴 コレクション 行動履歴 Chunk ( –無限大 〜 無限大] docA docB docC デフォルト 200MB
  • 8. 自動シャーディング - phase2 Mongod (Shard A) Mongod (Shard B) データベース etcr データベース etcr コレクション 行動履歴 コレクション 行動履歴 Chunk ( –無限大 〜 D] docA docB docC Chunk ( D 〜 無限大] docD docE docF
  • 9. 自動シャーディング - phase3 Mongod (Shard A) Mongod (Shard B) データベース etcr データベース etcr コレクション 行動履歴 コレクション 行動履歴 Chunk ( –無限大 〜 D] docA docB docC docC’ docC’’ docC’’’ Chunk ( D 〜 無限大] docD docE docF
  • 10. 自動シャーディング - phase4 Mongod (Shard A) Mongod (Shard B) データベース etcr データベース etcr コレクション 行動履歴 コレクション 行動履歴 Chunk ( –無限大 〜 C’] docA docB docC Chunk (C’ 〜 D] docC’ docC’’ docC’’’ Chunk ( D 〜 無限大] docD docE docF
  • 11. 自動シャーディング - phase5 Mongod (Shard A) Mongod (Shard B) データベース etcr データベース etcr コレクション 行動履歴 コレクション 行動履歴 Chunk ( –無限大 〜 C’] Chunk ( D 〜 無限大] docA docB docC docD docE docF Chunk (C’ 〜 D] docC’ docC’’ docC’’’ 水平方向に スケールアウト
  • 13. スキーマレス •  Create table, Create column family 不要 o  Insertした時点で作られる o  アプリ要件に合わせて柔軟に入れられる Item1 = { _id: ObjectId('4b0552b0f0da7d1eb6f12xxx'), name: 秘薬, price: 100, } Item2 = { _id: ObjectId('4b0552b0f0da7d1eb6f12yyy'), name: 自分用秘薬, }
  • 15. クエリ 周辺の話 (1) • Index(B-Tree) o  配列やオブジェクトに対してもはれる § ただし、配列は1つ / indexに制限 o  メモリに乗るようにintを使うと吉 // indexをつける db.test.ensureIndex({x:1, y:1, z:1}) ○ db.test.find({x:'a'}) ○ db.test.find({x:'a', y:'b'}) ○ db.test.find({x:'a', y:'b'}).sort({z:1}) // 順序が重要 × db.test.find({y:'b', x:'a'})
  • 16. クエリ 周辺の話(2) • クエリオプティマイザ o MySQLのようなコストベースではない o 初回のクエリで複数クエリプランを同時実行 o  最も早かったクエリを利用 o  データ量に応じて定期的に見直し o  explain()
  • 17. クエリ 周辺の話(3) • Capped コレクション o  あらかじめサイズを決めたコレクション o  古いものから順次消えていく o  挿入順での検索で高速 o  Shardingできない o  削除不能 o  Create文を明示的に発行して作成 § db.createCollection("mycoll", {capped:true, size:100000})
  • 18. クエリ findの話 (1) •  検索条件は、bsonオブジェクトの先頭に寄せる 1. db.activityHistoryDemo.find({owner_id: 123}) 2. db.activityHistoryDemo.find({‘concerned.id’: ‘201’}) { owner_id: 123, request: { type: '合成', params: {}}, process: {category: 'composit'}, memo: ['lv.0 -> lv.15'], concerned: [ {io: 'i', type: 'card', id: 100, object: '111', base: true}, {io: 'i', type: 'card', id: 201, object: '222'}, {io: 'o', type: 'card', id: 100, object: '111'}, ] })
  • 19. クエリ findの話 (2) •  bsonオブジェクト階層を細分化したほうが早い db.activityHistoryDemo.find({‘concerned.id’: ‘201’}) { owner_id: 123, request: { type: '合成', params: {}}, process: {category: 'composit'}, memo: ['lv.0 -> lv.15'], concerned: [ {io: 'i', type: 'card', id: 100, object: '111', base: true}, {io: 'i', type: 'card', id: 201, object: '222'}, {io: 'o', type: 'card', id: 100, object: '111'}, ] })
  • 20. クエリ findの話 (3) •  条件の指定順序 o  And条件は結果の小さな条件から順次 §  補集合を無視するので。 ○ db.sample.find({owner_id: 123, ‘concerned.type’: ‘card’}) × db.sample.find({‘concerned.type’: ‘card’, owner_id: 123}) o  Or条件は結果の大きな条件から順次 §  後続条件は補集合から検索するので。 ○ db.sample.find({$or: [{‘concerned.type’: ‘card’}, {owner_id: 123}]) × db.sample.find({$or: [{owner_id: 123}, {‘concerned.type’: ‘card’}])
  • 21. クエリ findの話 (4) •  DBRef doc = { name: 'ryooo', card:[ {'$ref': 'card', '$id' : ObjectId('4b0552b0f0da7d1eb6f12xxx')}, ] } doc.card[0].fetch() // ←カードオブジェクトがとれる @ruby db = Connection.new.db(”etcr ") user_card = db["user_card"].save({:name => ”ryooo”, :card_id => 123}) ref = DBRef.new(”card", user_card.card_id) db.dereference(ref) #=> カードオブジェクト
  • 22. クエリ findの話 (5) •  検索条件に関数も使える(javascript) // 極端な話、こんなクエリも書けちゃいます db.cards.find(function(){ row = db.user_summary.findOne({owner_id: this.owner_id}) return this._id == row.leader_card_id; }) •  mongoサーバーサイドに関数を登録できる // 関数を登録 db.system.js.save({_id:’name', value: function (){ //implementation }}); f = db.system.js.findOne({_id:’name'}) // 検索で利用(fはサーバー側で実行される) Db.cards.find(f)
  • 23. クエリ findの話 (6) Shard keyを利用したクエリ Shard keyを利用しないクエリ targeted global Mongod (Shard A) Mongod (Shard B) データベース etcr データベース etcr コレクション 行動履歴 コレクション 行動履歴 Chunk Chunk docA docB docC docD docE docF
  • 24. クエリ insert/updateの話 (1) •  fire and forget o  発火即忘却 §  結果を確認せずreturnする §  結果を知りたければgetlasterrorオプションを指定 •  確実にcommitさせる o  データファイルにフラッシュさせる §  fsync: true o  2台のメンバーに書き込みが完了するまで待機(timeout:5000) §  db.getlasterror(2, 5000) §  db.getlasterror('majority')
  • 25. クエリ insert/updateの話 (2) •  ID値 o  デフォルトでは、IDは自動で振られる o  ObjectId = BSON( [4byte timestamp] + [3byte hash(hostname)] + [2byte pid] + [3byte inc]) // parseすれば時間やサーバーなどもわかる object_id = '4b0552b0f0da7d1eb6f12yyy’ createdDt = new Date(parseInt(object_id.substr(0, 8), 16) * 1000) #=> Thu Nov 19 2009 23:14:08 GMT+0900 (JST)
  • 26. クエリ insert/updateの話 (3) •  Padding o  insert時に、パディング領域を確保している §  配列に追加されるなど、ドキュメントサイズが拡大しても高 速にupdateするため(In-place update) o  Padding領域を越える更新 §  ドキュメントの再配置が発生(遅い) §  増加性を持ったコレクションはPaddingサイズ調整が必要 •  Atomicな操作 o  1つのドキュメントの更新に対して別のクエリをブロック o  トランザクションのACIDのA(atomic : all or nothing)ではない。 o  sharding環境でサポートされない
  • 27. クエリ removeの話 •  断片化 o  削除時はドキュメントの再配置を行わないので断片化する o  repairコマンド §  同容量の空き領域が必要 §  サーバー単位(sharding環境なら各shardで) o  compactコマンド §  より少ない空き領域で可能 §  コレクション単位 §  paddingも削除するので、増加性を持ったコレクションはデ フラグ後にupdateパフォーマンス悪化
  • 28. 困った話 - 1 •  flush前のデータロスト o  デフォルトでは60sに1回flushされるまではメモリで保持 §  最大で60秒間のデータロストの可能性 o  対策1 (∼ver1.8) §  60秒の設定を短縮する §  getlasterror()でflushさせる •  重くなる o  対策2 ジャーナルモード (ver1.8∼) §  ジャーナルログ(disc)に100msに1回書き込む §  flushと違い、データの更新先などを意識しないため早い §  起動時にJournalディレクトリがあれば復元し、正常終了時 はディレクトリを削除する。
  • 29. 困った話 - 2 •  書き込み時(flush時)はDBロックする o  あまり問題にならないほど、書き込みは高速とのこと §  ほんまかいな •  非効率なCPUリソース利用 o  書き込み処理とMapReduceではシングルコアしか使えない o  読み込みは複数コアを使う
  • 30. みんなが苦労しているのは •  Shard key の決め方 o  Chunkの移動があまり起こらないこと o  長期の運用でも綺麗に分散すること o  Shard keyを使って効率よく検索できること •  Shard keyは一度決めると変えられない •  Migration中の残念なパフォーマンスと不整合
  • 31. Shard keyの考察 (うけうり) •  [bad] 離散データ o  chunk分割できない §  例:都道府県コード •  [bad] 単純インクリメントデータ o  最後のchunkのみが分割移動される §  例:連番 •  [bad] ランダム値 o  十分に分散するまでは偏りがあるため、大きなchunkができる §  例:ハッシュ •  [good] 緩やかに増加するキーと検索に利用するキーの組 み合わせ o  検索利用キーでひと月かけて偏りが発生してくるが、ひと月たてば偏 りがリセットされる §  例:yyyymm-owner_id
  • 32. シンプルな解析PFの例 Web Web 使ったことないものを 仕事で使ってみたいという想い 解析用サーバー 日次増分をMap/ Reduceで集計 認証機能が必要なため。 I/Oをjsonで一致させて 開発スピードアップ