前回は主に、キャッシュの読み取りと書き込みのさまざまなコード実装について説明しました。この記事では、前回の質問の続きとして、長年にわたるさまざまなキャッシュの使用状況を調べ続けます。
1: キャッシュのウォーミングアップ
前回、クラスメイトがそれについて質問しました。初めてロードするとき、キャッシュは空です。キャッシュをウォームアップする方法。
スタンドアロン Web の状況では、通常、RunTimeCache を使用します。この状況と比較すると:
1: 起動イベントで更新できます
void Application_Start(object sender, EventArgs e) { //刷新 }
2: 単一の更新キャッシュ ページを作成するか、オンラインになった後に手動で更新するか、公開時に自動的に更新を呼び出すか、単にユーザーによってトリガーされます。
分散キャッシュ (Redis、memcached) の場合:
例: 数十台のサーバーがキャッシュする場合、キャッシュだけを埋めるのにかなりの時間がかかります。
この種の予熱はもう少し複雑で、それを実行するアプリケーションを作成する人もいますが、それを (よりインテリジェントに) 処理するフレームワーク メカニズムを作成する人もいます。
目的はオンラインになる前です。すべてのキャッシュが事前にロードされます。
2: マルチレベルキャッシュ
2.1 はじめに
一般に、交換速度を向上させるために、CPU とメモリの間に 1 次キャッシュと 2 次キャッシュがあることがわかっています。
このようにして、CPU が大量のデータを呼び出すときに、メモリを回避して CPU キャッシュから直接呼び出すことで、読み取り速度を高速化できます。
CPU キャッシュに基づくマルチレベル キャッシュの特徴:
1: キャッシュの各レベルは、次のレベルのキャッシュの一部を格納します。
2: レベルごとに読み取り速度が順次低下し、コストも順次低下し、容量が順次増加します。
3: 現在のレベルがミスした場合、次のレベルに移動して検索します。
エンタープライズ アプリケーション レベルの開発では、マルチレベル キャッシュの使用の目的と設計は同じですが、粒度はより粗く、より柔軟です。
速度に従って整理されたlv1〜lv6のキャッシュタイプ図:
レベル3キャッシュのヒットフローチャートの例:
2.2 スレッドキャッシュ
Webアプリケーションは本質的にマルチスレッドです。一部のパブリック リソースでは、スレッドの安全性を考慮する必要があり、これまでのところ、データの整合性と正確性を確保するためにロックを使用する必要があります。
実際には、Web サーバーは少なくとも数百または数千のリクエストを処理する必要があります。考えてみてください。複雑なビジネス プロセスでは、関数が呼び出されるたびにロックする必要があります。
サーバーにとっても大きな無駄です。スレッド キャッシュにより、現在ユーザー リクエストを処理しているスレッドは、必要なものだけを受け取ることができます。
public static ThreadLocal<UserScore> localUserInfo = new ThreadLocal<UserScore>();
Net が提供するスレッド ローカル変数を使用すると、リクエスト エントリで現在のユーザーのデータを取得できます。
スレッドのライフサイクル全体において、ビジネス ロジックはスレッドの安全性を考慮することなく、このデータを心配することなく使用できます。
また、新しいデータを取得する必要がないため、データの破損を心配する必要もありません。
現在のスレッド サイクルのデータは完全かつ正確であり、ユーザーが 2 回目にリクエストを開始した場合にのみ新しいデータが取得されるためです。
これにより、サーバーのスループットが大幅に向上します。スレッドの終了時にデータが破棄されることに注意してください。
2.3 メモリキャッシュ
リモートデータベースの読み取りであっても、キャッシュサーバーの読み取りであっても。プロセス、ネットワーク、場合によってはコンピューター室を越えて通信することは避けられません。
アプリケーションの頻繁な読み書きはWebサーバーやDBサーバーに多くのコストを消費し、速度はメモリよりもはるかに遅くなります。
コードにロック、非同期、さらにはサーバーを追加することはお勧めできません。読み込み速度はユーザーエクスペリエンスにとって非常に重要であるためです。
そのため、ローカルメモリを必要とするプロジェクトでは、二次キャッシュにローカルメモリを使用することが非常に必要です。目的は 1: 同時実行防止、2: 読み取りの高速化です。
有名な 5 分間キャッシュ ルールがあります。これは、データが頻繁にアクセスされる場合はメモリに配置する必要があることを意味します。
例: 同時リクエストが 100 件ある場合、ロックにより 99 個のフロントエンド スレッドが待機することになり、待機しているこれらの 99 個のスレッドが実際に Web サーバーのリソースを消費します。これを追加しないとキャッシュ雪崩が起こります。
1分ごとにキャッシュをプルしてメモリにキャッシュすると、99スレッドの待ち時間が大幅に短縮されます。
2.4 ファイルキャッシュ
メモリに比べてハードディスクの容量が大きく、インターネットを使用するよりも高速です。
そのため、頻繁に変更されず、メモリ内で無駄になっている一部のデータをローカル ハードディスクにキャッシュできます。
たとえば、いくつかのファイルデータベースにsqliteを使用すると、それを簡単に実行できます。
2.5 分散キャッシュ
メモリキャッシュに基づくRedis、memcachedなど。
ファイル nosql に基づく Casssandra、mongodb など。
redis と memcached は主流の分散メモリ キャッシュであり、アプリケーションと DB の間の最大のキャッシュ レイヤーでもあります。
nosql は実際にはキャッシュに使用されるだけでなく、一部の非中核ビジネスの DB 層でも使用されます。
2.6 DBキャッシュ
このDBの層は主に元のデータから計算された結果をキャッシュします。また、SQL を介した Web プログラムによる直接計算や使用は避けてください。
もちろん、計算されたデータをキャッシュのために Redis に保存することもできます。
3: マルチレイヤーキャッシュ
マルチレイヤーキャッシュの概念は多くの場所で使用されています:
1: 上で述べたマルチレベルキャッシュは、コンテンツを異なるキャッシュに分割するキャッシュの一種です。読み取り頻度レベルに基づいて、頻度が高くなるほど、階層型ストレージに近づきます。
2: B ツリー検索と同様に、検索効率を向上させることができる多層キャッシュ インデックスのアプローチもあります。
3: アーキテクチャ的に言えば、クライアント キャッシュ、CDN キャッシュ、リバース プロキシ キャッシュ、サーバー キャッシュもマルチレイヤー キャッシュです。
4: まとめ
使用に関しては、誰もが実際のシナリオに基づいてさまざまな組み合わせを行うことができます。この記事はより理論的なものであり、多くの詳細は詳しく説明されていません。
たとえば、分散キャッシュの使用、キャッシュ置換戦略とアルゴリズム、キャッシュ有効期限メカニズムなど。今後も追加していきます。