Redisを例に、分散システムキャッシュの詳細について説明しましょう。

Redisを例に、分散システムキャッシュの詳細について説明しましょう。

分散 Web プログラミングでは、高い同時実行性と内部分離を解決するための重要なテクノロジはキャッシュとキューと切り離せないものであり、キャッシュの役割はコンピュータ ハードウェアの CPU のさまざまなレベルのキャッシュに似ています。昨今、ビジネス規模が少し大きいインターネットプロジェクトであれば、初期のベータ版開発でもデザインは控えめなものになります。ただし、多くのアプリケーション シナリオでは、慎重な検討を必要とする特定の高コストの技術的問題も発生します。

このシリーズでは、分散システムにおけるサーバー側キャッシュ関連の技術を中心に取り上げ、友人との議論と合わせて私自身の考えの詳細についても触れていきます。記事内に不適切な点がありましたらご指摘ください。この記事はシリーズの最初の記事であり、キャッシュ自体の基本的な設計とアプリケーション、および関連する操作の詳細について、可能な限り詳しく説明することを目的としています (具体的なアプリケーションでは、主に Redis を例に挙げます)。

[[246387]]

1. サーバー側データキャッシュ

1 区別

さまざまな条件に基づいてキャッシュを分割する方法は多数あります。ローカル キャッシュと分散キャッシュは一般的な分類であり、どちらにも多くのサブカテゴリが含まれます。

ローカルは、プログラムが配置されているローカル サーバーを指すのではなく (厳密な意味で)、より細かくはプログラム自体の内部ストレージ スペースを指します。一方、分散は、プロセス外部の 1 つ以上のサーバー上の、相互に通信するストレージに重点を置いています。特定のソフトウェア プロジェクトの設計と適用では、これらが混在することがよくあります。もちろん、個人的にはキャッシュの本質を理解することが最も重要だと考えています。概念的な分類に関しては、それは単に異なる理解に基づいた区分にすぎません。

2技術的なコスト

特定のプロジェクト アーキテクチャを設計する場合、前者 (ローカル キャッシュ) を単純に使用した場合の開発コストは間違いなく非常に低く、主な考慮事項はローカル メモリの負荷または非常に小さなディスク I/O の影響です。後者の設計の本来の目的は、分散プログラム間でキャッシュされたデータを効率的に共有および管理できるようにすることです。設計では、キャッシュが配置されているサーバーのメモリ負荷を考慮するだけでなく、シナリオによっては、ネットワーク I/O、CPU 負荷、ディスク I/O のコストも十分に考慮する必要があります。同時に、特定の設計では、全体的な安定性と効率性を可能な限り回避し、バランスをとるように努めています。これらは、キャッシュ サーバーのハードウェア コストと技術的なメンテナンスだけではありません。慎重に検討する必要がある根本的な問題には、キャッシュ間通信、ネットワーク負荷、レイテンシ、およびさまざまなトレードオフを必要とするその他の詳細が含まれます。

実際、キャッシュの本質を理解していれば、あらゆるストレージ メディアが適切なシナリオで効率的なキャッシュとして機能し、プロジェクト統合とキャッシュ クラスタリングを実行できることがわかります。一般的に主流となっている Memcached や Redis は後者に属し、NoSQL をベースに設計された MongoDB などのドキュメント データベースも含まれることがあります (ただし、これは役割の観点からであり、狭義にはディスクベースのリポジトリです。それぞれに特化していることに注意が必要です)。

これらのサードパーティ キャッシュでは、プロジェクトの統合やキャッシュ間のクラスタリングを実行するときに、いくつかの問題を解決する必要があります。プロジェクトのイテレーションが後期段階に至っても、より高度な専門知識を持つ運用・保守担当者の同時参加が求められることが多く、開発プロセスにおけるロジック設計やコード実装も一定程度作業負荷が増加します。したがって、特定のプロジェクトを設計する際には、一方では可能な限り余裕を持たせる必要があり、他方では実際の状況に基づいて可能な限り簡素化する必要がある場合もあります。

追加の経験をいくつか共有しましょう。私の限られた技術的学習と実践では、ノード データの相互作用、特にサービス間の通信に関して、完全な閉ループは存在しません。理論的には、それは「現在の段階」(おそらく人生と同じ)における「高い一貫性」に向けた単なるトレードオフです。

2. キャッシュデータベース構造の設計詳細

私の仕事では Redis 3.x がほとんど使用されているため、以下に機能に関する説明がある場合は参考にさせていただきます。

1 インスタンス

ビジネス シナリオに応じて、パブリック データとビジネス関連データに異なるインスタンスを使用する必要があります。単一インスタンスの場合は、DB によるパーティション分割を検討できます。 Redis を使用する場合、Redis の DB にはデータの分離がありますが、厳密な権限制限はないため、パーティション分割は単なるオプションになります。 Cluster クラスターでは、デフォルトの単一ライブラリが維持されますが、実際には、プロジェクトの規模や、どの開発段階で使用するかに応じて調整し、予約設計として使用します。

