MongoDBと過ごした8年を振り返りながら、お気に入りのMongoDBマグカップで濃いめのモカを啜っています。
たのしくテンポの良い開発、フラグメンテーションとの長い夜、主語の大きいロック、星の数ほどのMongoDBステッカー、高嶺の花のMongoDB公式Tシャツなどが走馬燈のように目の裏を駆け巡ります。
今年6月、ついに昨年10月のNasdaq上場後初のメジャーバージョンアップであるMongoDB 4.0がリリースされました。
この成長著しいMongoDBにキャッチアップすべく、私fdkはMongoDB 4.0の探検に出かけました。*1
MongoDBについて
MongoDBは2007年より10gen(現MongoDB Inc.)により開発され、2009年の初版リリース以来、継続的にリリースを重ねているドキュメント指向データベースです。階層構造を表現できるドキュメントと呼ばれるデータ構造を、BSONという表向きはJSONによく似たバイナリ形式で格納します。高速なオペレーション、スキーマレス、透過的圧縮のサポート、レプリカセットによる冗長性とスケーラビリティなどが強みとして挙げられます。
一方で、これまでトランザクション機能がない点がアキレスの踵と囁かれていましたが、MongoDB 4.0の登場により、そのような通説は風と共に消え去ろうとしています。
MongoDB 4.0の主な新機能
1. Multi-document ACID transactions
これまでMongoDBでは、ドキュメント単位のアトミックな更新は実現されており、実用上多くの利用ケースでは十分とされていました。MongoDB 4.0では、複数ドキュメントにまたがるトランザクションが実装され、課金、予約、口座間の資金移動などの、トランザクションが求められる領域にも対応できるようになりました。
MongoDB 4.0ではRDB同様にトランザクションの制御をデータベース側でサポートしてくれるので、アプリケーション側での実装コストが削減できます。
トランザクションは複数ステートメントで記述するようになっており、そのためのAPIが用意されています。*2
以下、MongoDB 4.0のトランザクションについてのメモです。
- 単一もしくは複数のコレクションやデータベースに含まれるドキュメントに対して適用される
- Snapshot isolationにより、各トランザクションはデータの一貫性ビューを提供し、データの整合性を維持するall-or-nothing実行を強制する*3
- 実行中のトランザクション内では、自身の未コミットの書き込みは参照できるが、トランザクション外の操作からは一切見えない
- 未コミットの書き込みはトランザクションがコミットされるまでセカンダリのノードにレプリケーションされず、トランザクションがコミットされると自動的に全てのセカンダリセカンダリに複製され適用される
- 長いトランザクションや膨大な操作を伴う単一のトランザクションはストレージエンジンであるWiredTigerのキャッシュを圧迫する(スナップショット以降の全ての書き込みの状態を維持しなければならないため)
- デフォルトでは60秒を超えるとトランザクションは自動的にabortされる
- トランザクション内で読むことのできるドキュメント数の上限は無いが、1トランザクション内での更新は1000ドキュメント以内であることが推奨される
- トランザクションは単一のoplogエントリとして記録されるため、16MBのサイズ制限を受け(更新の場合は差分のみ、新規の場合はドキュメント全体がカウント対象となる)、これを超えた場合トランザクションはabortされ、rollbackされる
- トランザクションがabortされるとドライバに例外が返され完全にrollbackされるが、ネットワーク障害やプライマリ選出中などの一時的な障害を想定し、アプリケーション側で適宜リトライなどの実装をするべきである
- コミット操作時にエラーが発生した場合、ドライバは1度だけリトライする
- トランザクションを使用しない場合のオーバーヘッドは全く無い
トランザクション機能が追加されたことで、将来的にトランザクション制御が必要になるかもしれないというケースにもMongoDBは有効な選択肢となりそうです。
2. Aggregation Pipeline Type Conversions
MongoDBはスキーマフリーのため*4、データ構造について柔軟です。それゆえに、収集したデータをBIや機械学習で活用する際に、同一のエレメントで複数の異なる型のデータが存在しているケースがありえます。
そのようなケースで、集計パイプラインにおける型変換を、別途外部のETLプロセスを介することなくデータベース内で行う機能です。*5
具体的には$convertという演算子を使い、型の変換ルールを指定します。
{ $convert: { input: <expression>, to: <type expression>, onError: <expression>, // Optional onNull: <expression> // Optional } }
この機能を活用すると、データ分析において別途のETL処理を省くことができるため、複雑性やコストの低減が期待できます。
3. The aggregation pipeline builder
MongoDB CompassというGUIツールにより、MongoDB内のデータの構造の可視化、アドホックのクエリ実行、インデックスの作成、バリデーション規則の作成といったことができます。このツールで集計のパイプラインの構築を試行錯誤しながら行えるようになりました。
画面は、サンプルデータ*6 で前述の型変換を試しつつパイプラインを構築してみた様子。作成したパイプラインを名前付けして保存できます。
コード吐き出し機能があり、作成したパイプラインのコードを出力できます。現時点でPython3, Node, Java, C#の4言語に対応しています。
直感的で使いやすく、データの観察、データ分析、アプリケーション開発の助けとなるツールではないかと思います。
4. MongoDB Charts (β版)
MongoDB Chartsは、MongoDB専用のBIツールです。Docker Swarm上のコンテナで動作します。 Redashなど他のツールと同様にデータソースに接続し、データの美しい可視化、ダッシュボードの作成、共有ができます。
画面はローカルで起動したMongoDB Chartsで作成したダッシュボード。MongoDB Atlas上に作成したレプリカセットに接続し、テスト用に作成したサンプルデータでチャートを作成してみました。beta版のためチャート作成の細かい部分はまだこれからという印象です。
5. Non-Blocking Secondary Reads
MongoDB 4.0ではセカンダリからの読み出しとレプリケーションの書き込みが同時に実行できるようになりました。
MongoDBでは、プライマリで発生した書き込みはセカンダリに対してバッチ適用するようになっています。
よく言われるようにMongoDBは結果整合では無く、実際には一連の書き込みは各ノードで同じ順序で見えるように制御されます。
4.0より前のバージョンでは、順序を維持するため、セカンダリに対する読み出し要求はブロックされていました。つまり、oplogが適用されるのを待たされるケースが発生しており、書き込み負荷が大きいほど停止時間は長く、セカンダリからの読み出しレイテンシのメトリクスに悪影響を与えていました。
加えて、書き込み側は全ての読み出しの完了を待つロックを必要とし、セカンダリへの読み出し要求が多い時に、書き込みが遅延する原因となっていました。
MongoDB 4.0では、一貫性のあるスナップショットから読むことにより、セカンダリへの読み出し要求はoplogの適用中にブロックされず、またプライマリへのwrite concernがmajorityの書込みはロックの緩和により速く承認されるため、読み出の遅延とセカンダリの遅延を減らすと同時にレプリカセット全体のスループットが最大化されるとのことです。*7
6. SHA-2 Authentication
MongoDB 4.0では、認証メカニズムの強化として、SCRAM SHA-256が追加され、MONGODB-CRは廃止になりました。 MONGODB-CRスキーマでの認証を行なっている場合は、MongoDB 4.0へのアップグレードに先立ってSCRAM-SHA-1にアップグレードする必要があります。
企業のセキュリティポリシーにより、既に脆弱性の見つかっているSHA-1を使わないようにする必要がある場合、SCRAM SHA-1からSCRAM-SHA256へのアップデートが選択肢となります。 *8
7. The improved shard balancer
MongoDB 4.0では、シャード・バランサーの性能が、同時実行により最大40%向上し、より時機を得たスケールができるようになったとのことです。
*9
アップグレードについて
3.6系にアップグレードしてから4.0にアップグレードする必要があります。
これまで同様に、ローリングアップグレードができます。
SCRAM-SHA-256などいくつかの新機能を有効にするためにはfeatureCompatibilityVersionを4.0に変更する必要があります。 当然ですが、テスト環境での事前の検証が推奨されます。
まとめ
MongoDB 4.0の新機能を駆け足で見てきました。木を見て森を見るようにMongoDBの深淵を垣間見ることができました。
トランザクションの実装により守備範囲を広げ、データ分析や機械学習向けデータ処理パイプラインのサポート、BIツールの提供、そしてクラウド、モバイルを含むあらゆる場所での実行をサポートするというホリスティックでダイナミックな舵切りに期待が高まりました。
これからもMongoDBと歩み続けよう、と気持ちを新たにした一日でした。
*1:主にMongoDB 4.0のホワイトペーパーと、Mongo UniversityのオンラインコースM040の内容を参考にさせていただきました。
What's New in MongoDB 4.0 | MongoDB
MongoDB University - Learn MongoDB from MongoDB
*2:https://docs.mongodb.com/master/core/transactions/
*3:https://docs.mongodb.com/master/reference/read-concern-snapshot/
*4:Schema validation機能により、データ構造と型を強制することもできます https://docs.mongodb.com/master/core/schema-validation/#validation-rules
*5:https://docs.mongodb.com/manual/reference/operator/aggregation/convert/
*6:https://github.com/ozlerhakan/mongodb-json-files
*7:https://www.mongodb.com/presentations/wiredtiger-timestamps-enforcing-correctness-in-operation-ordering-across-the-distributed-storage-layer
*8:https://docs.mongodb.com/manual/core/security-scram/
*9:https://docs.mongodb.com/manual/core/sharding-balancer-administration/