1

Google App Engine サービスでの db.put() 操作を可能な限り回復力のあるものにして、インフラストラクチャの問題や過負荷が発生した場合でも成功する可能性を最大限に高めたいと考えています。現時点で思いついたのは、発生する可能性のあるすべての例外をキャッチし、最初の試行が失敗した場合にコミットを再試行するタスクを作成することです。

try:
    db.put(new_user_record)
except DeadlineExceededError:
    deferred.defer(db.put,new_user_record)
except:
    deferred.defer(db.put,new_user_record)

このコードは考えられるすべてのエラー パスをトラップしますか? または、このコードでキャッチされない db.put() が失敗する可能性がある他の方法はありますか?


2013 年 3 月 28 日の編集 - いつ失敗が予想されるかを明確にする

これまでの回答では、 db.put() が失敗した場合、それはデータストアがダウンしているためであると想定しているようです。かなり負荷の高いアプリケーションを実行した私の経験では、これは必ずしも要件ではありません。ワークロード固有の API のボトルネックに遭遇することもあれば、ある API の速度が遅いために別の API でリクエストの期限が切れてしまうこともあります。このようなイベントの頻度は低くても、トラフィックが多い場合、その数はかなりの数になる可能性があります。これらは、私がカバーしようとしている状況です。

4

3 に答える 3

1

まあ、そのようなフォールバックを試みるのは良い考えではないと思います。データストアがダウンしている場合、それはダウンしており、運が悪いことになります (頻繁に発生するべきではありません:) コードに対するいくつかの考え:

  • put 操作中に発生する可能性のある例外は他にもたくさんあります (InternalError、Timeout、CommittedButStillApplying、TransactionFailedError など)。それらのいくつかは、put が失敗したことを意味しません。(つまり、CommittedButStillApplying は、プット操作が遅延していることを意味します)。あなたのアプローチでは、遅延呼び出しが成功した後、データストアにそのエントリが 2 回存在することになります。
  • タスクは最大 100KB に制限されています (ペイロードではなく合計サイズ)。ペイロードがその制限に近いかそれを超えている場合、deferred-api は自動的にペイロードをデータストアにシリアライズして、タスク自体をその制限未満に維持しようとします。データストアが実際に利用できない場合、これも失敗します。

そのため、データストアのエラーをキャッチして、リクエストが失敗したことをユーザーに通知する方がよいでしょう。

于 2013-03-27T14:52:36.903 に答える
1

これが最善のアプローチであるとは言えません。元の例外の原因が何であれ、再び発生する可能性があります。回復力を高めるために私が行うことは、最初に memcache に保存するレコードをロードすることです。put で例外が発生した場合 (すべての例外)、一定回数 (たとえば 3 回) 再試行し、それぞれの間に短いスリープを入れることができます。試み。アプリケーションに応じて、これは同期操作であるか、遅延タスクを使用して、memcache のデータを使用して非同期で実行できます。
最後に、行が実際に書き込まれたことを確認する例外がなくても、データ ストア内のレコードに対して実際にクエリを実行します。

于 2013-03-27T02:55:01.570 に答える