MongoDB 3.2 リリースノート説明

MongoDB 3.2が12月8日にリリースされました。

https://docs.mongodb.org/manual/release-notes/3.2/

リリースノートの要点を説明します。リリースノートの原文に従って、上から順番に説明しています。

# リリースノートの説明

## WiredTigerがデフォルトに

MongoDB 3.0では従来のMMAPベースのストレージエンジンがデフォルトでしたが、3.2からはWiredTigerがデフォルトになりました。WiredTigerの特徴については別投稿である[「WiredTigerにすると嬉しいこと」](http://qiita.com/fetaro/items/050a20f695652c6acc94)を参照してください。

## レプリケーションのフェイルオーバ時のプライマリ選出高速化

レプリケーションにおいて、プライマリがダウンすると、残ったセカンダリでプライマリを選出しますが、この選出にかかる時間が、プロトコルのバージョンアップにより速くなりました。

## configサーバ群がレプリカセットで組めるようになった

今まではconfigサーバはmongod 3台で2PC(2フェーズコミット)で更新するアーキテクチャでしたが、今後は普通のレプリカセットでconfigサーバを構築するようになります。これにより、通常のレプリカへと同じように扱うことができるメリットがあるとともに、configサーバを3台より多く増やすことができます。

## 読み込み保証オプション(Read Concern)

今までレプリカセットの読み込み負荷分散では、どこか一台から、そのノードにある最も最新のデータを読む動きでしたが。このとき読むデータは、レプリカセットの半数以上に書かれていることが保証されていないため、レプリカセットのの壊れ方によっては失われてしまうデータかもしれませんでした。もし、クラスタとして失うことが「正」であるデータを読んでしまうと、アプリケーションに不整合が起こる可能性があります。

そこで、Read Concernという仕組みが導入され、readConcernに`majorityy`と指定すると、~~レプリカノードの過半数にデータが書き込まれている場合に限り読み込みに成功し、そうでないならロールバックする動きとなります~~レプリカノードの過半数にデータが更新されるのを待って読みます。これにより確実にクラスタとして保持されることが保証されるデータだけを読むことができます。

> [公式のドキュメント](https://docs.mongodb.org/manual/reference/read-concern/)には、`majority`を指定して読んだデータは、rolled backされることはないと書いてあります。このrolled backとはMongoDB用語なので注意が必要です。rollbackは、プライマリに書かれた更新がセカンダリに反映する前にプライマリがダウンし、その後セカンダリがプライマリに昇格して元のプライマリとは別の更新を開始し、その後ダウンしたノードがリカバリしたときに、プライマリにしかない独自の更新は破棄されます。この「プライマリにしかない独自の更新は破棄」がrolled backという動きになります。

## 部分的インデックス

ドキュメントの中のある値の条件よって、そのドキュメントをインデックスに含めるかどうかを分けれるようになります。

例えば、ユーザドキュメントの中にアクティブ化非アクティブ化のフラグがあり、アクティブなユーザしか検索しない要件であれば、非アクティブのフラグのデータはインデックスに含めないことができ、これによりメモリを効率的に利用できます。

条件の指定は、値の確認だけでなく、値の存在や、値の型によってもできます。

## ドキュメントバリデーション

ドキュメントの中身にバリデーション(キー名や値のチェック)がかけられるようになります。

例えば、`{ age : { $gte : 0, $lte : 150 } }`というバリデーションドキュメントをコレクションに設定することにより、ageが0～15の間の数値であるドキュメントしかインサートさせないようにできます。

> 今まではスキーマレスを売りにしてきたが、やはり場合によってはスキーマが重要視されるため、ハイブリッドの戦略をとってきたようです。(筆者所感)

## アグリゲーションフレームワークの改良

アグリゲーションフレームワークに沢山のオペレータが追加されました。その中から一つだけ紹介しましょう。

一つ目は`$lookup`というパイプラインのステージが導入されました。これはSQLのLEFT OUTER JOINのようなもので、他のコレクションから紐づくデータを結合することができます。

>ただしこの結合はRDBMSの結合とは異なり、他のクエリから分離されたものではないと思われます。つまりアグリゲーションフレームの実行中に、結合先のテーブルが更新されたら、その影響を受けるでしょう。(筆者所感)

二つ目は、フレームワークの動作が最適化されたことです。まずはインデックス内にデータがあればそれを使いドキュメントにはアクセスしないように変更になりました。また、今まではアグリゲーションパイプラインが分割されるとプライマリシャードという特別なシャードでマージが必要で、そこに負荷がかかっていましたが、それがなくなりプライマリシャードがボトルネックになることが回避できるようになりました。

ただし`$out`と`$lookup`は依然としてプライマリシャードを使うようです。

## mongodumpとmongorestoreが圧縮&ストリーム転送対応

mongodumpとmongorestoreが圧縮に対応しました。さらに、リモートのmongodに対してdumpしたデータをストリームで転送しrestoreすることができるようになりました。

## 暗号化対応のWiredTigerストレージエンジン

WiredTigerを暗号化できるようになります。これは HIPAA, PCI-DSS, FERPAといったセキュリティの標準化に準拠しています。ただし、有償のEnterprise版のみで利用できます。


## 全文検索の改善

全文検索が英語以外に対応しました！が、残念ながら日本語は対応していません。
追加された言語はアラビア語、ペルシャ語、ウルドゥー語、中国語です。そして、有償のEnterprise版のみで利用できます。

ほかにもいくつか改善がありますが省略します。

## インメモリストレージエンジン

ディスクIOを行わないインメモリストレージエンジン`inMemory`が選べるようになりました。ただし、有償のEnterprise版のみで利用可能です。しかもまだベータ版です。

## テスト用ストレージエンジン

テストで毎回データをクリアしなくてよい、テスト用のストレージエンジン`ephemeralForTest`が選べるようになりました。ただしベータ版です。

## その他のエンハンス

### ビットをテストするオペレータの追加

### JavascriptのエンジンがまたSpidermonkeyに

今はJavascriptのエンジンはV8ですが、Spidermonkeyになるようです。

たしか2.4でSpidermonkeyからV8にしているので、戻ったことになります。

### MongoShellの新しいCRUDのAPI

今までのCRUDは、一回のクエリで更新されるドキュメントの数が一つだったり複数だったりでわかりにくかったので、新しいAPIが追加されました。

例えば、`update()`であれば、一つを更新する`updateOne()`や複数を更新する`updateMany()`を代用できます。

他にも`findAndModify()`もわかりにくかったんで、更新と置換と削除の３つの代用APIができてます。

### WiredTigerがfsyncでロックできるようになった

バックアップなどで静止点を作りたいときに使う。

### 32bitバイナリが非推奨になった。

### 地理空間インデックスの最適化

### 診断用データを取る仕組みの導入

デフォルトで1秒ごとに診断用データ(Diagnostic Data)がとられるようになった。データはデータフォルダにファイルとして出力される。

### Write Concernの仕様がちょっと変わった

### journalCommitIntervalのオプションがWiredTigerでも使えるようになった

# 所感

アプリ観点だと、ドキュメントバリデーションと部分的インデックス、そしてアグリゲーションフレームワークのJOINが大きいところでしょう。

基盤観点だと、mongodumpとmongorestoreの改良が地味にうれしいでしょう。あとはアグリゲーションを多用している場合はプライマリシャードのボトルネック問題解消は大きいかもしれません。

事前のアナウンスだとBIツールとの連携がされるとか言ってたんですが、結局盛り込まれませんでしたね。

全体的にかゆいところに手が届くリリースだったと思います。