また、サーバーメモリに大きく依存するキャッシュ製品であるため、永続性が有効になっている場合(後述)や、非常に高い同時実行性を持つサービスのサポートを提供する場合、大量のサーバーハードウェアリソースが占有されることにも注意が必要です。永続性ポリシー構成と組み合わせて、インスタンスに別のディスク ストレージを使用するかどうかを検討してください。

永続性の本質は、メモリ データをハード ディスク (フラッシュ ディスク) に同期的に書き込むことですが、ディスク I/O は実際には制限されています。強制的な書き込みブロックは、スレッドのブロックとサービスのタイムアウトを引き起こすだけでなく、追加の例外も発生させ、他の基礎となる依存サービスにも影響を与えます。もちろん、条件が許せば、プロジェクトの初期設計時に計画して決定するのが最善であるというのが私の提案です。

2 キャッシュ「テーブル」

一般的に、キャッシュには従来の RDBMS の直感的なテーブル概念はありません (多くの場合、キーと値のペア「KV」の形式で存在します) が、構造的に言えば、キーと値のペア自体はさまざまなテーブル構造に組み立てることができます。一般的には、まずデータベース テーブル関係図を生成し、次に文字列をいつ保存し、オブジェクトをいつ保存するかを分析し、キャッシュ キー (KEY) を使用してテーブルとフィールド (列) を分割します。

フィールド (列): name、sign、addr を含むログイン サーバー テーブル データを保存する必要があると仮定すると、データ構造を次の形式に分割することを検討できます。

  1. {キー: "server:name" 、値: "xxxx" }
  2. {キー: "server:sign" 、値: "yyyy" }
  3. {キー: "server:addr" 、値: "zzzz" }

なお、Redis などの分散キャッシュ製品では、複数のデータ構造(String、Hash など)が存在することが多く、データの相関関係や列数に応じて、対応するキャッシュ ストレージ データ構造を選択する必要があることに注意してください。関連するストレージスペースと時間の複雑さがまったく異なるため、初期段階ではこれを実感することは困難です。

同時に、キャッシュメモリを十分に大きく設定し、空きメモリが多い場合でも、RDBMS と同様の単一テーブル容量の問題も考慮する必要があります。制御エントリの数は無制限に増加することはできません (たとえば、ストレージ エントリが簡単に数百万に達すると予測される場合など)。 「データベースとテーブルを分割する」という設計思想は同じです。

3 キャッシュキー

前述のように、テーブルはキャッシュ キーに基づいて設計されます。ここではキー関連の個人仕様について個別に説明します。キーの長さが十分に短いことを前提として、同じ業務モジュールが関連付けられている場合は、検索や統計管理を容易にするために、同じ識別子(コード)で始まるように設計する必要があります。

たとえば、ユーザーはサーバー リストにログインします。

  1. {キー: "ul:server:a" 、値: "xxxx" }
  2. {キー: "ul:server:b" 、値: "yyyy" }

さらに、各独立したビジネス システムでは、一意のユニバーサル プレフィックス識別子を構成することを検討できます。もちろん、これは必要ありません。実際の作業で異なるライブラリを使用する場合は無視できます。

4 キャッシュ値

キャッシュ内の値のサイズ (ここでは単一のエントリを指します) に平均的な標準はありませんが、サイズは当然可能な限り小さくなります (Redis を使用する場合、操作の値が大きいと、ネットワーク I/O だけでなく、Redis 全体の応答時間に直接影響します)。占有されているストレージ容量が 10M 以上に達する場合は、関連するビジネス シナリオをホットスポット データと非ホットスポット データに分割できるかどうかを検討することをお勧めします。

5永続性

上記で簡単に述べたように、一般的に言えば、永続性とキャッシュ自体には直接的な関係はありません。大まかに言えば、1 つはハードディスク向け、もう 1 つはメモリ向けであると想像できます。ただし、今日の Web プロジェクトでは、一部のビジネス シナリオがキャッシュに大きく依存しています。永続性により、再起動後のキャッシュ サービスの迅速な回復が改善され、特定のシナリオにストレージ機能が提供されます。もちろん、永続性を確保するには、CPU プリエンプションやハード ディスク I/O への影響など、パフォーマンスをある程度犠牲にする必要があります。しかし、ほとんどの場合、利点は欠点を上回ります。キャッシュを適用する場合は、特別な状況がない限り、独自のメカニズムを使用して実装されているか、サードパーティを使用して実装されているかに関係なく、永続性を使用することをお勧めします。

