1

ユーザーが定義した時間に条件付きでユーザーのメールボックスにメッセージを挿入するために IMAP を使用する Web アプリがあります。

これらの「ジョブ」のそれぞれは、ジョブを実行する必要があるときのタイムスタンプ (数か月先の可能性があります) とともに MySQL DB に保存されます。ユーザーはいつでもジョブをキャンセルできます。

問題は、IMAP 接続を確立するプロセスが遅いことです。メッセージを挿入する前に、受信トレイ (または同様のもの) に誰かからの返信があるかどうかを条件付きで確認する必要があり、各ジョブにかなりの処理オーバーヘッドが追加されます。

現在、1 分ごとに cron スクリプトを実行するシステムがあり、次の X 分で配信する必要があるすべてのジョブを DB から取得します。次に、それらを Z ジョブのバッチに分割し、バッチごとに非同期 POST 要求を実行して、それらの Z ジョブのすべてのデータを同じサーバーに返します (「偽の」マルチスレッドを実現するため)。次にサーバーは、HTTP 経由で入ってくる Z ジョブの各バッチを処理します。

pnctl_fork のようなものではなく、マルチスレッドに非同期 HTTP POST を使用する理由は、他のサーバーを追加して、代わりにそれらにデータを POST させ、現在のサーバーではなくジョブを実行させることができるようにするためです。

だから私の質問は - これを行うためのより良い方法はありますか?

beanstalkdのようなワーク キューが利用できることはありがたいのですが、特定の時間にジョブを実行しなければならないモデルに適合しますか?

また、とにかく DB にジョブを保持する必要があるため (ジョブを管理するための UI をユーザーに提供する必要があるため)、そこにワーク キューを追加すると、実際にはオーバーヘッドが削減されるのではなく、オーバーヘッドが増加しますか?

私たちが必要とするものを達成するためのより良い方法があると確信しています - どんな提案も大歓迎です!

これらすべてに PHP を使用しているため、PHP ベース/互換性のあるソリューションが本当に求めているものです。

4

1 に答える 1

0

Beanstalkd は、これを行うための合理的な方法です。の概念を備えているput-with-delayため、プライマリ ストアから定期的にキューを予約して実行できるメッセージで満たすことができますX(実行したい-時間は現在の時間)。

その後、ワーカーは通常どおり実行され、beanstalkd デーモンに接続し、新しいジョブが予約されるのを待ちます。また、HTTP 接続のオーバーヘッドがなければ、はるかに効率的です。例として、Amazon SQS に (http で) メッセージを投稿していました。これはせいぜい 20 QPS しかできませんでしたが、Beanstalkd はほとんど努力することなく 1 秒あたり 1000 以上を受け入れました。

追加するために編集: ID を知らずにジョブを削除することはできませんが、それを外部に保存することはできます。OTOH、ユーザーはいつでも最後までジョブを削除できる必要がありますか? 数週間または数か月前にジョブをキューに入れる必要がないため、次のいくつかのジョブをキューに入れるために、たとえば 1 ~ 5 分ごとに実行される DB リーダーは 1 つしかありません。必要な数のワーカーを必要な数だけ確保し、効率を向上させることができます。

最終的には、実行している DB の読み取り/書き込みの数と、データベース サーバーがそれらをどのように処理できるかによって異なります。

あなたが今していることに問題がなく、追加の負荷で問題が発生しない場合は、続行してください。

于 2012-01-23T18:44:12.470 に答える