マルチレベルキャッシュアーキテクチャ設計

前もって言う

40 歳の建築家 Nien の読者コミュニティ(50 歳以上)では、多くの友人が Alibaba、NetEase、Youzan、Xiyin、Baidu、NetEase、Didi などの一流インターネット企業の面接資格を取得し、非常に重要な面接の質問が数多くありました。

  • 20w QPS のシナリオでは、サーバー アーキテクチャはどのように設計されるべきですか?
  • 10w QPS のシナリオでは、キャッシュ アーキテクチャはどのように設計されるべきですか?

Nien 氏は、キャッシュ アーキテクチャ、キャッシュ プランニング、キャッシュの削除、マルチレベル キャッシュのデータ整合性に関連する問題は、アーキテクチャと主要なオンライン問題に関する中心的な知識であることを思い出させました。

さらに、ニエンは履歴書や構造改革について全員に指導を行っています。数日前、私は Meituan のスーパーボスである L9 の履歴書を指導していましたが、彼もキャッシュに関するこれらの問題について話しており、次のような解決策を提供する必要があると話していました。

  • まずは学習教材
  • 2 番目: 建築用車輪。

上記の理由を踏まえ、Nien では、「JD サーバー アプリケーション マルチレベル キャッシュ アーキテクチャ ソリューション」と「Youzan 透過的マルチレベル キャッシュ ソリューション (TMC)」をベースに体系的かつ系統的にレビューを行います。そのため、面接ではその強力な「技術力」を遺憾なく発揮し、面接官を「思わずよだれが出る」ほどにさせることができます。

この質問と参考回答は、全員の 3 レベルのアーキテクチャ、設計、開発レベルを向上させるために、後続の友人が参照できるように、Nion Java インタビュー ガイド」の V105 バージョンにも含まれています。

『Nien Architecture Notes』、『Nien High Concurrency Trilogy』、『Nien Java Interview Guide』の PDF は、公式アカウント [Technical Freedom Circle] から入手してください。

同時実行性の高いシナリオ分析

一般的に10Wqpsや20Wqpsであれば分散キャッシュで耐えられます。

たとえば、redis クラスターには 6 つのマスターと 6 つのスレーブがあります。マスターは読み取りと書き込みを提供し、スレーブはバックアップとして機能し、読み取りと書き込みサービスを提供することはありません。

6 つのマスターと 6 つのスレーブ アーキテクチャでは、1 つのユニットは平均 3w ~ 4W の同時実行に耐えることができ、また 18Wqps ~ 24Wqps にも耐えることができます。

さらに、QPS が 100 万に達すると、redis クラスター内のマシンの数を増やすことで、キャッシュ容量と同時読み取りおよび書き込み機能を拡張できます。6 マスターと 6 スレーブのアーキテクチャは、30 マスターと 30 スレーブまで拡張可能

同時に、キャッシュされたデータはアプリケーション間で共有され、マスター/スレーブ アーキテクチャにより高可用性が実現されます。

質問: キャッシュ ホットスポット (ホット キー) 問題を解決するにはどうすればよいですか?

キャッシュ ホット スポットが発生すると、たとえば 10 件のトラフィックが同じキーにアクセスし、特定の Redis インスタンスに集中すると、インスタンスの CPU 負荷が高くなりすぎる可能性があります。

この場合、Redisクラスタの数を増やしても根本的な解決にはなりません。では、ホットキーの問題を解決する効果的な方法は何でしょうか? 非常に効果的な手段の 1 つはローカル キャッシュです。主な理由は次のとおりです。 ローカル キャッシュにより、単一の Redis キャッシュ サーバーの高負荷が回避されます。同時に、ネットワーク経由でデータを送信する必要がなく、データがアプリケーションのメモリに直接保存されるため、ローカル メモリ キャッシュのアクセス速度が速くなります。

ローカル キャッシュの本質:時間とスペースを交換する複数のコピーです複数のキャッシュ コピーを複製してリクエストを分散すると、キャッシュ ホットスポットによって引き起こされる単一のキャッシュ サーバーへの負荷を軽減できます。

何事にも長所と短所があります。

では、ローカルキャッシュの導入によりどのような問題が生じるのでしょうか? 主な問題は次のとおりです。

  • データの一貫性の問題
  • ローカルキャッシュデータ汚染問題

上記 2 つの質問については、Nien の以前の記事「シナリオの質問: 100,000 人が突然訪問したと仮定すると、システムは雪崩をどのように回避できますか?」を参照してください。"では、Youzan の透過的なマルチレベル キャッシング ソリューション (TMC) に基づいて、包括的なレビューを提供しました。

