DockerでmongoDB起動時にインデックスを生成する

センタデータに限らず大量のデータを高スループットで書き込みたい場合は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を指定して、フェイルオーバー構成を組む方法があるのでいずれそちらに挑戦しようと思います。


カテゴリー:AnalyticsPf,docker

Output不足なエンジニア

統計が好きになれず、機械学習やったら必然的に統計が必要になるだろうと思ったら想像以上に機械学習にハマる。数学は芸術なので商売にするつもりはないけど、DeepLearningは数学じゃないし商売にしたいと思っているところ。画像処理がメイン。