MongoDB On EC2を試してみる

2016.06.23

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

クラメソダー市田です。

今回は、MongoDB on EC2についてです。
目的としては、MongoDBのレプリカセットをアマゾンで紹介されていた方式で構築してみることなんですが、何回かに分けて書かせていただこうと思います。

概要

初回はAmazon Linux単体にMongoDB Community Editionをインストールして、データの登録や簡単な操作方法までを確認してみたいと思います。

公式ページの通りにやれば問題なくインストールできると思いますが、試しにやってみます。
なお、使ったAmazon Linuxは「Amazon Linux 2016.03.2 (HVM)」です。

MongoDBの種類

MongoDBにはエンタープライズエディションとコミュニティエディションがありますが、大きな機能差がある訳ではないので、今回はコミュニティエディションをインストールしたいと思います。

ちなみに、エンタープライズエディションだと、主に次のような違いがあります。

  • マネジメントサービスが利用できる(バックアップや監視ソリューション)
  • SNMPモニタリングができる
  • KerberosやLDAP認証が利用できる
  • TableauなどのBIツールと連携可能な「MongoDB Connector for BI」が使える(Ver3.2以上)
  • スキーマビジュアライゼーションツール「MongoDB Compass」が使える
  • インメモリストレージエンジンが使える(Ver3.2.6以上)
  • 公式サポートやトレーニングが受けられる

何気に「MongoDB Connector for BI」なんか気になりますね。

参考ぺージ:

MongoDBをAmazon Linuxにインストール

MongoDBの公式サイトにはディストリビューション毎に詳細なマニュアルがあり、Amazon Linuxも独立した項目として記載されています。
今回は下記の公式ページの内容に従ってMongoDBをインストールしていきたいと思います。

Install MongoDB Community Edition on Amazon Linux — MongoDB Manual 3.2

他のOSだと、RHEL、SUSE、Ubuntu、Debian、OS X、Windowsのインストールマニュアルがあります。
もちろんTarballからインストールする方法も記載されています。

Yum設定

MongoDBのインストールは、公式のYumレポジトリからインストールします。
まずは、レポジトリファイルを/etc/yum.repos.d/mongodb-org-3.2.repoとして作成します。

今回は最新のStableバージョンをインストールします。
同様の手順で3.0よりも以前のバージョンをインストールできるリポジトリもあるようですので、必要に応じて使い分けてもらえればと思います。

