2017-11-13 13 views
0

Google App Engineで実行中のアプリケーションでは、操作の一部としてシーケンス番号が生成されます。これらの数字は、以下の基準を満たしている必要がありますGoogle Datastoreのアトミックシーケンスカウンタ

  • 彼らは、指定された開始と終了の範囲
  • の間になければならない範囲の端がいくつかのケースのために到達するまで、彼らは我々が開始することができ、その場合には、(一意である必要があります再びシーケンスの開始)
  • から彼らは連続している必要があります(ランダム番号は、彼らが他の2つの基準を満たしていても、何も良いではない)

私たちは、生成された数字であることを保証しようとするコードを記述しましたグローバルにユニークですが、私はそのコードを共有することはできません。なぜなら、a) b)それは私の雇用者の財産であり、c)それは重い負荷の下で働くようには見えません。

私たちが独自の基準を満たしていることを確認することができず、sharded countersに関するいくつかの情報を見つけられなかったので、読んだことがありましたが、私はこのアプローチがまだ私たち固有の配列を生成するために100%確実である。私が疑問に思うのは、Datastoreにはupsertsに関するレイテンシがあることと、カウンタが更新されてからその更新が次の読み取りに反映されるまでの遅延が原因だということです。シャーディングを処理するPHPの例はありません(実際にPHPの例があれば他の例からも分かります)。

  • が両方のMemcacheのカウンタの現在値を維持する(整数の原子増分をサポートする)とデータストアに(永続性):以下のように、この問題に対する

    私の提案された解決策です。私たちはDatastoreのカウンターを断片化しようとするかもしれません。

  • 所定の配列から新しい番号の要求がでてくる:
    • は、現在の値をMemcacheのを確認してください。データはMemcacheのではない場合には、データストア
    • からそれを取り込む
    • が永続
    • を確保するために戻ってデータストアに新しいカウンタ値を書き込み、当社のプロセスのためのMemcacheから返された値を使用するMemcacheで
    • をアトミックインクリメントを行いますその顔には

この合理的な解決策と思われるが、私はまだアップデートの多くが同時に起こる場合は特に、我々は一貫性のないカウンタ値で終わるエッジケースがあるかもしれない心配です。 Memcacheは戻り値のアトミック性を保証しますが、Datastoreへの書き込みはリクエストの順番で行われ、Datastoreの最後にはMemcacheの値が反映されない可能性があります。アプリケーションがダウンし、サービスが復元されたときに不正な値がDatastoreからロードされます。

データストアの書き込みは、受信した順序で適用されますか?すべての書き込みが実行された後、Datastoreの値がMemcacheの値と一致することを保証できますか?この問題(オートインクリメント/シーケンスサポート付きのSQLデータベースに切り替える以外)の方が良い解決策がありますか?

答えて

0

AppEngineデータストアのシーケンシャルIDは、取り組むのが難しい問題です。

データストアに永続性を持たせて1つずつ実行しようとすると、トランザクションスループットの上限に達するでしょう。私は考えることができる

最善のアプローチ:

  1. 使用シャーディングは、最後のNカウンタ値を維持します。
  2. スタートトランザクション
  3. ロックmemcacheのエントリデータストアシャードを更新する前に(あなたが行くにndsパッケージを使用するか、同様の方法に行うことができます)とキーによってデータストアからすべてのシャード値を取得します。基本的には、すべてのシャードについてnds.GetMulti()と電話するだけです。ロックには、合理的な有効期限が必要です。 ndsパッケージの場合は30秒です。
  4. 最大値を持つシャードのシャードIDと値を取得します。
  5. データストアに適切なシャード値を最初に更新します。 - データベースにストアするだけで1つのエンティティになります。たとえば、シャード番号がカウンター値の最後の桁に対応している、0〜9の数字を持つ10個のシャードを持つことができます。だから、23は、適切なmemcacheの値を更新したり、memcacheのからそれを削除する)操作をトランザクション
  6. (使用memcacheのCAS(コンペア・アンド・スワップ(トランザクションFUNC /コンテキストのうち終了)をコミット3.
  7. をシャードにマッピングされるだろう。けれどもそれが右のそれを行うには簡単な作業ではありませんあなたは私がNDSパッケージに開始議論読むことができます - 。。https://github.com/qedus/nds/issues/58

基本的にあなたがすべてでmemcacheのなしで行うことができますが、memcacheのはあなたにお金を節約になるとレイテンシ(またはしない)を減少させることを

重要な点は、mをロックすることですemcacheを実行し、データストアを更新してから、memcacheから削除するか、CASを使用して更新します。あなたは反対のことを計画しています。

+0

申し訳ありませんが、私はGoogleを使用していないため、NDSライブラリを使用することはできません。私たち自身のPHPバージョンをロールバックすることができるかもしれません – GordonM

+0

それはOKです、私はNDSライブラリの著者ではありません。しかし、それはあなたにいくつかのアイデアや悪夢を与えることができます。 –

関連する問題