しかし、将来のスーパーアーキテクトとして、私たちは何百もの学派の長所から学び、技術的な視野を広げる必要があります。

したがって、ここでは「JD サーバー アプリケーションのマルチレベル キャッシュ アーキテクチャ計画」に基づいた別の記事を紹介します。オリジナルの JD サーバー アプリケーションのマルチレベル キャッシュ アーキテクチャ ソリューション | JD Cloud 技術チーム。

ユニバーサルなマルチレベル キャッシュ ソリューション

JD サーバーは、マルチレベル キャッシュ アーキテクチャ ソリューションを使用します。これは、実際には一般的に使用されるレベル 2 キャッシュ アーキテクチャ ソリューションです。

(1) L1 レベル 1 キャッシュ: ローカル キャッシュ guava

(2) L2二次キャッシュ:分散キャッシュredis

レベル 2 キャッシュ アーキテクチャ方式のキャッシュ アクセス プロセス:

  • リクエストは最初にアプリケーションのローカル キャッシュに送信されます
  • ローカル キャッシュが存在しない場合は、redis クラスターに移動してキャッシュを取得し、同時にローカルにキャッシュします。

上記のプロセスは、キャッシュ アサイド キャッシュ モードと同様です。具体的なキャッシュアクセスのプロセスはおおよそ次のとおりです。

DB キャッシュと Redis キャッシュ間のキャッシュ アサイド キャッシュ モードにおけるデータの整合性の問題については、Nien の「Java High Concurrency Core Programming Volume 3 Enhanced Edition」を参照してください。

では、ローカルキャッシュの導入によりどのような問題が生じるのでしょうか? 主な問題は次のとおりです。

  • データの一貫性の問題
  • ローカルキャッシュデータ汚染問題

マルチレベルキャッシュデータの一貫性の問題

マルチレベルキャッシュデータの一貫性の問題を解決するにはどうすればよいですか? 主に多値キャッシュです。主にパブリッシュ/サブスクライブ モードまたは基礎となるコンポーネントの RPC 通信メカニズムを使用して、ローカル キャッシュと Redis キャッシュ間のデータ同期を完了します。

  • JD.com はパブリッシュ/サブスクライブ モデルを使用しています。
  • Youzan が採用した基礎となるコンポーネントの RPC 通信メカニズム
  • J2cache はパブリッシュ/サブスクライブ モデルを使用します。

まずパブリッシュとサブスクライブについて見てみましょう。さらに詳しく見てみると、次の 2 つのモードがあります。

  • プッシュ モード: 各チャネルはクライアント リストを保持しており、メッセージが送信されると、リストが走査され、メッセージがすべての加入者にプッシュされます。
  • プル モード: 送信者はメッセージをメールボックスに入れ、メールボックスに登録しているすべてのクライアントがいつでもメッセージを受信できます。すべてのクライアントがメッセージ全体を正常に受信するまで、メッセージは削除されません。

まず、JD.com のデータ整合性の問題、つまりマルチレベルのキャッシュ同期ソリューションを見てみましょう。

  1. バックグラウンド操作では、データを保存し、Redis キャッシュに書き込み、Redis のパブリッシュおよびサブスクライブ機能を使用して情報を公開します。
  2. ビジネス アプリケーション クラスターは、メッセージ サブスクライバーとして、運用データ メッセージを受信した後、ローカル キャッシュを削除します。
  3. C 側のトラフィック要求が到着したときに、ローカル キャッシュが存在しない場合、キャッシュは Redis からローカル キャッシュにロードされます。
  4. 極端な状況下で Redis キャッシュが無効になるのを防ぐために、スケジュールされたタスクを通じてデータを Redis キャッシュに再ロードできます。

次に、Youzan のデータ整合性の問題を見てみましょう。通信モジュールを使用して各ノード間のデータ整合性を実現します

具体的な紹介については、Nien の二次創作記事「シナリオの質問: 100,000 人が突然訪問すると仮定すると、システムは雪崩をどのように回避できますか?」を参照してください。"では、Youzan の透過的なマルチレベル キャッシング ソリューション (TMC) に基づいて、包括的なレビューを提供しました。

さらに、業界には成熟した二次キャッシュ ミドルウェアがいくつかあり、主にメッセージ キュー rocketmq/kafka を使用して、ローカル キャッシュと分散キャッシュ間のデータの一貫性を実現します。このアーキテクチャ ソリューションの詳細については、Nien のアーキテクチャ ビデオ「100Wqps レベル 3 キャッシュ コンポーネントの実践動作」を参照してください。

Jingdong パブリッシュ サブスクライブ キャッシュ同期コンポーネントの選択