[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc

MongoDBと関連ツールのインストール

yumでインストールします。
パッケージのバージョンを明示的に指定することで特定バージョンをインストールすることも可能なようですが、今回は特に指定せず最新のものをインストールします。

$ sudo yum install -y mongodb-org

同時にmongo shellなどの関連パッケージもインストールされます。

  • mongodb-org-mongos
  • mongodb-org-server
  • mongodb-org-shell
  • mongodb-org-tools

mongodb-org-toolsには、データをバックアップするためのmongodumpやステータス状況を見れるmongostatなどのMongoDBを使う上での便利ツールが含まれています。

MongoDBの起動

起動

インストールが完了したら起動します。

$ sudo service mongod start

停止や再起動もおなじみのコマンドです。

# 停止
$ sudo service mongod stop

# 再起動
$ sudo service mongod restart

無事に起動できていたら、/var/log/mongodb/mongod.logに下記のようなログが出ています。

[initandlisten] waiting for connections on port 27017

27017はMongoDBのデフォルトポートです。変更する場合は、/etc/mongod.confで指定します。

自動起動する設定も忘れないようにします。

$ sudo chkconfig mongod on

各種設定など

MongoDBのデフォルトでは/var/lib/mongoがデータファイルで、/var/log/mongodbがログファイルになります。実行ユーザはmongodとなります。
これらを変更する場合は、/etc/mongod.confを編集することになります。
また、実行ユーザを変える場合は、/var/lib/mongo/var/log/mongodbのアクセス権限も修正が必要になります。

アンインストール

Yumによるアンインストールです。
プロセスを止めて、パッケージマネージャで削除し、データファイルも削除します。

$ sudo service mongod stop
$ sudo yum erase $(rpm -qa | grep mongodb-org)
$ sudo rm -r /var/log/mongodb
$ sudo rm -r /var/lib/mongo

データ登録

今後レプリカセットを作るので、事前にテストデータを登録しておくことにします。
データ登録にはmongoシェルを使ってインタラクティブに行います。
今回は「myms」というデータベースを作成し、テーブルに相当するコレクション名は「msinfo」とします。

mongoシェルの起動

mongoシェルの起動は簡単です。

$ mongo

起動時にwarningのメッセージが出るかもしれませんが、warningを消す方法は最後の方に書いていますので、気になる方は設定してみてください。

データベースの作成

これも簡単です。次の内容だけで「myms」という名前のデータベースが作成できます。

> use myms
switched to db myms

ドキュメント(レコード)の登録

当たり前ですが、最初は何もありません。

> db.stats()
{
    "db" : "myms",
    "collections" : 0,
    "objects" : 0,
    "avgObjSize" : 0,
    "dataSize" : 0,
    "storageSize" : 0,
    "numExtents" : 0,
    "indexes" : 0,
    "indexSize" : 0,
    "fileSize" : 0,
    "ok" : 1
}

レコードに相当するドキュメントの登録は下記のようにdb.(コレクション名).insert();という形で登録します。
今回は以下の4件を登録しておくことにします。(内容に深い意味はありません。)

> db.msinfo.insert({ "name" : "ZAKU", "color" : "green", "height" : 1750 , "state" : "EFSF", "pilot" : [ "Cucuruz Doan" ]});
> db.msinfo.insert({ "name" : "GOUF", "color" : "blue", "height" : 1870 , "state" : "Zeon", "pilot" : [ "Ramba Ral" ]});
> db.msinfo.insert({ "name" : "ReZEL", "color" : "blue", "height" : 2050 , "state" : "EFSF", "pilot" : [ "Riddhe Marcenas" ]});
> db.msinfo.insert({ "name" : "KSHATRIYA", "color" : "green", "height" : 2230, "state" : "NeoZeon", "pilot" : [ "Marida Cruz" ]});

では、登録できたか確認してみます。

> db.msinfo.find()
{ "_id" : ObjectId("576ab03ea181f0b69fa75a38"), "name" : "ZAKU", "color" : "green", "height" : 1750, "state" : "EFSF", "pilot" : [ "Cucuruz Doan" ] }
{ "_id" : ObjectId("576ab044a181f0b69fa75a39"), "name" : "GOUF", "color" : "blue", "height" : 1870, "state" : "Zeon", "pilot" : [ "Ramba Ral" ] }
{ "_id" : ObjectId("576ab049a181f0b69fa75a3a"), "name" : "ReZEL", "color" : "blue", "height" : 2050, "state" : "EFSF", "pilot" : [ "Riddhe Marcenas" ] }
{ "_id" : ObjectId("576ab04ea181f0b69fa75a3b"), "name" : "KSHATRIYA", "color" : "green", "height" : 2230, "state" : "NeoZeon", "pilot" : [ "Marida Cruz" ] }

検索

検索では比較演算子も使えます。
試しに機体色が緑色のMSを検索してみます。

> db.msinfo.find({color:'green'})
{ "_id" : ObjectId("576ab03ea181f0b69fa75a38"), "name" : "ZAKU", "color" : "green", "height" : 1750, "state" : "EFSF", "pilot" : [ "Cucuruz Doan" ] }
{ "_id" : ObjectId("576ab04ea181f0b69fa75a3b"), "name" : "KSHATRIYA", "color" : "green", "height" : 2230, "state" : "NeoZeon", "pilot" : [ "Marida Cruz" ] }

次に、全高(height)が2000cm以上のMSを検索してみます。

> db.msinfo.find({height:{$gte:2000}})
{ "_id" : ObjectId("576ab049a181f0b69fa75a3a"), "name" : "ReZEL", "color" : "blue", "height" : 2050, "state" : "EFSF", "pilot" : [ "Riddhe Marcenas" ] }
{ "_id" : ObjectId("576ab04ea181f0b69fa75a3b"), "name" : "KSHATRIYA", "color" : "green", "height" : 2230, "state" : "NeoZeon", "pilot" : [ "Marida Cruz" ] }

その他のクエリやmongoシェルの操作方法については公式サイトに詳しく書かれています。

The mongo Shell — MongoDB Manual 3.2

コレクションの消去

コレクションのデータを全て消去したい場合は次のようにします。

> db.(コレクション名).remove({});

バージョンが2.Xのものはdb.(コレクション名).remove();で消すことができます。Ver3.Xとは異なるようです。

mongoシェル起動時のwarningを消す

先ほども書きましたが、mongoシェルを起動した際に、Amazon Linuxでは下記のようなエラーが出ました。

[initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
[initandlisten] **        We suggest setting it to 'never'

これはMongoDBの公式ぺージに説明があります。

Disable Transparent Huge Pages (THP) — MongoDB Manual 3.2

ここの記載では、おおよそ下記の様な説明が書かれています。

  • Transparent Huge Pages (THP)というメモリ管理の仕組みをLinuxは持っている。
  • これは、TLB(Translation Lookaside Buffer)ルックアップのオーバーヘッドを減らす為にある。
  • しかし、THPによってデータベースのパフォーマンスが落ちることがある。
  • なぜならデータベースは、連続したメモリアクセスよりも、まばらなメモリアクセスの方が多い傾向があるからである。
  • その為、MongoDBで最高のパフォーマンスを出す為にTHPは無効にした方が良い。

(英語訳に誤りがあればご指摘頂ければ幸いです。)

THPの無効化

無効化の手順も同じページに書かれています。

まず、下記のinitスクリプトを/etc/init.d/disable-transparent-hugepagesとして作ります。

#!/bin/sh
### BEGIN INIT INFO
# Provides:          disable-transparent-hugepages
# Required-Start:    $local_fs
# Required-Stop:
# X-Start-Before:    mongod mongodb-mms-automation-agent
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Disable Linux transparent huge pages
# Description:       Disable Linux transparent huge pages, to improve
#                    database performance.
### END INIT INFO

case $1 in
  start)
    if [ -d /sys/kernel/mm/transparent_hugepage ]; then
      thp_path=/sys/kernel/mm/transparent_hugepage
    elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
      thp_path=/sys/kernel/mm/redhat_transparent_hugepage
    else
      return 0
    fi

    echo 'never' > ${thp_path}/enabled
    echo 'never' > ${thp_path}/defrag

    unset thp_path
    ;;
esac

実行権限をつけます。

$ sudo chmod 755 /etc/init.d/disable-transparent-hugepages

OS起動時に実行されるようにしておきます。

$ sudo chkconfig --add disable-transparent-hugepages

先ほどのスクリプトを実行します。

$ sudo service disable-transparent-hugepages start

反映させる為にMOngoDBも再起動します。

$ sudo service mongod restart

これで次からmongoシェルを起動してもwarningは出なくなります。

以上になります。

次回は、「MongoDBレプリカセット On EC2」を試してみたいと思います。