Redis を使用している場合、AOF や RDB などの独自の永続化戦略があります。ほとんどの場合、両方を同時に構成します (もちろん、最新の公式バージョンではハイブリッド モードも提供されています)。同時実行性が高くないシナリオや、中小規模のプロジェクトの管理モジュールで最適化手段としてのみ使用され、永続性が不要であると判断された場合は、パフォーマンスのオーバーヘッド損失を抑えるために直接閉じるように設定できますが、インスタンスのパブリック使用範囲を確保するために、プログラム内でインスタンスをマークすることをお勧めします。

6排除する

キャッシュが無制限に増大すると、有効期限を短く設定したとしても、ある時点で、同時実行性の高い大量のデータのバッチが短期間で使用可能なメモリのピークに達します。このとき、プログラムとキャッシュ サーバー間のやり取りに多くの遅延とエラーが発生し、サーバー自体に深刻な不安定性を引き起こすこともあります。したがって、実稼働環境では、キャッシュの最大メモリ制限と適切な削除戦略を構成するようにしてください。

Redis を使用すると、独自の除去戦略の選択がより柔軟になります。

私の個人的な設計では、データがべき乗分布を示す場合、アクセスの少ない大量のデータが常に存在することになります。最もアクセスが少ないデータを削除するために、allkeys-lru と volatile-lru を構成することを選択します。たとえば、キャッシュをログ アプリケーションとして使用する場合、通常はプロジェクトの初期段階では no-enviction を設定し、後期段階で volatile-ttl を設定します。

もちろん、キャッシュを軽量の永続データベースとして直接使用し、それが端末となる特殊なビジネス向けの設計も見たことがあります。最初は少し斬新だと感じましたが、後になってビジネス設計と非常に一致していることがわかりました(たとえば、複雑なロジックはほとんどなく、トランザクションが強力です)。したがって、それは合理的であり、伝統的なデザインに限定されるべきではありません。結局のところ、アーキテクチャは常にビジネスに基づいてリアルタイムで組み合わせられ、変更されます。

3. CURDの基本と1次キャッシュの関連情報

1追加(作成)

特別なビジネス要件(上記など)がない場合は、挿入時に有効期限を設定する必要があります。同時に、有効期限のランダム性を確保するようにしてください。バッチ キャッシュを実行する場合、私の個人的なアプローチは、キャ​​ッシュ アバランシェのリスクと影響を軽減するために、有効期限が少なくとも分散されるようにすることです (これについては、後の拡張で説明します)。

たとえば、バッチ キャッシュの対象は、100,000 エントリと 60*60*2 (秒) のキャッシュ時間基準の結果セットです。今ではそれらを同時にキャッシュする必要があります。私がやっていることは、デフォルトで random (範囲 0 - 1000) などの乱数を生成し、有効期限を (60*60*2 + random) に設定することです。

2更新

キャッシュされたデータを更新し、有効期限を再調整する必要があるかどうかを確認します。同時に、複数のキャッシュ間で同期する場合など、多くの状況では、キャッシュを更新するのではなく、キャッシュを直接削除することをお勧めします。変更操作は多くの場合、DB 間の同期操作に関連しており、比較的要求が厳しく、分散トランザクションの問題を検討する必要があります。これについては、後続の記事で説明します。

3読む

キャッシュを検索するときに、エントリが複数あり、データ量が多くない場合は、必ずキーに厳密に一致するパターンを使用し、ワイルドカードを使用しないようにしてください。送信コマンドのキーデータは長くなりますが、キャッシュ内の不要な検索パフォーマンスの低下は回避されます。

たとえば、Redis 独自のストレージ最適化を単純に信頼し、時間の複雑さを考慮せずにキー パターンを制限なしで使用すると、多数のスレッドがブロックされることになります (これはマスター スレーブ レプリケーションとは関係ありません)。妥協して代わりにスキャン ページングを使用する場合、それは「心配のない」実装ではありません。まず、プログラム コードのカプセル化でより低い容量を設定する必要があります。次に、プログラムロジック内でデータのファントム読み取りなどの潜在的な問題に対して、適切な制御と処理を必ず行ってください。

もう 1 つの例えは、DB 内の大きなテーブルを操作する場合、ホットスポット データ ヒットが後方に分散されることです。

4削除/クリア

キャッシュを削除するには、通常、直接削除する方法と有効期限を設定する方法(常に有効期限を長くするスライドではない)の 2 つの方法があります。詳しい説明はありません。しかし、類似したデータのバッチが要求され、即時性に対する高い要件がない特殊なビジネス シナリオがあると聞いたことがあります。有効期限が設定されており、その時間は若干ばらつきます。

キャッシュをクリアします。私はまだこれをプロジェクトに適用していませんし、直接使用することもお勧めしません。ただし、使用する場合は、2つの側面を慎重に考慮する必要があります。1つはクリーンアップのタイミング、もう1つはクリーンアップの適時性です(Redisの場合、flushdbでもflushallでも、一定のブロックが発生します)

