MongoDB Enterprise Advanced:In-MemoryストレージエンジンのWriteパフォーマンスを検証する

2017.07.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、菊池です。

MongoDBの商用ライセンスであるMongoDB Enterprise Advancedの機能の1つ、In-Memoryストレージエンジンについて、構築手順を紹介しました。

今回は、In-Memoryストレージエンジンの書き込み性能を、他のストレージエンジンと比較してみました。

Writeパフォーマンス検証

検証環境

MongoDB Enterprise

  • インスタンスタイプ:r4.xlarge(vCPU:4、メモリ:30.5GB)
  • OS:Amazon Linux AMI 2017.03.1
  • データストレージ:
    • EBSタイプ:GP2
    • 容量:100GB
    • ファイルシステム:xfs
  • MongoDB Enterprise
    • バージョン:3.4.6

クライアント

  • インスタンスタイプ:t2.xlarge(vCPU:4、メモリ:16GB)
  • OS:Amazon Linux AMI 2017.03.1

検証方法

クライアントから、ツールを使って書き込みを実行。ツールは以下を参考にさせて頂きました。

MongoDB側は、In-Memory/WiredTiger/MMAPv1の各ストレージエンジンで用意します。1KBのデータを100セッション/100多重で5,000,000件書き込み、その時間を測定しました。

$ go run mongo_bench.go 100 100 100000

各ストレージエンジンの設定は以下の通りです。

  • In-Memory
storage:
  engine: inMemory
  dbPath: /data
  inMemory:
    engineConfig:
      inMemorySizeGB: 10
  • WiredTiger
storage:
  dbPath: /data
  journal:
    enabled: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 10
    collectionConfig:
      blockCompressor: snappy
  • MMAPv1
storage:
  dbPath: /data
  journal:
    enabled: true
  engine: mmapv1

結果

テスト結果は以下のようになりました。

ストレージエンジン 書き込み性能(write/sec)
In-Memory 49,530
WiredTiger 45,397
MMAPv1 19,224

Diskへの書き込みが不要なIn-Memoryがもっともパフォーマンスがよく、次にWiredTigerが続く結果となりました。In-Memoyに比較して、データ圧縮やDiskフラッシュが必要なWiredTigerも大きく劣るわけではなく、優秀な結果です。

一方、MMAPv1は他の2つに比べてかなり下がる結果です。MMAPv1は、コレクションレベルロック(バージョン2.x以前はDBレベルロック)であるため、多重書き込み時にはロック待ちが多くなるのと、非圧縮のためにDiskフラッシュ時の書き込み量が多くなるためと推測します。

また、それぞれのストレージエンジンで、書き込み完了後のdb.stats()を確認しました。

  • In-Memory
MongoDB Enterprise > db.stats()
{
       	"db" : "test",
       	"collections" : 1,
       	"views" : 0,
       	"objects" : 5000000,
       	"avgObjSize" : 1000,
       	"dataSize" : 5000000000,
       	"storageSize" : 5000000000,
       	"numExtents" : 0,
       	"indexes" : 1,
       	"indexSize" : 90579120,
       	"ok" : 1
}
  • WiredTiger
MongoDB Enterprise > db.stats()
{
       	"db" : "test",
       	"collections" : 1,
       	"views" : 0,
       	"objects" : 5000000,
       	"avgObjSize" : 1000,
       	"dataSize" : 5000000000,
       	"storageSize" : 736706560,
       	"numExtents" : 0,
       	"indexes" : 1,
       	"indexSize" : 50180096,
       	"ok" : 1
}
  • MMAPv1
MongoDB Enterprise > db.stats()
{
       	"db" : "test",
       	"collections" : 3,
       	"views" : 0,
       	"objects" : 5000004,
       	"avgObjSize" : 1007.9992448006042,
       	"dataSize" : 5040000256,
       	"storageSize" : 5297836032,
       	"numExtents" : 25,
       	"indexes" : 1,
       	"indexSize" : 168695408,
       	"fileSize" : 8519680000,
       	"nsSizeMB" : 16,
       	"extentFreeList" : {
       		"num" : 0,
       		"totalSize" : 0
       	},
       	"dataFileVersion" : {
       		"major" : 4,
       		"minor" : 22
       	},
       	"ok" : 1
}

In-Memoryでは、dataSize、storageSizeがオブジェクトサイズ x オブジェクト数で一致しており、非圧縮でメモリ上にデータを保持しているようです。WiredTigerではdataSizeに対しstorageSizeがかなり小さく、圧縮が効いていることがわかります。一方でMMAPv1ではstorageSizeが書き込み量よりも多く、さらに、fileSizeがかなり大きく取られています。

まとめ

以上です。

In-Memoryが高速なのは予想通りでしたが、それ以上に書き込みにおいてはWiredTigerが非常に優秀だという印象を持ちました。次は各ストレージエンジンでReadパフォーマンスを調査してみたいと思います。