0

私の Python High Replication Datastore アプリケーションには、100,000 ~ 1,000,000 エントリの大きなルックアップ テーブルが必要です。そのコードに関連付けられた値 (関連付けがない場合は None) を返すコードをメソッドに提供できるようにする必要があります。たとえば、テーブルに受け入れ可能な英語の単語が含まれている場合、その単語が見つかった場合は関数が True を返し、それ以外の場合は False (または None) を返します。

私の現在の実装は、テーブル エントリごとに 1 つの親のないエンティティを作成し、そのエンティティに関連データを含めることです。そのエンティティのデータストア キーをルックアップ コードと同じに設定しました。(キーの競合を防ぐために、すべてのエンティティを独自の名前空間に配置しますが、この質問には必須ではありません。) 次に、コードで get_by_key_name() を呼び出すだけで、関連付けられたデータを取得します。

問題は、複数のエンティティ グループにまたがろうとするため、トランザクション中にこれらのエンティティにアクセスできないことです。例に戻って、チャット セッションで使用されるすべての単語のスペル チェックを行いたいとしましょう。チャット内のすべてのメッセージに共通の祖先を与えることでアクセスできましたが、エントリに親がないため、単語テーブルにアクセスできませんでした。トランザクション中にテーブルを参照できることが不可欠です。

私のルックアップテーブルは固定されているか、めったに変更されないことに注意してください。これもスペルチェックの例と一致します。

解決策の 1 つは、1 つのトランザクション中にチャット セッション内のすべての単語を読み込み、それらの単語をスペル チェック (結果を保存) してから、保存された結果に対してスペル チェックを行う 2 番目のトランザクションを開始することです。しかし、これは非効率であるだけでなく、トランザクションの間にチャット セッションが追加された可能性があります。これは不器用な解決策のようです。

理想的には、ルックアップ テーブルが不変であることを GAE に伝えたいと考えています。これにより、トランザクション内の複数のエンティティ グループについて不平を言うことなくクエリを実行できるはずです。ただし、これを行う方法はありません。

テーブル エントリを memcache に格納するのは魅力的ですが、これにも問題があります。これは大量のデータですが、さらに厄介なのは、GAE が memcache エントリを起動すると、トランザクション中に再読み込みできなくなることです。

大規模なグローバル ルックアップ テーブルの適切な実装を知っている人はいますか?

私がスペル チェック Web サービスなどを探しているわけではないことを理解してください。この質問を明確にするためだけに単語ルックアップを例として使用していますが、あらゆる種類の大きなルックアップ テーブルの一般的な解決策を望んでいます。

4

2 に答える 2

1

可能であれば、データをインスタンス メモリに収めてみてください。インスタンス メモリに収まらない場合は、いくつかのオプションを利用できます。

アプリでアップロードするリソース ファイルにデータを保存できますが、変更頻度が低い場合は、ディスクからアクセスできます。これは、簡単なディスク ルックアップを可能にするデータ構造を構築できることを前提としています。つまり、独自の読み取り専用ディスク ベース テーブルを実装していることになります。

同様に、サイズが大きすぎて静的リソースに収まらない場合は、上記と同じ方法でデータをブロブストアに保存できます。

データが絶対にデータストアにある必要がある場合は、独自の読み取り-変更-書き込みトランザクションをエミュレートする必要がある場合があります。レコードに「リビジョン」プロパティを追加します。変更するには、レコードを (トランザクション外で) フェッチし、必要な変更を実行してから、トランザクション内で再度フェッチしてリビジョン値を確認します。変更されていない場合は、自分のレコードのリビジョンを増やしてデータストアに保存します。

基盤となる RPC レイヤーは、理論的には複数の独立したトランザクション (および非トランザクション操作) をサポートしていますが、API は現在、トランザクション内からこれにアクセスする方法を公開していないことに注意してください。不幸にも。

最後のオプションの 1 つ: より多くのメモリでプロビジョニングされたバックエンドを実行し、「SpellCheckService」を公開して、フロントエンドから URLFetch 呼び出しを行うことができます。インメモリは常に、どのディスクベースのオプションよりもはるかに高速であることを忘れないでください。

于 2011-09-19T04:33:01.933 に答える
1

まず、名前空間がキーの競合を回避するのに役立つと信じている場合は、一歩下がってください。キーは、エンティティの種類、名前空間、名前または ID、およびエンティティが持つ可能性のある親で構成されます。2 つの異なる種類のエンティティが同じ名前または ID を持つことは完全に有効です。したがって、たとえば、LookupThingy一致する a があり、一意の名前を指定して各メンバーを作成した場合、キーは他のものと衝突しません。

トランザクション内でペアレント化されていないルックアップ テーブルに対してスペル チェックと同等の処理を行うという課題については、ルックアップ テーブルをコードに保持することは可能ですか?

それとも、あなたが必要としているものにより近いアナロジーを思いつくことができますか? トランザクション内でルックアップを行う必要性を動機付けるものは?

于 2011-09-17T03:46:07.917 に答える