問題タブ [app-engine-ndb]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
google-app-engine - アプリ エンジン データストアの住所モデル、共通プロパティはどのように構造化する必要がありますか?
2 つのモデルに基づく数百万のアドレスがあるとします。
/li>Address
モデルには、次のような一般的なプロパティであっても、プレーンな文字列プロパティがありますcounty
。
/li>StructuredAddress
model は、それぞれを として定義することにより、より一般的なプロパティを他のモデルへの参照として保持しますKeyProperty
。
質問は次のとおりです。
のような一般的なプロパティに基づいてクエリを実行する場合、どのモデルがより効率的
zipcode
ですか?county
プロパティの数が約50で、プロパティの数が約100万の場合を想定しzipcode
ます。何百万もの住所レコードがある場合、この場合、どのモデルがより効率的でしょうか?この例での使用
KeyProperty
は、より多くの読み取り操作を意味し、実質的に請求額が高くなることを意味しますか? 組み込みの ndb キャッシングはすでにこれを回避していますか?
google-app-engine - NDB の id プロパティを使用するには?
古いデータストアでは、キーを使用しました。ここで、ID を使用する必要があります ( NDB Cheat Sheet docから取得):
しかし、このコードは機能しないようです - レコードが数回追加されます。
(私の場合、user_idは文字列です)
google-app-engine - データストアから多数のndbエンティティをクエリするためのベストプラクティス
AppEngineデータストアで興味深い制限に遭遇しました。実稼働サーバーの1つで使用状況データを分析するのに役立つハンドラーを作成しています。分析を実行するには、データストアから取得した10,000以上のエンティティをクエリして要約する必要があります。計算は難しくありません。使用サンプルの特定のフィルターを通過するアイテムのヒストグラムにすぎません。私が直面した問題は、クエリの期限に達する前に処理を実行するのに十分な速度でデータストアからデータを取り戻すことができないことです。
パフォーマンスを向上させるために、クエリを並列RPC呼び出しにチャンク化するために考えられるすべてのことを試しましたが、appstatsによると、クエリを実際に並列で実行することはできないようです。私がどの方法を試しても(以下を参照)、RPCは常に次の連続クエリのウォーターフォールにフォールバックしているように見えます。
注:クエリと分析のコードは機能しますが、データストアから十分な速さでデータを取得できないため、実行速度が遅くなります。
バックグラウンド
共有できるライブバージョンはありませんが、これが私が話しているシステムの一部の基本モデルです。
サンプルは、ユーザーが特定の名前の機能を利用するときと考えることができます。(例:'systemA.feature_x')。タグは、顧客の詳細、システム情報、および機能に基づいています。例:['winxp'、 '2.5.1'、'systemA'、'feature_x'、'premium_account'])。したがって、タグは、対象のサンプルを見つけるために使用できる非正規化されたトークンのセットを形成します。
私が行おうとしている分析は、日付範囲を取得し、顧客アカウント(ユーザーごとではなく会社)ごとに1日(または1時間)に使用される一連の機能(おそらくすべての機能)の機能が何回あったかを尋ねることで構成されます。
したがって、ハンドラーへの入力は次のようになります。
- 開始日
- 終了日
- タグ
出力は次のようになります。
クエリの共通コード
すべてのクエリに共通するコードを次に示します。ハンドラーの一般的な構造は、webapp2を使用した単純なgetハンドラーであり、クエリパラメーターを設定し、クエリを実行し、結果を処理し、返すデータを作成します。
試した方法
データストアからデータをできるだけ早く並行してプルするために、さまざまな方法を試しました。私がこれまでに試した方法は次のとおりです。
A.シングルイテレーション
これは、他の方法と比較するためのより単純な基本ケースです。クエリを作成し、すべてのアイテムを反復処理して、ndbが次々にそれらをプルするために行うことを実行できるようにします。
B.ラージフェッチ
ここでのアイデアは、1つの非常に大きなフェッチを実行できるかどうかを確認することでした。
C.時間範囲全体での非同期フェッチ
ここでの考え方は、サンプルが時間全体でかなり間隔が空いていることを認識することです。これにより、時間領域全体をチャンクに分割する一連の独立したクエリを作成し、非同期を使用してこれらのそれぞれを並列に実行しようとします。
D.非同期マッピング
このメソッドを試したのは、Query.map_asyncメソッドを使用すると、ndbが自動的に並列処理を利用する可能性があるように思われるためです。
結果
全体的な応答時間とappstatsトレースを収集するために、1つのクエリ例をテストしました。結果は次のとおりです。
A.シングルイテレーション
実数:15.645秒
これは、バッチを次々にフェッチしてから、memcacheからすべてのセッションを取得します。
B.ラージフェッチ
実数:12.12秒
オプションAと実質的に同じですが、何らかの理由で少し高速です。
C.時間範囲全体での非同期フェッチ
実数:15.251秒
最初はより多くの並列処理を提供するように見えますが、結果の反復中に次への一連の呼び出しによって速度が低下するようです。また、セッションmemcacheルックアップを保留中のクエリとオーバーラップさせることはできないようです。
D.非同期マッピング
実数:13.752秒
これは私が理解するのが最も難しいです。かなりの重なりがあるように見えますが、すべてが並列ではなく滝の中で伸びているようです。
推奨事項
これらすべてに基づいて、私は何が欠けていますか?App Engineの制限に達したばかりですか、それとも多数のエンティティを並行してプルダウンするためのより良い方法がありますか?
次に何をしようか迷っています。クライアントを書き直して、App Engineに複数のリクエストを並行して行うことを考えましたが、これはかなりブルートフォースのようです。App Engineがこのユースケースを処理できるはずなので、何か足りないものがあると思います。
アップデート
結局、私の場合はオプションCが最適であることがわかりました。6.1秒で完了するように最適化することができました。まだ完璧ではありませんが、はるかに優れています。
何人かの人からアドバイスを受けたところ、次の項目を理解し、覚えておくことが重要であることがわかりました。
- 複数のクエリを並行して実行できます
- 一度に飛行できるRPCは10台のみです。
- 二次クエリがない点まで非正規化してみてください
- このタイプのタスクは、リアルタイムクエリではなく、reduceキューとタスクキューをマップするために残しておくことをお勧めします
それで、私がそれをより速くするためにしたこと:
- クエリスペースを最初から時間に基づいて分割しました。(注:返されるエンティティに関してパーティションが等しいほど良い)
- データをさらに非正規化して、セカンダリセッションクエリの必要性を排除しました
- ndb非同期操作とwait_any()を使用して、クエリを処理とオーバーラップさせました
期待したり、期待したりするパフォーマンスがまだ得られていませんが、今のところは機能しています。ハンドラーで多数のシーケンシャルエンティティをメモリにすばやくプルするためのより良い方法であるといいのですが。
app-engine-ndb - 直接の親の祖先クエリ
App Engine NDB を使用して再帰構造をモデル化しようとしています。
ここから、直下の子のルート エンティティをクエリします。私ができることは、ルートのすべての子孫を照会することです。
私がやりたいことは次のとおりです。
しかし、(即時の) 親キーによるクエリは、ndb API ではサポートされていないようです。うまくいけば、私は間違っています。解明が待ち遠しい。ありがとう
google-app-engine - NDB の GAE Memcache 使用率が低いようです
約 40 GB のデータベースを持つ Google App Engine プロジェクトがあり、NDB での読み取りパフォーマンスが低下しています。memcache のサイズ (ダッシュボードに表示されている) が約 2 MB しかないことに気付きました。パフォーマンスを向上させるために、NDB が暗示的に memcache をより多く使用することを期待しています。
NDB の memcache の使用をデバッグする方法はありますか?
python - 新しいモデル エンティティを作成し、その直後にそれを読み取るにはどうすればよいですか?
私の質問は、新しいモデル エンティティを作成し、その直後にそれを読み取るための最良の方法は何かということです。例えば、
これにより、次のような例外がスローされることがよくあります。
つまり、新しい LeftModel エンティティの取得に失敗しました。私は appengine でこの問題に数回直面しましたが、私の解決策は常に少しハッキーでした。通常、エンティティが正常に取得されるまで、すべてを try except または while ループに入れます。無限ループ (while ループの場合) のリスクを実行したり、コードを台無しにしたり (try except ステートメントの場合) することなく、モデル エンティティが常に取得されるようにするにはどうすればよいですか?
google-app-engine - NDB での繰り返しプロパティのカウントによるクエリ
NDB で繰り返されるプロパティのアイテム数でクエリを実行するための効率的なメカニズムはありますか?
私は次のようなことをしたいと思います:
もちろん、これは機能しません。
python - keys_only=True でクエリを実行してから get_multi を実行するか、完全なクエリを実行するのが最善ですか?
スレッドセーフモードをオンにして、Python 2.7 で NDB を使用しています。
キー名による取得とは異なり、NDB を使用したエンティティのクエリはローカル キャッシュや memcache を使用せず、データストアに直接送信されることを理解しています。(この前提が正しくない場合、残りの質問は冗長になる可能性があります。)
したがって、keys_only=True でのみクエリを実行し、get_multi を実行して完全なエンティティを取得するのが良いパラダイムでしょうか?
利点は、keys_only=True クエリが keys_only=False よりもはるかに高速であることです。
欠点は、RPC クエリ呼び出し + get_multi 呼び出しがあることです。1 つの get_multi で呼び出すことができるエンティティの数には制限があるため、有効なクエリ サイズが制限される可能性があります。
どう思いますか?keys_only=True を使用してのみクエリを実行してから、get_multi を実行する必要がありますか? 完全なエンティティを返すクエリを実行する場合ほど効果的ではない、特定の最小および最大クエリ サイズの制限はありますか?
python - KeyProperty による NDB クエリ フィルタ
ndb モデルにクラス メソッドがあり、「ユーザー」(問題ありません) と「業界」でフィルタリングしています。
問題は、エンティティRecommendationには業界プロパティがなく、Stock の KeyProperty である Stock プロパティがあり、Stockには業界プロパティがあることです。
get_last_n_recommendations_for_user_and_industryメソッドを修正して、業種 (株式の KeyProperty) でフィルタリングするにはどうすればよいですか??
これを行うと、次のエラーが発生します。
python - 名前空間を持つマルチテナント Appengine アプリケーションでのグローバル データの管理
名前空間を使用してマルチテナント システムを設計しています。
ユーザーは OpenID 経由で認証され、ユーザー モデルは Cloud Datastore に保存されます。ユーザーは組織にグループ化され、データベースでもモデル化されます。アプリケーション データは、組織ごとに分割する必要があります。
したがって、名前空間を「組織」にマップするという考え方です。
ユーザーがログインすると、組織が検索され、セッションに保存されます。
WSGI ミドルウェアはセッションを検査し、それに応じて名前空間を設定します。
私の質問は、「グローバル」なデータ (つまり、ユーザーと組織) とアプリケーション データ (組織によって名前空間が設定されている) の間の切り替えを管理する最善の方法に関するものです。
私の現在のアプローチは、python デコレーターとコンテキスト マネージャーを使用して、そのようなグローバル データにアクセスする操作のためにグローバル名前空間に一時的に切り替えることです。例えば
また
これはまた、モデルがクロスネームスペース KeyProperties を持っていることを意味します:
これは合理的なアプローチに思えますか?私には少しもろいように感じますが、それは私が App Engine で名前空間を操作するのに慣れていないためだと思います。私の別のアイデアは、すべての「グローバル」データを Cloud Datastore から外部 Web サービスに抽出することですが、可能であればそれは避けたいと思います。
ありがたいアドバイスをいただきました。前もって感謝します