仕事している過程で、ふと疑問に思うことがありました。非同期についてです。
非同期問題を解決する方法はたくさんあると思いますが、MongoDBで解決できるのかが気になったので
試してみました。
非同期問題とは
ここでの非同期問題とは、例として、2プロセスがディレクトリにあるデータを操作することを考えます。
- Aプロセスでデータを新規書込/削除
- Bプロセスでデータを読込/追記
の場合、以下の問題が考えられます。
- Aプロセスが削除したデータをBプロセスが読込、あるいは追記する
- Bプロセスが追記したデータをAプロセスが上書きする
ことが生じます。
いずれも操作対象オブジェクト一覧をロックしようがないためです。
さて、MongoDBで同様のことを処理するとどうなるか?を試してみました。
テスト環境
使用した環境は以下です。
- WSL2 (Windows 10)
- ubuntu 22.04(LTS)
- Python 3.10.2
- MongoDB 7.0.5
MongoDBのインストール
systemdではなく手動で起動しました。
$ sudo apt-get install -y mongodb-org $ sudo mongod
テストコード
ここのような実装をしてみました。
MongoDBのアクセスはMongoEngineを使用しています。
各プロセスは以下を行います。
プロセスA
- User(MongoDBではCollection)を生成
- 乱数によりデータ新規or追記、あるいは削除
プロセスB
- 全Userデータを取得し、乱数により追記
条件付きでエラーを防げる
各プロセスで以下のように一覧取得後(User.objects)にデータが削除された場合、e_idがNoneになるようです。
for u in User.objects: ... if not u.e_id: <--- 一覧として取得してるはずなのにデータがない continue
結論: MongoDBを使用すると条件付きで非同期処理が可能
ということで、実装次第で「非同期処理」が可能なようです。
参考
https://mongoengine-odm.readthedocs.io/apireference.html
https://docs.mongoengine.org/projects/flask-mongoengine/en/latest/session_interface.html
https://qiita.com/key/items/b3894c64161a02d10649