satococoa's blog

主にサーバーサイド、Web 系エンジニアのブログです。Go, Ruby, React, GCP, ...etc.

第2回 MongoDB JP 勉強会 in Tokyoに参加してきた

MongoDB JP 勉強会 in Tokyoに参加してきました。 簡単に感想程度書いてみようと思います。

発表の感想

Sharding詳解

@doryokujinさん

Shardingについての前提知識がほとんど内容な状態で聞いてきましたが、その概要から問題点までよくわかりました。

大事なこととして挙げられたことは以下の2つ。

  1. Shard Keyの設定は非常に重要、慎重に
    一度設定すると基本的には変更できない。
    もし偏りが出たときにはMongoDBが自動的に是正するようにMigrationを行なってくれるが、
    処理が遅かったり、問題があるためになるべくならMigrationが起こらないようにすることが大事。
    (Migrationしないように設定することもできるそうですが、その場合偏りが起きたら手動でChunkを移動しないとならない。)
  2. Sharding環境におけるクエリは振る舞いがあやしい部分があるので要注意
    Migration中のcountが正しい値を返さなかったり、uniqueであるべき値が重複してしまう可能性があったり。

あと、ほとんど前提知識がない状態の僕が学べたことを箇条書きでつらつらと。

  • Sharding環境のMongoDBは3種類のサーバーで実現されている
    mongos, config, mongod
    mongosが仲介役をしてくれるので、アプリケーションからは普通にmongodにアクセスするのと同じ感覚でmongosにアクセスすればOK。
  • Chunkとは特定のCollectionの連続した範囲のデータ集合であり、データがどのChunkに属するかはShard Keyによって変わる
  • Chunkはデフォルトで200MBであり、それを超えると等分割される
  • Shard Keyの値は型がバラバラでもOK。MongoDBではすべての型を通して順番が決まっている
  • 特定のShardにChunkが集中してしまうと、Migrationが起こる
    MongoDBが自動的にバックグラウンドでやってくれるものではあるが、処理にかかる時間が非常に遅い
    また、Migration中はクエリの結果が怪しいことがある
  • Migrationの問題点
    • configサーバーへの負担
    • ネットワーク帯域の圧迫
    • メモリ領域の圧迫
    • パフォーマンスの低下
    • Migration中、クエリの結果を正しく返さない可能性がある
    • 低速
  • Shard Keyは「ゆるやかに増加するキー」+「検索でよく使われるキー」の複合が良い
  • Sharding環境でのクエリには2種類がある
    • Targeted
      Shard Keyが指定されることによって、必要なデータがあるShardのみにアクセスするクエリ
    • Global
      システム内のほぼすべてのShardにアクセスするクエリ
      (でもindexが効いていればそれほど速度低下するわけではない。)
    • どのようなクエリがTargetedになるのか、はShardingの紹介 - Docs-Japanese - 10gen Confluenceの「オペレーションタイプ」の表を参照
  • サーバーの構成はShardingの紹介 - Docs-Japanese - 10gen Confluenceの「サーバーレイアウト」の項目を参照

今日の話の多くはScaling MongoDBという本に書かれている内容らしく、さらに詳しい内容を知りたい方はこちらを読むことをおすすめされていました。

Type-safe MongoDB in Scala

@bibrostさん

Scala + Lift + Rogueでサービスを作られたそうで、MongoDBと組み合わせたときの利点をトイレの実装の例などを通して、笑いを交えながら説明してくださいました。

この組み合わせで開発するメリットとしては以下の4つを挙げていらっしゃいました。

  1. コンパイル時に型チェックされる
  2. アプリ側だけに定義を書けばいい
  3. クエリを使って検索ができる(しかも型安全に)
  4. プロパティを増やすときのコストが少ない

コードも多かったので、詳しい内容は直接資料をご覧になった方がいいと思います。

例えばRails + Mongoidでも「コンパイル時に型チェック・・・」以外は同じメリットを享受できると思いますので、
動的言語と比べたときの一番の利点は型チェックされることなんだと思います。

