LoginSignup
2
1

More than 5 years have passed since last update.

MongoDBのコレクションのドキュメントにユニークな番号を発番する方法を考えてみた

Posted at

前提

例えば、コレクションAのドキュメントにnumberというユニークな連番を保持するフィールドが必要だとする。

条件として、MongoDBはReplicaSetで構成されていて、複数のアプリケーションサーバーから参照されている状態とし、write concernとフィールドのuniq設定は使えないものとする。また、ナンバリングしたデータは直ぐには必要のないデーターとする。

上記の場合、アプリケーションサーバー側でnumberフィールドのmax numberを取得し、そのアプリケーションのプログラム上でnumberをインクリメントして最新の最大numberとして保存すると、アプリケーションサーバー側が同じmax numberを掴む可能性があるので、ユニーク値での連番が作れない可能性がでてくる。

それでも、発番をしたい場合どうすべきかを2パターン、MongoDBを使ってどうするかということが課題としてあったので考えてみた。

パターン1 ジョブキューを使う

  • 構成例
項目 説明
App Server Python Tornado冗長化構成
Job Server RQ numberingキューを 1つのジョブワーカーに設定
Queue DB Server Redis (AWS ElastiCascheを利用)
Backend DB Sever MongoDB (ReplicaSet構成)
処理の流れ
"""
APP Servers(Python Tornado)
   ↓ ジョブをnumberingキューに追加
Redis Servers     
  ↑↓ numberingキューからジョブを取得して実行
rq worker
   ↓ DBをアップデート 
MongoDB
"""

作業

  • 既にジョブキューサーバーがあれば、キューを1つのジョブワーカーに設定
  • アプリケーションサーバー側でジョブを作成しenqueueする

特徴

  • キューがあれば都度実行

課題

  • データーは保持されるが、ワーカー1台だと、それがspof
  • 処理が増えた場合、スケールアップの対応しかできない
  • ジョブキューサーバーが対応してる言語に依存するので、汎用性は低い

パータン2 メッセージキューを使う

  • 構成例
項目 説明
App Server Python Tornado冗長化構成
Message Queueu AWS SQS
Batch Server EC2 Instance上で1プロセスのみ実行
Backend DB Sever MongoDB (ReplicaSet構成)
処理の流れ
"""
APP Servers(Python Tornado)
   ↓ キュー情報を追加 
AWS SQS
  ↑↓ キュー情報を取得してバッチプログラムで処理
Batch Server
   ↓ DBをアップデート 
MongoDB
"""

作業

  • バッチで動かすためのプログラムを書く
  • アプリケーション側にenqueue処理を追加

特徴

  • プログラム言語の依存は低い

課題

  • データーは保持されるが、バッチがこけると処理が止まるという問題
  • スケールアップの対応しかできない

まとめ

結構制約が多い中どうするか、numberingやめて_idを使えばいいじゃんとか妥協案はあるのですが、どうしてもナバリングしたい。

上記の様に考えてみるとやはりドキュメントのnumberingを一貫性を保ちながら処理していくことは結構大変。

ただ、非同期に処理をすることでなんとなくできそうだということもわかった。

あと、規模によっては、課題にある問題でnumberingがうまく動かなかった場合の復活の呪文プログラムも別途用意しておけば、実運用的には問題ないということもなんとなくわかった。

一貫性を保った処理をしたい場合(ナンバリングしたデータは直ぐには必要のないデーターというのが前提だが)ジョブキューかメッセージキューを使うとそれなりに対応できるかもしれない。

他に良いアイディアがあれば、教えてもらいたい。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1