Jingdong は、Redis のチャネル メカニズムを使用して、ローカル キャッシュと Redis キャッシュ間のデータ同期を完了します。Redis チャネル メカニズムでは、パブリッシュ/サブスクライブ モデルはプッシュ モデルです。

  • SUBSCRIBE コマンドを使用すると、1 つ以上のチャネルに登録して、関連するチャネルがメッセージをパブリッシュしたときに通知を受け取ることができます。
  • PUBLISH コマンドは、1 つ以上のチャネルにメッセージを送信するために使用されます。メッセージがチャネルに公開されると、そのチャネルに登録しているすべてのクライアントが対応する通知を受け取ります。

さらに、Redis のパブリッシュ/サブスクライブ モデルは非同期です。メッセージがチャネルにパブリッシュされると、Redis はそのチャネルにサブスクライブしているすべてのクライアントにメッセージを非同期的にプッシュします。これは、クライアントがメッセージの待機中にブロックされず、他のタスクの実行を継続し、受信する必要がある場合にのみメッセージを取得することを意味します。この非同期アプローチは、システムの同時実行性と効率の向上に役立ちます。

キャッシュ汚染問題とは何ですか?

ローカルキャッシュの導入によりどのような問題が生じるのでしょうか? 主な問題は次のとおりです。

  • データの一貫性の問題
  • ローカルキャッシュデータ汚染問題

先ほど、データの一貫性の問題について説明しました。キャッシュ汚染の問題を見てみましょう。

キャッシュ汚染問題とは、キャッシュ内に残り、実際には再度アクセスされないにもかかわらず、キャッシュ領域を占有するデータを指します。

このようなデータの量が大きい場合、またはキャッシュがいっぱいになる場合は、新しいデータがキャッシュに書き込まれるたびに、データをキャッシュから段階的に削除する必要があり、キャッシュ操作の時間オーバーヘッドが増加します。

したがって、キャッシュ汚染問題を解決するには、一度または数回しかアクセスされないデータを特定し、データを削除する際に優先順位を付けて削除することが最も重要な技術となります。したがって、キャッシュ汚染を解決するための中心的な戦略は次のように呼ばれます。

キャッシュ内で一般的に使用される主なキャッシュ削除戦略は次のとおりです。

  • ランダム ランダム
  • るー
  • ルフ

(1) Random: 主に volatile-random と allkeys-random を含む、削除するデータをランダムに選択します。volatile-random や allkeys-random などのランダムな削除では、アクセスされなくなったデータをフィルターで除外することができず、キャッシュ汚染を引き起こす可能性があります。

(2) LRU: LRU アルゴリズムの基本的な考え方は、キャッシュ領域が不十分な場合、最も最近使用されていないキャッシュ項目、つまりアクセス時間が最も長いデータ項目を削除する必要があるということです。これにより、最も一般的に使用されるデータ項目が常にキャッシュに保持されるため、システムの応答速度とスループットが向上します。LRU ポリシーはデータのアクセス適時性のみを考慮するため、LRU ポリシーは一度しかアクセスされないデータを迅速にフィルターで除外することはできません。

(3) LFU戦略はLRU戦略に基づいて最適化されており、データをフィルタリングする際、最初に訪問数が少ないデータをフィルタリングして削除し、次に同じ訪問数のデータのうちアクセス時間が最も長いデータをフィルタリングして削除します。 。

実際のビジネス アプリケーションでは、LRU 戦略と LFU 戦略の両方が適用されます。

LRU と LFU の 2 つの戦略は、異なるデータ アクセス特性に焦点を当てており、LRU 戦略ではデータの適時性がより重視され、LFU 戦略ではデータ アクセスの頻度がより重視されます

通常の状況では、実際のアプリケーションの負荷は時間局所性が優れているため、LRU 戦略がより広く使用されることになります。

ただし、スキャン クエリのアプリケーション シナリオでは、LFU 戦略はキャッシュ汚染の問題に効果的に対処できるため、最初に LFU 戦略を使用することをお勧めします。

Jingdong のローカル キャッシュは guava を使用しているため、戦略は LRU です。LRU 戦略はデータの適時性により注意を払い、時間局所性が高く、ほとんどのデータ シナリオで使用されます。

ほとんどのローカル キャッシュではカフェインの使用が推奨されるため、戦略は LRU+LFU です。これは時間的局所性が高く、ほとんどのデータ シナリオで使用できます。また、スキャン クエリ アプリケーション シナリオにおけるデータ汚染の問題を回避するために、データのアクセス頻度にも注意を払います。具体的な原理については、Nien の「100Wqps レベル 3 キャッシュ コンポーネント」ビデオを参照してください。このビデオでは、カフェインの内部原理とアーキテクチャが詳しく紹介されており、カフェインのパフォーマンスもグアバよりも優れています。

