7

重要な画像処理を伴うアプリケーションを構築しています。RabbitMQ交換から画像をレンダリングするリクエストを受信する任意の数のレンダリングマシンを使用して、分散マナーで構築しています。

レンダリングがすでに処理されている間に画像のリクエストが届く可能性があり、2つのレンダリングサーバーで作業を複製したくないため、mySQL画像テーブルにis_renderingという列をブール値として作成しました。

レンダリングサーバーがレンダリングの要求を受信すると、次のような一連の手順に従います。

  1. 画像行を更新するために選択します
  2. is_rendering==trueの場合レンダリング要求を中止します
  3. is_rendering == trueに設定し、トランザクションをコミットします
  4. 画像をレンダリングし、サムネイルをグローバルにアクセス可能なストアに保存します
  5. is_rendering == falseを設定し、

それは間違いなく機能しますが、これらの頻繁なデータベース更新が少しばかげているように見えるのではないかと心配しています。さらに、レンダリングサーバーがレンダリングの途中で失敗し、is_rendering == trueのままになって、その画像がレンダリングされないようにするエッジケースを検討しています。この問題に対して私が検討している解決策は、is_rendering列をtinyint(1)からdatetimeフィールドに変更し、ロックの日付を「true」値として保存し、nullを「false」値として保存することです。定期的なサービスヘルスチェックでは、特定の期間を過ぎたis_rendering値を持つすべての行を選択し、この場合はロックを解除できます。

これはこの問題に対する正しいアプローチですか、それとも私が検討すべき他のよりエレガントなアプローチがありますか?

4

2 に答える 2

0

親愛なるあなたの問題を理解しているので、以下のルールに従っている場合、最初のアプローチも正しいです:1)テーブルタイプがinnoDBです。2)コードでトランザクションを使用しています。更新中に分割が発生した場合はロールバックするためです。

結局、2番目のアプローチも優れています。あなたが私の言及したポイントを満たしていない場合

于 2012-04-28T22:45:11.900 に答える
0

私は先に進み、DATETIME列を使用するように実装を変更しました。

これが一般的にmySQLの不適切な使用であるかどうか、私はここに本当に興味がありました。私が調査したことから、HadoopのZooKeeper(http://zookeeper.apache.org/doc/r3.1.2/recipes.html)やGoogleの内部Chubbyシステムのようなものを使用することができます。これはサービスの最初のイテレーションにすぎないので、mySQLを使い続けます。

私がここで読んだこと、そしてグローバルロックを生成する方法としてmySQLを使用してオンラインで読んだことはひどい考えではなく、それをDATETIME列に変更することは、少し鈍感ですが、ジョブの処理中にマシンがシャットダウンするという奇妙なケースを処理するための有効期限ポリシーを実装します。

トランザクションレベルのロックを保持することは別のアプローチですが、単一のサーバーが小さな接続プールで多くのスレッドを実行している場合は意味がありません。クライアント接続が失われます。

于 2012-04-29T12:15:01.170 に答える