電力サービスでのMongoDB運用

2018年02月13日 火曜日

「電力サービスでのMongoDB運用」のイメージ

Engineers Blogでは初めまして、藤本です。
IIJが運営している他のブログ、「Bルートブログ」では何度か記事を書かせていただいています。

普段の業務はwebサービスの開発・運用がメインで、数年前から開始している「Bルート活用サービス」を担当しています。

各家庭や工場などのスマートメーターから電力データを収集するサービスで、まとめて「電力サービス」などと呼んでいます。
上記サービスでは電力データを貯めるデータベースとして MongoDB を開発時から運用しており、
今回はこの電力サービスでの MongoDB 運用についてあれこれ書きたいと思います。

電力サービスについて

まず始めに電力サービスについて簡単に紹介したいと思います。

このサービスはスマートメーターから電力データを取得する検針端末と、
検針端末から送られてくる電力データを保存・可視化するwebアプリで成り立っています。

検針端末から送られてくるデータは主に以下のようなものです。

  • 瞬時電力量 (30 ~ 60秒ごと)
  • 予測電力量(60秒ごと)
  • 定時電力量(30分ごと) * 2
    • 消費電力量と売電力量などの2種類
  • keepalive
    • 端末の接続断検知用

他にも色々ありますが、上記のような時系列データを保存するためのデータベースとして、MongoDBを利用しています。

(ちなみに時系列でない契約情報などのデータは、お堅くMySQLに保存しています)

MongoDB

MongoDBはMongoDB社(ややこしい)によって開発されている、いわゆるNoSQLと呼ばれるDBで、その中でもドキュメント指向型に分類されます。
ドキュメント指向型はXMLやJSONといったドキュメントを保存する機能を持つDBであり、MongoDBはJSONドキュメントを保存することからこう呼ばれます。

そのJSON繋がりかJavaScriptと親和性が高いように思われ、shellでクエリを書く際もJavaScriptライクな記法で書きます。
また MongoDB + Express + AngularJS + Node.js で合わせて「MEANスタック」と呼ばれるほど、webアプリケーション開発でよく利用されています。

主な機能は 公式ドキュメント にもありますが、あえて特徴をまとめると

  • スキーマレス(当然?)
  • 複合indexに対応
  • レプリケーションと自動フェイルオーバーによる冗長化
    • =レプリカセット
  • shardingでの負荷分散
  • RDBっぽく使えるNoSQLとよく言われる
    • RDBの概念が結構そのまま通用する
    • トランザクション機能がNoSQLでは比較的強力
  • プロトタイプの開発に便利

あたりでしょうか。

上記の特徴がそのまま採用利用にもなりますが、後から考えると何よりDBとして「できないこと」が少なく、indexの貼り方や構成を変更したり、aggregationを導入したりとアプリケーションの変化に耐えうる柔軟さが大きかった気がしています。

アーキテクチャ

簡単にですが、電力サービスにおけるMongoDBホストのアーキテクチャ図をまとめました。

詳しくは公式ドキュメントなどを参考にしてもらうとして、それぞれの用語について軽く説明します。

  • mongod: MongoDBが動いているホスト
  • arbiter: レプリケーションをせずレプリカセットの投票処理のみを行うホスト
  • mongos: どちらのシャードにデータを保存すべきか or 検索時に探しに行くべきかルーティングするホスト
  • レプリカセット: レプリケーション+フェイルオーバー機能を実現する1単位。
  • configサーバー: どちらのシャードにデータが保存されているか記録しておくMongoDB。これ自体もレプリカセット。

図のように電力サービスでは2シャードにデータを分散して保存することで負荷分散をしています。

ただこれはMongoDBの欠点(?)なのですが、1シャードで運用する限りは mongod * 2 + arbiter の3台で構成できるものの、
2シャードに増やすと途端に レプリカセット * 2 + mongos * 2 でホストを8台も増やす必要があります。

そしてこれが最低でも本番用とテスト(stg)用の2環境必要なため、管理すべきホストの台数は 22台+α となります。
この台数の設定を管理しつつ、例えばMongoDBのversionを上げたりなんかしようとするとかなりの重労働ですね。

電力サービスではこの運用コストを減らすため、MongoDB Cloud Manager というMongoDB社のサービスを利用しています。

MongoDB Cloud Managerを利用した運用

MongoDB Cloud Managerはその名の通り、MongoDBのホストを管理するためのクラウドサービスです。
(昔はMongoDB Management System = MMS という名前で、今でも略称として「MMS」が使われるようです)
有料サービスですが、今は30日間の無料トライアルがあるようです。

主な機能として以下のようなものがあります。

  • 設定の管理
    • mongod用の設定
    • レプリカセットの構築
    • シャードクラスタの構築
    • シャードキーの設定(比較的最近追加された)
    • など
  • モニタリング
  • データ閲覧(最近追加された)
  • データバックアップ( 要追加課金なため使ってません)

以下はその実際の画面です。

左は管理中ホストの一覧と設定画面を開いたところです。黄色い警告っぽいのが出てるのはversion upをサボってるからですね!
右はメトリックを閲覧できる画面です。クエリの実行回数やcpu使用率、レプリケーションのラグやpage fault数など様々なメトリックが閲覧できます。

MMSを利用するとホストの管理が劇的に楽になります。
例えば構築時においては、各ホストには「Automation Agent」と呼ばれるツールをインストールし、設定ファイルにMMSアカウントのtokenを追記します。
あとは画面から設定を入力すると自動的にmongodがインストールされ、上記画面のようにホストとして利用可能な状態にしてくれます。

2系から3系へのversion up作業

特にMMSが威力を発揮したのは正式リリース前に行ったMongoDB2系から3系へのversion up作業でした。
MongoDBの2系と3系ではストレージの実装が mmap から WiredTiger に変わっており、性能が劇的に上がることが分かっていました。
そのためどうしても正式リリース前にversionを上げておきたかったのです。

ただ既にトライアルという形で外部のお客様相手にサービスを提供していたことを考えると、簡単にサービスを止めるわけには行かない状況でもありました。

本来であればdumpを取ったあと、primary <=> secondaryの切り替えを考慮しつつversionアップし、データを再投入という気の遠くなる作業が必要でした。
(それを22台分!)
しかしMMSを利用したことで、上記作業は全て画面上で設定を変更するだけで完了しました。
画面で設定を変更すると、MMSは自動的にprimary <=> secondaryを切り替えながらversion upし、データを再投入してくれます。

MongoDB社の有料サービスということで、下手にこちらで手順を作って作業するよりもミスなく進められるのも大きな利点です。

まとめ

電力サービスでのMongoDBの運用について紹介しました。
半分MMSの宣伝のようになってしまいましたが、大規模なMongoDBの運用をする際には本当に便利なサービスだと思います。

そのうちindexやシャードキーの張り方、アプリケーションとの連携方法なども紹介できたらと思います。

藤本 椋也1

藤本 椋也

2018年02月13日 火曜日

IIJ ネットワーク本部 IoT基盤開発部 センサーネットワーク課所属。2015年に新卒入社。webアプリケーション実装・運用を中心にやりたいことがあれば何でも手を出してみる所存です。