あと、実際に稼動しているシステムのCollection構成を教えていただいたのですが、どこまで正規化し、何をembedするか、という設計はやっぱり悩ましいところらしいです。

アクセスログをできるだけいろいろ見る時のmapreduce + ニフティクラウドでの構築とパフォーマンスを初心者からわかりやすく

@muddydixonさん

そもそもmapReduceを使っていないので、情けないことに正直あまりついていけなかったのですが、
重要そうなポイントだけメモ。

  • よくわからないデータをとりあえず突っ込んでおくのにはMongoDBは最適
    サービスを横断するログなどは必ずしも形式が一緒じゃないが、重要なところだけをある程度合わせて
    とりあえずインポートしておくことで、あとは必要になったときにはクエリでなんとかできる
  • MongoDBにおけるmapReduceはドキュメントに対して縦横無尽に検索をかけられるという特性を活かして、
    keyをきちんと考えるほうが良い。valueは数え上げに徹する方がいいかも。(実際、valueは1にすることが多い)
  • mapReduceを使うならShardingを使うとパフォーマンスがよくなる
    Shard毎に処理した結果をさらにまとめているから。
    その関係上、平均・最大・最小などを求めるときにはFinalizeを使わないと正しい値にならないが。
地理空間インデックスを利用したWebアプリケーション

@yamaneko1212さん

地理空間インデックスはかなり興味のあるところでした。(最近は位置情報を使ったアプリも多いですし。)

ある座標の「近く」を検索できるだけではなく、矩形内にあるかどうかを簡単に検索できるのもMongoDBのいいところですね。 注意点として、球体モデルを利用したい場合には座標を保存する際に緯度・経度の順番を間違えないように、ということをご指摘されていました。

{loc: [経度, 緯度]}

この辺の情報は公式のマニュアルも詳しいですね。 地理空間のインデックス - Docs-Japanese - 10gen Confluence

Tachy with MongoDB

@joe_hrmnさん

サイバーエージェントさんで開発しているTachyというアプリのお話でした。

MongoDBを使った理由を以下のように挙げていらっしゃいました。

  • 使ってみたかった
  • データ分散の処理は大変
  • データアクセスが高速(と聞いて)
  • 自動でfailover
  • ドキュメント形式の柔軟性

そして、使ってみて良かったことを以下のように述べていらっしゃいました。

  • Index重要
  • mongostatが役に立った
    Sar, vmstat, iostat
  • RDBのノウハウの流用が可能
    explain(MongoDBにもあるんですね)

こうして実戦投入して、その中で出会った問題点やその解決方法などを聞くことができるのは非常に有意義です。
まだまだMongoDBではこうした実例が少ないので、とても貴重な発表を聞くことができて嬉しかったです。

懇親会

お話をさせて頂いた方のほとんどがソーシャル系のお仕事をされていて、ソーシャルの勢いを感じました。
実際にMongoDBを実際のシステムに投入した方はまだ少ないようで、まずはログ解析などの社内で使う仕組みから・・・と考えている方が多いようでした。

僕の仕事はいわゆるBtoBのシステムなので、よっぽどRDBMSで難しい案件でも来ない限り仕事で使うことは無いと思います。
・・・何年先でしょう。

会場について

大崎にあるフューチャーアーキテクトさんのセミナールームを貸していただきました。
会場に着いたときに思わずツイートしてしまいましたが、受付がまるで観光地のホテルのような感じで、さらに内部にはバーがあったり、と軽くカルチャーショックを受けるようなすごいオフィスでした。

最後に

大変ためになる勉強会でした。実際に会社の仕事で使うのはまだ難しそうですが、個人的には次のアプリではぜひMongoDBを使って勉強してみたいな、と感じました。

スタッフの方々、発表者の方々、そして会場を貸してくださったフューチャーアーキテクトの方々、どうもありがとうございました。

つらつらと書いてみましたが、まだまだ僕自身MongoDBは勉強不足なので色々怪しいところがあるかもしれません。
間違って解釈しているところはぜひ教えてください!