データを取得する方法として、MongoDB をキューとして使用し、PHP-Queue を使用しています。これは POC であり、私は OSX マシンで実行しています。Mongo のパフォーマンス、つまり findmodify 関数のパフォーマンスが非常に遅いことがわかります。私は PHP 側で一連のテストを行いましたが、PHP 処理は時間の約 5% しか占めていません。たとえば 10,000 件のメッセージで Mongo コレクションをいっぱいにすると、3 ~ 5 秒程度ですぐにいっぱいになります。でも、空にすると250秒くらいかかります。このうちPHP側はわずか10秒ほど。mongod プロセスをチェックすると、約 60MB を超えることはありませんが、CPU は全体で 90% 以上スパイクします。コレクションのインデックスを作成しました。以下は、メッセージ データとインデックスのサンプルです。
メッセージの例 (これは、キュー内の 10,000 件の同様のメッセージの 1 つです):
{
"_id": ObjectId("526c47d5c5008c1d5cd63ef8"),
"payload": {
"0": {
"EVENT_HEADER_KEY": NumberInt(9094775),
"event_name": "Account Change",
"source_name": "Work",
"event_category_name": "Complex Events",
"EVENT_TIMESTAMP": "Aug 17 2013 12:00:00:000AM",
"PARENT_HEADER_KEY": null,
"year": NumberInt(2013),
"month": NumberInt(10),
"Company_Name": "ACME PRODUCTS, INC.",
"Company_Email": "blabla",
"Company_Phone": "555-555-5555",
"First_Name": "Jon",
"Last_Name": "Doe",
"ID_NUMBER": "111111111",
"created_by": "Load Job Name",
"created_at": "Oct 18 2013 04:07:31:140PM",
"product_analytical_category": "blabla",
"_Event_Type": "blabla",
"CUSTOMER_ID": "111111111"
}
},
"running": false,
"resetTimestamp": ISODate("2038-01-19T03:14:07.0Z"),
"earliestGet": ISODate("1970-01-01T00:00:00.0Z"),
"priority": 0,
"created": ISODate("2013-10-26T22:53:09.440Z")
}
自動的に作成されたと思われるこのコレクションのインデックス:
{
"_id": NumberInt(1)
}
mongo.log を確認すると、キューを空にすると、約 70 のメッセージに対してメッセージあたり約 1 ミリ秒しかかからず、opid が変更され、300 ~ 900 ミリ秒の遅延が発生してから続行することがわかります。メッセージあたり約1ミリ秒の同じペースで新しいopid。これらの opid の変更は、250 秒の処理時間のうち約 50 ~ 100 秒を占めているため、さらに多くの処理が行われています。
mongo.log からの抜粋:
**Sat Oct 26 15:15:25.189** [conn4] warning: ClientCursor::yield can't unlock b/c of recursive lock ns: test.abe top: { **opid: 20064**, active: true, secs_running: 0, op: "query", ns: "test", query: { findandmodify: "abe", query: { running: false, earliestGet: { $lte: new Date(1382825725143) } }, update: { $set: { resetTimestamp: new Date(1382825785000), running: true } }, fields: { payload: 1 }, sort: { priority: 1, created: 1 } }, client: "127.0.0.1:53045", desc: "conn4", threadId: "0x119024000", connectionId: 4, locks: { ^: "w", ^test: "W" }, waitingForLock: false, numYields: 0, lockStats: { timeLockedMicros: {}, timeAcquiringMicros: { r: 0, w: 3 } } }
**Sat Oct 26 15:15:25.190** [conn4] warning: ClientCursor::yield can't unlock b/c of recursive lock ns: test.abe top: { **opid: 20064**, active: true, secs_running: 0, op: "query", ns: "test", query: { findandmodify: "abe", query: { running: false, earliestGet: { $lte: new Date(1382825725143) } }, update: { $set: { resetTimestamp: new Date(1382825785000), running: true } }, fields: { payload: 1 }, sort: { priority: 1, created: 1 } }, client: "127.0.0.1:53045", desc: "conn4", threadId: "0x119024000", connectionId: 4, locks: { ^: "w", ^test: "W" }, waitingForLock: false, numYields: 0, lockStats: { timeLockedMicros: {}, timeAcquiringMicros: { r: 0, w: 3 } } }
**Sat Oct 26 15:15:25.507** [conn4] warning: ClientCursor::yield can't unlock b/c of recursive lock ns: test.abe top: { **opid: 20141**, active: true, secs_running: 0, op: "query", ns: "test", query: { findandmodify: "abe", query: { running: false, earliestGet: { $lte: new Date(1382825725501) } }, update: { $set: { resetTimestamp: new Date(1382825785000), running: true } }, fields: { payload: 1 }, sort: { priority: 1, created: 1 } }, client: "127.0.0.1:53045", desc: "conn4", threadId: "0x119024000", connectionId: 4, locks: { ^: "w", ^test: "W" }, waitingForLock: false, numYields: 0, lockStats: { timeLockedMicros: {}, timeAcquiringMicros: { r: 0, w: 3 } } }
これは、これらの 10,000 メッセージのログ全体で基本的に同じです。メッセージごとに 1 ミリ秒しかかからない findandmodify() の長いシーケンスがあり、その後 opid が変更され、ほぼ 1 秒かかる遅延が発生します。これが何か重要なことを示しているかどうかはわかりませんが、私は Mongo を初めて使用し、有望と思われるパターンを見つけようとしています。
アップデート:
このクエリは、フィールド 'running' が false であることを確認し、さらに EarlyGet フィールドがエポック (1-1-1970) より新しいことも確認します。これらのフィールドにインデックスを追加しても無駄でした。これらのフィールドはコレクション内のすべてのメッセージ ('false' および 1970 年 1 月 1 日) で同じであるため、それらのインデックス作成によってクエリ時間が増加するだけである可能性があります。これを適切に機能させるために何をすべきかわかりません。1970 年 1 月 1 日よりも新しい最初のレコードを取得する必要があるようですが、明らかに Mongo はまだコレクション全体を処理しているため、クエリが遅すぎて実用的ではありません。さらに、選択基準がない場合でも、応答時間は 202 秒です。これは高速ですが、許容範囲ではありません。また、「yield can't unlock b/c of recursive lock ns:」というメッセージも表示されます。