センタデータに限らず大量のデータを高スループットで書き込みたい場合はRDBよりNoSQLのDBのほうが優れています。mongoDBはNoSQLの一つで、ドキュメント思考(雑に言うとスキーマ定義が不要でJSONをそのまま突っ込む感じ)のDBです。mongoDBはインデックスをサポートしているので、今回はmongoDBをdockerで立てる際にCollection(テーブルみたいなもの)とインデックスを設定する方法を記載します。
dockerイメージは公式を利用します。
ユーザとパスワードを設定する
公式のmongoDBイメージは次の環境変数が指定されれば初期化時にrootユーザとパスワードを設定してくれます。Dockerfileかdocker-compose.ymlに次の環境変数=”設定値”を記載するだけでOKです。
- MONGO_INITDB_ROOT_USERNAME
- MONGO_INITDB_ROOT_PASSWORD
初期化スクリプトの記載・利用
Dockerイメージの「/docker-entrypoint-initdb.d/」配下にshかjsファイルを格納すると初回起動時に実行してくれます。どんな処理が実行できるかはリファレンスを参照してください。例えば次のようなことが可能です。
// ユーザを作成する
db.createUser({user情報JSON})
// Collectionを作成
db.createCollection('my_collection')
このときの「db」オブジェクトはデフォルトでは「test」というDBを示します。別のDBにしたい場合はDockerイメージ内の環境変数で指定します。
- MONGO_INITDB_DATABASE
ちなみに初回起動時にShellなりJavascriptが実行されるのは、Dockerコンテナ起動時に「docker-entrypoint.sh」というshellが実行されるからです。中身を見るとわかるのですが、「/docker-entrypoint-initdb.d/」配下の全ファイルを見て、.shか.jsで終わっていたら実行する感じになってます。色々事前に処理したい場合は1ファイルに書く必要はありません。(ただ、実行順序は意識したほうが良いかも)
Collectionとインデックスを作成する
以上を踏まえて次のJavascriptファイルとdocker-composeファイルを用意しておけばインデックス付きのCollectionが作成できます。ついでに確認用にmongo-expressというGUIツールも導入します。PostgreSQLは初めからずっとCLIで使っていたのでpgAdmin使ったこと無いのですが、初めて使うDBはやはりGUIで確認できると理解が早い気がします。
【init-mongo.js】
db.createUser(
{
user: "root",
pwd: "passwd",
roles: [
{
role: "readWrite",
db: "weather_sonsor"
}
]
}
)
db.createCollection('raw_data')
db.raw_data.createIndex({'create_time': 1})
【docker-compose.yml】
version: '2'
services:
mongo:
image: 'mongo'
environment:
# ユーザを作って初期化スクリプトで利用するDBを指定する
- MONGO_INITDB_DATABASE=weather_sensor
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=passwd
volumes:
# 初期化スクリプトを指定のディレクトリにコピー.ついでにvolumeのマウント
- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
- ./mongo-volume:/data/db
ports:
- '30001-30010:27017'
networks:
- analytics_pf
mongo-express:
image: mongo-express
ports:
- '31001:8081'
networks:
- analytics_pf
environment:
# 管理画面に入るユーザ・パスワードと、参照するmongoの情報
ME_CONFIG_BASICAUTH_USERNAME: admin
ME_CONFIG_BASICAUTH_PASSWORD: passwd
ME_CONFIG_MONGODB_PORT: 27017
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: passwd
depends_on:
- mongo
networks:
analytics_pf:
external: true
docker-compose でコンテナを起動すれば「localhost:31001」で管理画面に入って、weather_sensorというDBにraw_dataというCollectionがあって、インデックスとしてcreate_timeが指定されていることが確認できます。
※mongoDBのCollectionにはデフォルトで「_id」というユニークな自動生成カラムがインデックスとして設定されているので、もしそのカラムをインデックスとして使いたくない場合は削除する処理も必要になります。
以上です。一応docker-compose.ymlでmongoのportsが’30001-30010:27017’と指定されているので、複数コンテナ起動することができますが、あまり意味がありません。mongoDB公式でprimary, secondaryを指定して、フェイルオーバー構成を組む方法があるのでいずれそちらに挑戦しようと思います。