5. ロック/シグナル(ロック)

これはキャッシュ自体とは関係ありませんが、いくつかの同時実行機能の実装に属し、特定の適用可能なシナリオがあります。これには Redis でのアトミックベースの実装がいくつかありますが、このシリーズの議論には関係ありません。

6パブリッシュ・サブスクライブ

なぜ、Produce-Consume に関連するこのアクションについて言及するのでしょうか?このメカニズム自体はキャッシュ自体の範囲には属しませんが、メッセージ キューに関連しています。これを言及する理由は、今日の主流のキャッシュ製品にはすべてこの機能が組み込まれているため、多くのシナリオで使いやすく、構成が簡単で、効率が十分に高速になるからです。しかし、それはしばしば虐​​待につながります。最も重要なことは、不必要な強い結合によって全体的な柔軟性とパフォーマンスも低下し、スケーラビリティも非常に制限されるということです。もちろん、これは私の現在の意見です。

私の提案は、特別なシナリオアプリケーションがない場合は、使用しないようにすることです。少なくとも、最初にキャッシュ独自のパブリッシュ/サブスクライブ機能を使用することはお勧めしません。キャッシュ クラスター システムでも、考慮すべき詳細事項がさらにあります。

推奨されるアプローチは、MQ ベースの代替製品など、他の専門的なミドルウェア ソリューションを使用することです。具体的な候補としては、友人が言っていた中国の Alibaba がここ 2 年で開発した RocketMQ をはじめ、RabbitMQ、Kafka などの優れたオープンソース作品が挙げられますが、私がよく使うのはやはり RabbitMQ です。もちろん、ここではあまり詳しく説明しません。シナリオに応じて最も適切な技術的ソリューションを選択するだけです。

この記事はここで終わります。次の記事では、関連するトピックについて詳しく説明します。私の個人的な能力と経験は限られているため、私も学びと実践を続けています。記事中に不適切な点がありましたらご指摘ください。

<<:  エッジコンピューティングはクラウドの終焉を意味するのでしょうか?

>>:  デスクトップ仮想化における3D仮想化ソリューションの体験概要

推薦する

草の根ウェブマスターは、検索エンジンアルゴリズムの頻繁な変更にどのように対処できるでしょうか?

インターネットに注目している友人は、最近、Google のランキング アルゴリズムの考え方が変わり、...

#BlackWeek5#: webhostingbuzz - 仮想ホスト 50% オフ/VPS 50% オフ/サーバー 50% オフ

私たちのお気に入りの webhostingbuzz のブラックフライデーセールが始まりました。このセ...

Zhihui Huayun: カーネルバイパス技術の紹介と Ceph でのその応用

クラウドコンピューティング事業の急速な発展に伴い、国内外のクラウドコンピューティング企業間の特許紛争...

「剣ネット作戦」は183の違法サイトを閉鎖し、282件の海賊版事件を捜査した

12月28日の鳳凰科技報によると、今朝、国家著作権局と他の4つの部門が共同で、2012年の「剣ネット...

Bilibiliは積極的に収益化していますか?

Bilibiliは重大な岐路に立たされている。コンテンツに固執すべきか、それとも積極的に収益化すべき...

淘宝、抖音、快手の一流アンカーが「撤退」

インターネット界のゴッドファーザー、ケビン・ケリーはかつてこう言った。「注目が集まるところに、お金は...

ヤフーの取締役会がマイクロブログサイトTumblrの11億ドルの買収を承認

[Caixin.com] (MarketWatch-Ruth Mantell) ウォールストリート・...

大失敗: 有名インターネット企業の失敗から学ぶ教訓

Kaixin、BYD、ITAT、The9、ZCOM、Yanhuang Media、Changshen...

火星から生中継?中国の火星探査プロジェクトのクラウド監視機能を果たす方法

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

ハイブリッドクラウドと人工知能に賭けるIBMの分社化は成功できるか?

[[346377]]建国記念日を前に、NVIDIA による ARM 買収のニュースはテクノロジー界で...

SaaSとデータ復旧に関する誤解

クラウドベースのアプリケーションは、現在、グローバルなビジネスと業務にとって不可欠です。しかし、Of...

高品質なWebサイトの夢を成功に導く、高品質なWebサイト制作の3つの秘訣(後編)

高品質サイトの作成に関するこれまでの 2 つの記事は、多くのウェブマスターから支持を得ています。本日...

SpringBoot は Kafka を統合して高いデータスループットを実現します

1. はじめに前回の記事では、Kafka のアーキテクチャモデルについて詳しく紹介しました。クラスタ...

JD.comがWeChatでPinduoduoを「コピー」

PingouからJingxiまで、 JD.comはPinduoduoを「ピクセルレベル」でコピーしま...