2

BigTableデータストアでこれを処理する方法がわかりません。

次の例を想像してみてください(概念を説明するためだけです。この例は実際のデータモデルと一致しません)。

  • データストア内のトランザクション数を追跡するCounterエンティティがあります。現在の「カウント」が100であるとしましょう。
  • これで、2つのWebリクエストがこの値を同時に読み取ります。
  • 両方のWebリクエストが新しいトランザクションを追加します
  • そして最後に、両方ともカウンターを更新します(101に)。

カウンタ値が不正確になりました。102である必要があります。

この状況に対処する方法について何か提案はありますか?カウンターを「ロック」して、最初のWebリクエストが完了するまで2番目のWebリクエストがカウンターを読み取らないようにすることはできますか?

4

2 に答える 2

4

いくつかのオプションがあります。

  • カウンターとエンティティのスコープに応じて、トランザクションエンティティをカウンターの子エンティティにします。次に、トランザクションを挿入し、カウンターをトランザクションで更新できます。これにより、更新レートが約1〜5QPSに制限されることに注意してください。
  • カウントが100%正確である必要がない場合は、エンティティを挿入し、(単一エンティティトランザクションを使用して)カウンターを個別に更新します。通常のcronジョブを実行して、エンティティの数を再カウントし、エラーによって同期が外れた場合にカウンターを修正できます。
  • 独自の限定分散トランザクションサポートを構築できます。
于 2009-11-26T16:10:19.833 に答える
1

Nickが提供するオプションに加えて、カウンターをシャーディングすることを検討できます。

複数のカウンターを保持し、2つのリクエストが同時に同じシャードを選択することが(理想的には)不可能であるか(失敗する)可能性が低い方法で更新するカウンターを1つ選択します。

その後、さらにオプションがあります。シャードを親としてトランザクションを実行できます(これにより、単一のカウンターと比較して競合が減少します)が、最終的には、親が任意に選択された新しいトランザクションエンティティになります。または、トランザクションを気にしないでください。その場合、ニックの非トランザクションオプションのように、カウントを時々修正する必要があります。

合計数を読み取るには、すべてのシャードを合計します。それらすべてを「同時に」読むことはありませんが、通常は問題ありません。カウンターを読み取ると、読み取るときと値を使用するときの間に増加する可能性があるため、値は実際には単なる下限です。シャードの合計は、おそらく時間がかかることを除いて、違いはありません。

于 2009-11-26T18:50:29.807 に答える