MongoDB製JOB Queue
お盆が暇だったので
MongoDB製Job queue を作った。
名前はMONMOちゃん。
javascriptで手軽に使いたい部分があって個人用で考えていたが
結構マトモなモノが出来上がったので公開する事にする。
またMONMOちゃんを使って、自然言語処理も一式書いてみたが
こちらは次回紹介する。
About Monmoちゃん
概要
- 全ての処理はMongoDB(mongod) 及び Mongo shell(mongo)上で動作する。
- JobはJavascriptで記述する。
- MongoDBへJob投入(制御データと実装)すると、予めどこかで起動したWorkerが処理する。
- Job投入側にはスクリプトを用意した。
- 現在のJobの種類
- 通常Job
- Map Job
- MapReduceは実装作業中・・(emitを効率化できてなくて困ってる。。)
なぜ必要?
MongoDBにも以下の様なロジックを走らせる仕組みはある。
- where
- aggregate
- mapreduce
- などなど
しかし、これらはサーバサイド(mongod)で走る。
OracleのPL/SQLの様なモノだ。DBでアプリ処理を行えば割り食ってDBの性能が落ちる。
下手するとDB自体が落ちる!
なんの為に分散DB使ってるんだ!?
と・・・
そこでMongoDBクライアントであるMongo shell (mongo)を利用する事にした。
Mongo shellはMongoDBをオペレーションする時に不可欠なシェルだが、只のreadline程度のものじゃない。
V8搭載の高性能なJavascript実行環境だ!
MONMOちゃんの構成はこんな感じだ。
使い方
準備も利用も超簡単!
== 準備 ==
1. MongoDBを立てる。
2. MONMOちゃん一式をgit cloneする。(上記github)
3. MONMOの設定ファイルにMongoDBのパスを指定
4. MONMOワーカーを立てる。
# ワーカーを4プロセス立てる $ ./worker.sh -J 4
== JOB投入 ==
5. Job実装ファイルを作る
== samplejob.js == function main(jobctl,options) { jobctl.put( function(){ return new Job({ // Job投入側の処理 //( // サンプルなのでコレクションにデータを入れている // 本来はJOBの制御情報を作る処理になる // ) create_job : function(){ this.src.drop(); this.src.save({_id: 1,n:1}); this.src.save({_id: 2,n:1}); this.src.save({_id: 3,n:1}); this.src.save({_id: 4,n:1}); this.src.save({_id: 5,n:1}); this.src.save({_id: 6,n:2}); this.src.save({_id: 7,n:2}); this.src.save({_id: 8,n:2}); this.src.save({_id: 9,n:2}); this.src.save({_id:10,n:2}); return { ok:1 }; }, // Worker側で実行される処理(只のSUM) run : function(){ var data = {i:0,n:0}; this.src.find().forEach(function(doc){ data.i += doc._id; data.n += doc.n; }); this.dst.save(data); return { ok:1, msg: 'success', data: data }; }, }); },options); }
6. Jobを投入
# "test" DB "TEST"コレクションを入力側、"test" DB "RESULT"コレクションを出力側として指定 # $ ./jobctl.sh -s test.TEST -o test.RESULT -f samplejob.js
7. 結果
- Load : ./sample/jobs/samplejob.js { "_id" : ObjectId("5218092e241076268cbc9b71"), "args" : { }, "dst" : "test.RESULT", "name" : "test.RESULT.job", "src" : "test.TEST", "st" : 1377306937204, "timeout" : 600000, "tm" : ISODate("2013-08-24T01:15:26.800Z"), "end" : ISODate("2013-08-24T01:15:27.209Z"), "ok" : 1, "msg" : "success", "data" : { "i" : 55, "n" : 15 } }