2

デザインを最適化しようとしていますが、全体像を把握するのは非常に困難です。次のケースがあるとします。

A. ユーザーは 1,000 件のステータス更新を持っています。これらの更新は、別のエンティティである Statuses に保存されます。日付 X の後の uploadDate を持つユーザーのステータスを取得したいので、クエリを実行します。

statuses = Statuses.query(Statuses.uploadDate > X).fetch()

B. ユーザーは 1,000 件のステータス更新を持っています。各 User エンティティにはlist_of_status_keys、ユーザーのステータスへのすべてのキーのリストである list プロパティがあります。日付X以降のuploadDateですべてのステータスを取得したいので、を使用してステータスのリストを簡単に取得しますstatuses = ndb.get_multi(list_of_status_keys)。次に、それぞれをループして日付を確認します。

for a_status in statuses:
  if a_status.uploadDate > X:
     myList.append(a_status)

どちらを最適化する必要があるのか​​ 本当にわかりません。クエリはより整理されているように見えますが、キーによるフェッチの方が高速です。誰にも洞察がありますか?

アップデート

結論は次のとおりです。GAE への各 http 要求で、ユーザーのすべての通知とステータスの更新を取得します (Facebook と同様)。Appstats を使用すると、各リクエストのコストは 490 マイクロペニー (1 ペニー = 1,000,000 マイクロペニー) であることがわかります。

通知とステータスを取得することはユーザーにとって重要であるため、これを何度も行うことが予想されます。私が苦労しているのは、これが多いかどうかを判断することです。可能な限りこの数を最小限に抑えようとしています。これまでサービスを実行したことがないので、これがどれくらいの費用がかかるかわかりません。数学は次のとおりです。

結果が返されない場合、各リクエストには 490 マイクロペニーの費用がかかります (したがって、基本的なクエリの場合は 490 の費用がかかりますが、いくつかの結果が返される場合には 10,000 mp の費用がかかる可能性があります)、1 ペニーで 2040 のリクエストを実行できます。 1 ドルで、204,000 件のリクエストを実行できます。

50,000 人のユーザーがいて、各ユーザーが 1 日に 75 回 (妥当な) 通知をチェックしているとします。

75 requests X 490 mp per request X 50,000 users = 1,837,500,000 micropennies per day = 1837.5 pennies = 18.37 dollars per day.(そうですか?)

これまで大規模なサービスを実行したことがないので、これらのコストは通常​​のものですか? それともこれは高すぎますか?リクエストごとに 490 マイクロペニーは高いですか? それが依存している場合、どうすればこれに対する答えを見つけることができますか?

4

1 に答える 1

2

デザインAが優れています。

設計では、GAEは日付を使用してキー付きクエリを実行します。つまり、Appengineは、日付で並べ替えられたステータステーブルにインデックスを自動的に作成します。インデックスがあるため、指定した日付以降のレコードのみを読み取り、フェッチします。これにより、大量の読み取りを節約できます。

デザインBでは、基本的に自分でインデックス作成作業を行う必要があります。各ステータスを取得してからその日付を比較する必要があるため、CPU(コスト)とパフォーマンスの両方の観点から、より多くの作業を行う必要があります。

編集

データがこれと同じくらい頻繁にアクセスされる場合は、他の設計オプションもある可能性があります。

まず、StatusオブジェクトをStatusUpdatesPerDayに結合することを検討できます。毎日、単一のインスタンスを作成し、そのオブジェクトにステータスの更新を追加します。これにより、数百回の読み取りが数回の読み取りに削減されます。

次に、ステータスの更新には頻繁にアクセスされるため、ステータスをmemcacheにキャッシュできます。これにより、コストと遅延が削減されます。

第三に、上記のように最適化しない場合でも、ndbにはキャッシュが組み込まれていると思います。この機能を使用したことはありませんが、実際の読み取り数は計算よりも少ない可能性があります。

4番目のオプションは、すべてのステータス更新を一度に表示しないようにすることです。たぶん、ユーザーは最後のいくつかだけを見たいと思うでしょう。次に、クエリカーソルを使用して、ユーザーが要求したとき(および要求した場合)に残りを取得できます。

于 2012-09-18T21:00:41.853 に答える