私はキャッシング (主に redis と memcached) を調べてきましたが、データが絶えず変化しているときにキャッシングを正確に使用する場所を見つけるのに苦労しています。
Twitter を例にとります ( Twitter を 10000% 速くする を読んでください)。データベース レコードの大部分が絶えず変更されている場合、どのようにデータをキャッシュしますか (またはキャッシュしますか?)
Twitter には次のモデルがあるとします: User
、Tweet
、。Follow
Favorite
1 日に 1 回リツイートされるツイートを投稿する人もいれば、1 日に 1000 回リツイートされるツイートを投稿する人もいます。その 1000 回のリツイートの場合、24 * 60 == 1440
1 日は約数分あるため、ツイートがほぼ毎分更新されたことを意味します (440 のお気に入りも獲得したとします)。誰かをフォローするのと同じように、チャーリー・シーンは1 日で 100 万人の Twitter フォロワーを獲得しています。このような場合にキャッシュする価値はないように思われますが、まだそのレベルに達していないためかもしれません。
また、平均的な Twitter フォロワーは、少なくとも 1 日に 1 回はツイート/フォロー/お気に入りのいずれかを行っているとします。つまり、単純な intro-rails スキーマの場合、users テーブルは少なくとも 1 日に 1 回更新されます (tweet_count
など)。このケースは、ユーザー プロファイルのキャッシュに適しています。
しかし、上記の 1000x ツイートと 100 万人のフォロワーの例では、データのキャッシュに関して推奨される方法は何ですか?
具体的には (memcached または redis を想定し、純粋な JSON API (ページ/フラグメント キャッシュなし) を使用する場合):
- 個々のツイート/記録をキャッシュしますか?
- それとも、ページネーションを介してレコードのチャンクをキャッシュしますか (たとえば、それぞれの redis リスト
20
)? - それとも、両方のレコードを個別に、またはページでキャッシュしますか (単一のツイートと JSON フィードを表示する場合)?
- それとも、ホーム タイムラインのツイート、ユーザーのツイート、ユーザーのお気に入りのツイートなど、さまざまなシナリオごとにツイートのリストをキャッシュしますか? それとも上記のすべてですか?
- または、データを「最も揮発性が高い (最新)」から「過去数日」、「古い」チャンクに分割します。「古い」データは、より長い有効期限でキャッシュされるか、個別のページ分割されたリストなどにキャッシュされますか? そして、最新のレコードはまったくキャッシュされません。(つまり、データがツイートのように時間に依存している場合、古いレコードがそれほど変化しないことがわかっている場合、別の方法で処理しますか?)
私が理解していないのは、データの変更量とキャッシュする必要がある場合の比率です (そして、キャッシュの有効期限が切れる複雑さに対処します)。Twitter は、さまざまなユーザーのツイート フィードとユーザーごとのホーム ツイートをキャッシュしているように見えますが、1 つのお気に入り/ツイート/リツイートのたびにキャッシュを無効にすると、それらすべてのキャッシュ アイテム (およびキャッシュされたレコードのリスト) が更新されることになります。ある時点で、キャッシュを無効にすることは非生産的であることを意味するように思えます。
このように大きく変化しているデータをキャッシュするための推奨される戦略は何ですか?