マルチレベルキャッシュアーキテクチャに関する考慮事項

  1. ローカル キャッシュは Java プロセスの JVM メモリ領域を占有するため、大量のデータの保存には適しておらず、キャッシュ サイズを評価する必要があります。
  2. ビジネスが短期間にデータの不整合を許容できる場合は、シナリオの読み取りにはローカル キャッシュの方が適しています。
  3. キャッシュ更新戦略では、アクティブな更新であってもパッシブな更新であっても、ローカル キャッシュに有効期間を設定する必要があります。
  4. 極端な場合のデータ損失を防ぐために、スケジュールされたタスクを設定してキャッシュを同期することを検討してください。
  5. RPC 呼び出しでは、ローカル キャッシュの汚染を避ける必要がありますが、この問題は合理的なキャッシュ削除戦略によって解決できます。
  6. アプリケーションを再起動するとローカルキャッシュが無効になるため、分散キャッシュを読み込むタイミングに注意する必要があります。
  7. パブリッシュ/サブスクライブを通じてデータの一貫性の問題を解決する場合、パブリッシュ/サブスクライブ モードでメッセージ データが保持されず、メッセージが失われた場合、ローカル キャッシュの削除に失敗します。したがって、メッセージのパブリッシュおよびサブスクライブの高可用性の問題を解決する必要があります。
  8. ローカル キャッシュに障害が発生した場合は、同期ロックを使用して、同時更新を避けるために Redis キャッシュが 1 つのスレッドによってロードされるようにする必要があります。

最後に: 質問がある場合は、古いアーキテクチャにアドバイスを求めることができます。

建築の道は山あり谷あり

アーキテクチャは高度な開発とは異なります。アーキテクチャの問題はオープン/開発指向であり、アーキテクチャの問題に対する標準的な答えはありません。

このため、多くの友人は多大なエネルギーとお金を費やしたにも関わらず、残念ながら一生のうちにアーキテクチャのアップグレードを完了することができません

したがって、アーキテクチャのアップグレード/変革のプロセスにおいて、どうしても効果的な解決策が見つからない場合は、40 歳の建築家 Nien に助けを求めることができます。

昨日、友人からe コマース ウェブサイトのゴールデン リンク構造を構築するように頼まれ、最初はアイデアが見つかりませんでしたが、10 分間ニンの音声ガイダンスを聞いた後、突然悟りを開いたようになりました。

参考文献

https://it.sohu.com/a/696701644_121438385

https://blog.csdn.net/crazymakercircle/article/details/128533821

推奨読書

100 億回の訪問、キャッシュ アーキテクチャの設計方法

メッセージプッシュアーキテクチャ設計

Alibaba 2: ノードは何台導入していますか?」1000W の同時実行を導入するにはどうすればよいですか?

Meituan 2 Sides: Five Nines 高可用性 99.999%。それを達成するにはどうすればよいですか?」

NetEase 側: シングルノード 2000Wtps、Kafka はどうやってそれを行うのですか?」

バイト側: トランザクション補償とトランザクション再試行の関係は何ですか?」

NetEase 側: Mysql への 25Wqps の高スループット書き込み、100W データが 4 秒で書き込まれます。これを実現するにはどうすればよいですか?」

10億レベルのショートビデオをどのように構成するか? 」

爆上げ、「自慢」に頼ってJD.comを乗り切る、月給4万

あまりに過酷なので、『自慢』に頼ってSFエクスプレスを乗り切り、月収は3万です

爆発しました...Jingdongは片側で40の質問を要求し、それを通過した後、それは500,000以上でした

質問するのはもううんざりです...アリは命を懸けて27の質問をしました、そしてそれを通過した後の質問は60万以上です

Baiduは狂ったように3時間要求しました、Dachangはオファーを受け取りました、男は本当に冷酷です!」

Ele.me は残酷すぎる: 高度な Java に直面して、それがどれほど困難で残酷な作業であるか

Byte による 1 時間のクレイジーな質問の後、その男はオファーを受け取りました。それはとても残酷です!」

" Didi のオファーを受け入れる: この男の 3 つの経験から、何を学ぶ必要がありますか?

『Nien Architecture Notes』、『Nien High Concurrency Trilogy』、『Nien Java Interview Guide』PDF は、下記公式アカウント【Technical Freedom Circle】から入手してください ↓↓↓

おすすめ

転載: blog.csdn.net/crazymakercircle/article/details/132637261