数百億回のアクセス、キャッシュ アーキテクチャの設計方法

前もって言う

40 歳の建築家、ニエンの読者コミュニティ(50 歳以上) では、最近、アリババ、ネットイース、ヨウザン、Xiyin、バイドゥ、ネットイース、滴滴出行などの一流インターネット企業の面接資格を取得した友人もいます。いくつかの非常に重要な面接の質問に答えました::

  • 分散キャッシュシステムをどのように構築するか?
  • 数百億のアクセスに対応するキャッシュ アーキテクチャを構築するにはどうすればよいでしょうか?

最近、Weibo の友人がまた次の問題に遭遇しました。数百億回の訪問に対応するキャッシュ アーキテクチャを構築するにはどうすればよいでしょうか?

次に、ニエン氏は Weibo キャッシュ アーキテクチャの設計実践事例を使用して、この質問に対する答えを明らかにします。

この記事は非常に重要です。誰もがそれを収集し、ゆっくりと消化してマスターすることができます。

なぜ?最新のインターネット アプリケーションでは、分散キャッシュがアプリケーションのパフォーマンスを最適化するための標準構成になっています。優れたキャッシュ システムは、高可用性、高性能を備え、データの一貫性とフォールト トレランスを保証できる必要があります。

この記事では、アーキテクチャの基本、アーキテクチャ全体の設計、実装原則、一貫性モデル、障害処理など、可用性の高い分散キャッシュ アーキテクチャを設計する方法を紹介します。

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

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

分散キャッシュ システム アーキテクチャの基礎知識

分散システムでは、キャッシュ システムの構築が重要なリンクであり、そのインフラストラクチャには主に次の重要な部分が含まれます。

  • データシャーディング

単一ノードへの過剰な負荷によるシステムのクラッシュを防ぐために、キャッシュされたデータをシャーディングする必要があります。このようにして、異なるキャッシュ ノードがそれぞれ異なるデータ スライスを管理し、関連する読み取りおよび書き込み要求の処理を担当することができます。このシャーディング方法は、データプレッシャーを効果的に分散するだけでなく、システムの応答速度も向上します。

  • 負荷分散

クライアントがリクエストを開始すると、それを処理するために適切なキャッシュ ノードを選択する必要があります。これには、現在のシステム負荷、ネットワーク トポロジ、その他の要因に基づいてリクエストの処理に最適なノードを選択できる負荷分散アルゴリズムの介入が必要です。このようにして、クライアント要求に対するタイムリーな応答を保証するだけでなく、ノードに対する過度の圧力がシステム全体の動作に影響を与えるのを防ぐこともできます。

  • フォールトトレランス

分散環境では、ネットワーク通信やその他の問題により、キャッシュ ノード間で障害が発生する可能性があります。システムの可用性を向上させるには、いくつかのフォールト トレラント メカニズムを設計する必要があります。たとえば、データのバックアップによりデータ損失を防ぐことができ、フェイルオーバーにより、ノードに障害が発生した場合でもシステムが動作し続けることが保証されます。これらのフォールト トレラント メカニズムにより、システムの安定性と信頼性が効果的に向上します。

  • データの一貫性

データは複数のノードに分散して保存されるため、データの一貫性を確保する必要があります。この目標を達成するには、同時読み取りおよび書き込み操作を処理するためにいくつかのプロトコルとアルゴリズムを採用する必要があります。たとえば、分散トランザクション プロトコルを使用してデータの原子性と一貫性を確保したり、オプティミスティック ロック アルゴリズムを使用して同時書き込み操作との競合を回避したりできます。これらの手段により、データの一貫性が効果的に確保され、システムの正しい動作が保証されます。

全体的なアーキテクチャ設計

高可用性と同時実行機能を備えた分散キャッシュ システムを構築する場合は、次の側面を考慮する必要があります。

  • キャッシュサービスノード

キャッシュ サービス ノードは、対応するデータ フラグメントを処理し、さまざまなキャッシュ操作にインターフェイスを提供する責任を負います。複数のキャッシュ サービス ノードを使用することで、キャッシュ クラスターを構築し、システムのスケーラビリティと可用性を向上させることができます。

  • 共有ストレージデバイス

共有ストレージ デバイスは、複数のキャッシュ サービス ノードで共有できるキャッシュ データとメタデータを保存するために使用されます。一般的な共有ストレージ デバイスには、分散ファイル システム、分散ブロック ストレージ、分散オブジェクト ストレージなどがあります。

  • 負荷分散装置

負荷分散デバイスの役割は、クライアントの要求を適切なキャッシュ サービス ノードに分散することであり、キャッシュ サービス ノードの負荷状態に基づいて動的に調整できます。

  • 設定サービス

構成サービスは、ノード情報、シャーディング情報、負荷分散ルール、フェイルオーバー設定などのキャッシュ システムのメタデータ情報を維持および管理する責任を負います。

実施原則

分散キャッシュ システムの実装には、データ シャーディング アルゴリズム、負荷分散アルゴリズム、フォールト トレラント処理アルゴリズム、整合性アルゴリズムなど、多くのテクノロジが必要です。

データシャーディングアルゴリズム

分散キャッシュ システムでは、データ シャーディング アルゴリズムが重要なテクノロジーです。一般的なデータ シャーディング アルゴリズムには、ハッシュ アルゴリズム、範囲アルゴリズム、逐次アルゴリズム、およびランダム アルゴリズムが含まれます。最も一般的に使用されるシャーディング アルゴリズムの 1 つであるハッシュ アルゴリズムは、ハッシュ関数を通じてデータのキー値を数値にマップし、この数値に基づいてシャーディングします。

  • 負荷分散アルゴリズム

負荷分散戦略は、キャッシュ システムにおいて重要な役割を果たします。キャッシュノードの負荷状況、ネットワークトポロジー、クライアントリクエストなど複数の要素を総合的に考慮する必要があります。一般的なロード バランシング戦略には、ラウンド ロビン戦略、最小接続数戦略、IP ハッシュ戦略、加重ラウンド ロビン戦略などが含まれます。

  • コンセンサスアルゴリズム

分散環境では、データの一貫性が重要な問題になります。複数のクライアントが同じキー値を同時に読み書きする場合、データの整合性を確保する必要があります。

一般的なコンセンサス アルゴリズムには、Paxos アルゴリズム、Raft アルゴリズム、Zab アルゴリズムなどが含まれます。

  • 強整合性と結果整合性の違い

強い一貫性とは、すべてのクライアントが同じキー値を読み取るときに同じ結果を得ることができることを意味します。最終整合性とは、クライアントがキャッシュ ノードにデータを書き込んだ場合、将来のある時点で、最終的にすべてのキャッシュ ノードが同じデータを持つことを意味します。

データをレプリケートすることで強い一貫性を実現できますが、これはシステムのパフォーマンスと可用性に影響を与える可能性があります。最終的な整合性は、非同期レプリケーションとプロトコル アルゴリズムを通じて実現できるため、システムのパフォーマンスと可用性がある程度向上します。

  • 失敗と例外を処理する方法

分散キャッシュ システムでは、障害と例外は避けられません。システムの可用性を確保するには、データのバックアップ、フェイルオーバー、データのリカバリ、アラームの監視など、障害や例外に対処するための一連の措置を講じる必要があります。同時に、システムの高可用性と高性能を確保するために、システムを定期的に保守および最適化する必要もあります。

分散キャッシュ システム アーキテクチャの概要

この記事では、アーキテクチャの基本、アーキテクチャ全体の設計、実装原則、整合性モデル、障害処理など、可用性の高い分散キャッシュ システムを構築する方法を詳しく紹介します。優れたキャッシュ システムには、高可用性、高性能が備わっており、データの一貫性と耐障害性が保証されている必要があります。

数百億回の訪問がある Weibo はどのようにキャッシュ アーキテクチャを実装しているのでしょうか?

Weibo は、1 億 6,000 万人を超える毎日のアクティブ ユーザーと数百億回の毎日の訪問者を持つ大規模なソーシャル プラットフォームであり、その効率的で継続的に最適化されたキャッシュ システムは、巨大なユーザー ベースの大規模なアクセスをサポートする上で重要な役割を果たしています。

1 つ目は Weibo 運営時のデータの課題、そしてフィード システムのアーキテクチャです。

次に、キャッシュのアーキテクチャと進化の分析に焦点を当て、最終的にはそれを要約して楽しみにしています。

マイクロブログトラフィックチャレンジ

Weiboフィードプラットフォームのシステムアーキテクチャ

システム全体は 5 つのレベルに分けることができ、最上位は Web クライアント、クライアント (iOS および Android デバイスを含む)、オープン プラットフォーム、サードパーティ アクセス インターフェイスなどの端末層です。次はプラットフォーム アクセス層です。これは主に主要なコア インターフェイスに高品質のリソースを割り当て、より柔軟なサービス機能を備え、バースト トラフィック時のサービスの安定性を向上させることを目的としています。さらにその下にはプラットフォーム サービス層があり、主にフィード アルゴリズム、関係などが含まれます。次に中間層があり、さまざまな中間メディアを通じてサービスを提供します。最下層はストレージ層であり、プラットフォーム全体のアーキテクチャはほぼ同じです。

1. フィードのタイムライン

  • ビルドプロセス

私たちが日常生活で Weibo を使用する場合、たとえばホームページやクライアントを更新すると、最新の 10 ~ 15 件の Weibo の投稿が表示されます。では、このプロセスはどのようにして達成されるのでしょうか?

更新操作により、ユーザーの注目関係が取得されます。たとえば、フォロワーが 1,000 人であれば、その 1,000 個の ID が取得されます。この 1,000 個の UID に基づいて、各ユーザーが投稿した Weibo が取得されます。同時に、ユーザーの受信トレイも取得されます。彼女が受け取ったのは、特別なニュースです。

たとえば、グループ内の一部の Weibo、グループ内の Weibo、彼女のフォロー関係、および彼女がフォローしている人の Weibo リスト。この一連の Weibo リストを取得した後、それらを収集して並べ替えて、必要な Weibo ID を取得し、これらを並べ替えます。各Weibo IDに対応するWeiboコンテンツを取得するためのID。

これらの Weibo が転送されると、元の Weibo も取得され、元の Weibo に基づいてユーザー情報が取得されます。ユーザー情報は元の Weibo を通じて取得され、これらの Weibo はユーザーのフィルターに基づいてさらにフィルタリングされますWeibo、これらの Weibo を離れた後、ユーザーがこれらの Weibo を収集または気に入っているかどうかを詳しく調べ、いくつかのフラグ設定を行い、さまざまなカウントも収集します。再投稿、コメント、いいねの数を含むこれらの Weibo のメッセージを収集し、最終的にこれらの十数の Weibo メッセージをユーザーのさまざまな端末に返します。

このように見ると、ユーザーは 1 回のリクエストで十数件のレコードを取得することになり、バックエンド サーバーは数百、場合によっては数千のデータをリアルタイムで処理してユーザーに返す必要があります。キャッシュシステムの強さ。したがって、キャッシュ アーキテクチャ設計の品質は、Weibo システムのパフォーマンスに直接影響します。

2. フィード キャッシュ アーキテクチャ

次に、キャッシュ アーキテクチャを見てみましょう。キャッシュ アーキテクチャは主に 6 つの層に分かれています。

  • 受信トレイの最初の層、この部分には主にグループ Weibo とグループ所有者の Weibo が含まれており、受信トレイの数は比較的少なく、主にプッシュ方式が使用されます。
  • 送信トレイの第 2 層では、各ユーザーが通常の Weibo を公開します。これらの Weibo は送信トレイに保存されます。保存されている ID の数に応じて、実際には複数のキャッシュに分割されます。通常は約 200、長い場合は約 2,000 です。
  • ソーシャル グラフの 3 番目の層は、注目、ファン、ユーザーなどの関係です。
  • 4 番目のレイヤー Content はコンテンツで、Weibo の各投稿のコンテンツの一部がここに保存されます。
  • 存在の第 5 レベルは存在判断であり、例えば、Weibo で、ある Weibo の投稿が「いいね」されたかどうか、著名人の中には、ある Weibo の投稿に「いいね」をしたと言っている人もいますが、実際にはそうではなく、ニュースになることもあります。 、実際には、彼女はある時点でそれを好きだったが、その後忘れてしまったからです。
  • 6 番目のレイヤーのカウンターは、Weibo のコメント、転送、その他のカウント、およびユーザーのフォロー数、ファン、その他のデータをカウントします。

Weibo キャッシュのアーキテクチャと進化

1. 単純な KV データ型

次に、Weibo キャッシュ アーキテクチャの進化プロセスに焦点を当てます。Weibo が最初にリリースされたとき、Weibo は単純な KV キーと値のペア データ型として保存されました。主にハッシュ シャーディングを使用して MC プールに保存しました。オンラインになってから数か月後、ノードマシンのダウンタイムやその他の理由により、大量のリクエストがキャッシュ層を通過して DB に到達し、リクエスト全体の速度が低下したり、 DBがフリーズする。

この問題を解決するために、私たちはすぐにシステムを変更し、高可用性 (HA) レイヤーを追加しました。これにより、メイン層の一部のノードがダウンしたり正常に動作しなくなった場合でも、リクエストはDB層に到達せず、さらにHA層に到達するため、システムのヒット率を安定させることができます。いかなる状況でもパフォーマンスが低下しないため、システム サービスの安定性が大幅に向上します。

現在、このアプローチは業界で広く使用されています。ただし、ハッシュ技術を直接使用する人もいますが、これには実際にはいくつかのリスクがあります。たとえば、ノード (ノード 3 など) がダウンすると、メイン層はそのノードを削除し、ノード 3 のリクエストの一部を他のノードに分散します。ビジネス量がそれほど大きくない場合、データベースはこの圧力に耐えることができます。ただし、ノード 3 が復旧後に再参加するとアクセスは戻りますが、ネットワークなどの理由で再度ダウンした場合、ノード 3 のリクエストは他のノードに分散されます。このとき問題が発生する可能性があります。以前に他のノードに割り当てられていたリクエストは誰も更新されていないため、削除が間に合わないとデータの混乱が発生します。

WeChatとWeiboの間には大きな違いがあります。実際、Weibo はオープン スクエア ビジネスに似ています。たとえば、予期せぬ事件が発生したり、有名人の交際が暴露された場合、トラフィックは一瞬で 30% に急増することがあります。この場合、特定のノードに大量のリクエストが集中してノードが非常に混雑し、MC を使用しても大量のリクエストに対応できなくなります。このとき、MC層全体がボトルネックとなり、システム全体の速度が低下します。この問題を解決するために、実際にはメインの関係プールである L1 レイヤーを導入しました。各 L1 レイヤーのサイズは、リクエストの量に応じてメイン レイヤーの約 1/6、1/8、または 1/10 です。リクエスト量が多い場合は、L1レイヤーを4~8層追加します。このように、リクエストが来ると、最初に L1 層にアクセスします。L1 層がヒットした場合、リクエストは直接アクセスします。ヒットしなかった場合、リクエストは Main-HA 層にアクセスし続けます。バースト トラフィックの場合、L1 層はほとんどのホット リクエストに耐えることができるため、Weibo のメモリ負荷が軽減されます。Weibo では、新しいデータがますます人気になるため、大量のリクエストを処理するためにメモリを少し増やすだけで済みます。

  • キーポイント
    • Memcached ベース
    • 層内の HASH ノードはドリフトせず、ミスは浸透します
    • マルチグループ L1 読み取りパフォーマンスの向上、ピーク トラフィック コストの削減読み取りおよび書き込み戦略
      • 書く:もっと書く
      • 読み取り: レイヤーごとの浸透、ライトバックミス
    • Json/xml --> プロトコルバッファ
    • QuickLZ圧縮

要約すると、単純な KV データ型ストレージ、主に MC を使用しており、層内の HASH ノードはドリフトせず、読み取りのために次の層にミスが浸透します。複数のグループの L1 読み取りパフォーマンスの向上により、コストを削減しながらピークおよびバースト トラフィックに対処できます。読み取りおよび書き込み戦略にはマルチライトを使用し、読み取りにはレイヤーバイレイヤーペネトレーションを使用します。ミスの場合はライトバックが実行されます。保存データについては、当初は Json/xml を使用していましたが、2012 年以降は Protocol|Buffer 形式を直接使用し、より大きなデータについては QuickL を使用して圧縮しました。

2. 収集データ

  • 事業の特徴
    • 一部変更
    • ページに入る
    • リソースコンピューティング: リンクドコンピューティング
    • タイプ: フォロー、ファン、グループ、一緒にフォロー、XX もフォロー
  • 解決策: Redis
    • ハッシュ分散、MS、キャッシュ/ストレージ
    • 30+T メモリ、2 ~ 3 兆読み取り/日

簡単なQAデータに関しては、すでに対処方法がわかっています。ただし、複雑な収集データの場合、たとえば 2,000 人をフォローする場合、新しい人を追加するにはいくつかの変更が必要になります。1 つの方法は、2000 個の ID をすべて削除して変更することです。これにより、帯域幅とマシン負荷が増大します。また、ページング検索のニーズもありますが、例えば2ページ目(10~20番目)など数ページだけを取得したいのですが、すべてのデータを完全に取得することはできないのでしょうか?また、特定の人の間でABCをフォローし、さらにユーザーDをフォローするなど、一部のリソースのリンク計算もあります。これには、一部のデータの変更、取得、計算が含まれますが、MCは実際にはこれが苦手です。すべてのアテンション関係は Redis に保存され、ハッシュを通じて分散および保存され、読み取りと書き込みを分離するために一連のマルチストレージ メソッドが使用されます。現在、Redis には約 30 テラバイトのメモリがあり、毎日 2 ~ 3 兆件のリクエストがあります。

  • Redis 拡張機能 (ロングセット)
    • Long型オープン配列、ダブルハッシュアドレッシング
    • クライアントがデータ構造を構築し、要素は一度書き込まれる
    • Lsput: フィルレートが高すぎます。クライアントによって再構築されました
    • Lsgetall --> Lsdump
    • 少量のホットデータ: mc アンチ読み取り

Redis を使用する過程で、他にもいくつかの問題が発生しました。例えば、関係フォローの観点から、私は 2,000 件の UID をフォローしていますが、すべて保存するのも 1 つの方法ですが、Weibo はユーザー数が多く、ログイン頻度が低いユーザーもいれば、特にアクティブなユーザーもいます。それらすべてをメモリに保存する量は比較的大きくなります。そこで、Redis の使用をキャッシュに変更し、アクティブなユーザーのみが保存されるようにし、最近アクティブでなかった場合は Redis から追い出され、再度アクセスされたときに追加されます。ただし、Redis の動作メカニズムはシングルスレッド モードです。特定の UV を追加して 2,000 人のユーザーに注目すると、20,000 の UID に拡張される可能性があります。20,000 の UID が詰め戻されると、Redis は基本的にスタックして提供できなくなります。その他のサービスもございます。そこで、新しいデータ構造を拡張しました。2万個のUIDが直接オープンされます。書き込み時は、直接Redisに順番に書き込まれます。全体の読み書き効率が非常に高くなります。その実装は、長いOpen配列型です。 、ダブルハッシュを通じて対処されます。

  • Redis のその他の拡張機能
    • ホット アップグレード: 10 分以上 > ミリ秒レベル
    • AOF : 回転
    • RDB : AOFの位置
    • 完全な増分コピー
    • フロア/シンクロスピードコントロール

Redis については、他にもいくつかの拡張機能を作成しました。たとえば、以前の共有では、データをパブリック変数に入れたことをインターネットで見ることができます。1G をテストしたときは、アップグレード プロセス全体の読み込みに 10 分かかりましたが、10G では約 10 分以上かかりました。現在は、ミリ秒レベルのアップグレード。AOFはローリングAOFを使用しており、各AOFにはIDがあり、一定量に達すると次のAOFにスクロールします。RDB が実装されると、RDB の構築時に AOF ファイルとその場所が記録され、新しい RDB および AOF 拡張モードを通じて完全な増分レプリケーションが実装されます。

3. その他のデータ型 - カウント

  • 事業の特徴
    • 1 つのキーに複数のカウントがあります (Weibo/ユーザーの複数のカウント)
    • 値のサイズが小さい (2 ~ 8 バイト)
    • 毎日 10 億近くの新しいレコードが追加され、総レコード数は数千億に達します。
    • 一度に複数の KV をリクエストする

次に、カウントなどの他のデータ型について説明します。実際、インターネット企業のあらゆる分野において、カウントは不可欠です。一部の中小企業では、MC と Redis で十分にニーズを満たすことができます。ただし、Weibo ではカウントにいくつかの特殊な特性があり、たとえば、Weibo にはリツイート、コメント、いいねの数など複数のカウントが含まれる場合があります。さらに、ユーザーはファンやフォロワーの数など、さまざまな数字を持っている場合があります。カウントの性質上、値のサイズは通常小さく、約 2 ~ 8 バイトであり、最も一般的なものは 4 バイトです。Weibo には毎日約 10 億件のレコードが追加されており、レコードの総数はさらに多くなります。1 回のリクエストで、数百のカウントを返す必要がある場合があります。

  • 選択 1: Memcached
    • MC カリング、再起動データ損失
    • カウント0が大量にある場合の保存方法
  • 選択 2: Redis
    • メモリペイロードが低い
    • アクセスパフォーマンス
  • 最終計画: 自社開発の CounterService
    • Shema は複数の列をサポートし、ビット単位で割り当てられます。
    • 事前に割り当てられたテーブル、ダブルハッシュアドレス指定
    • メモリが1/5~1/15以下に減少
    • ホット データとコールド データを分離し、SSD には古いデータが保存され、古いホット データは LRU に保存されます。
    • 着陸した RDB + AOF 完全増分レプリケーション
    • 単一マシン: 100 億レベルのホット データ、1,000 億レベルのコールド データ

4. カウンターサービス

当初、Memcached を使用することを選択しましたが、カウントがその容量を超えると一部のカウントが削除されたり、ダウンタイムまたは再起動後にカウントが失われるという問題がありました。また、ゼロカウントも多く、その際にどのように保存するか、保存する必要があるか、メモリを多く消費しないようにするかを考慮する必要があります。Weibo のカウントは毎日数十億件あり、ゼロ値を保存するだけでも大量のメモリを消費します。保存されていない場合、データベース層への侵入につながり、サービスのパフォーマンスに影響を与える可能性があります。

2010 年から、アクセスに Redis の使用に切り替えました。ただし、データ量が増加し続けると、Redis のメモリ使用率が比較的低いことがわかります。KV には約 65 バイトが必要ですが、実際にはカウントを保存するのに 8 バイトしか必要とせず、値の 4 バイトを加えれば、実際の有効ストレージはわずか 12 バイトです。残りの 40 バイト以上は無駄になります。これは単一の KV の場合のみであり、キーに複数のカウントがある場合、無駄なスペースはさらに多くなります。たとえば、カウントが 4 つ、キーが 8 バイトを占め、各カウントが 4 バイトを占める場合、合計 16 バイトが必要ですが、実際に使用されるのは 26 バイトだけです。

ただし、Redis ストレージを使用するには、約 200 バイトが必要です。その後、Counter Service の独自の研究開発により、メモリ使用量を Redis の 1/5 ~ 1/15 以下に削減しました。同時に、ホット データとコールド データの分離を実現し、ホット データをメモリに保存し、コールド データを LRU に配置します。コールド データが再びホットになると、RDB と AOF に配置され、完全な増分レプリケーションが実現されます。このようにして、1 台のマシンに数百億のホット データと数千億のコールド データを保存できます。

ストレージ アーキテクチャ全体の概要は次のとおりです。上部にメモリ、下部に SSD があります。メモリはあらかじめ N 個のテーブルに分割されており、各テーブルには ID ポインタのシーケンスに従って特定の範囲が割り当てられます。新しい ID が来た場合は、まずその ID が存在するテーブルを見つけて、増加または減少の操作を実行します。メモリが不十分な場合は、小さなテーブルを SSD にエクスポートし、新しい ID 用に新しい場所を予約します。

という疑問を持たれる方もいると思いますが、一定の範囲内であればID数は4バイトに設定されていましたが、Weiboの人気により4バイトを超えて非常に大きなカウントになってしまった場合はどうすればよいのでしょうか?制限を超えるカウントについては、Aux dict に保存します。SSD に保存されているテーブルの場合、RDB 経由でテーブルにアクセスし、コピーするための専用の IndAux があります。

5. その他のデータ型 - 存在判定

  • 業種要件
    • 存在するかどうかを確認します(「いいね」と読みます)
    • 単一レコードのサイズは小さく、値は 1 ビット (0/1)
    • データの総量が膨大で、値が0のものも多数ある
    • 毎日の新規追加数は数千億に達します

Weiboにはカウント以外にも生存判定などのサービスもあります。たとえば、ツイートが「いいね!」されたか、読まれたか、推奨されたかなどです。ユーザーが既に Weibo を読んでいる場合、Weibo は表示されなくなります。このタイプのデータの特徴は、各レコードは非常に小さい (たとえば、Value には 1 ビットしか必要ない) にもかかわらず、全体のデータ量が膨大になることです。たとえば、Weibo では毎日約 1 億件の新しい Weibo 投稿が公開され、その閲覧量は数百億、数千億に達する可能性があります。このデータをどのように保存するかが大きな問題です。そしてそれらの多くは存在が0です。前述の質問が再び生じます: 0 ストレージは必要ですか? 保存されていれば、毎日数千億件のレコードが保存されることになりますが、保存されていない場合は、大量のリクエストがキャッシュ層を通過して DB 層に到達し、これほど大量のトラフィックに耐えられる DB はありません。

  • 選択 1: Redis
    • シングル kv: 65 バイト
    • 毎日の新しいメモリ 6T (HA を考慮しない)
  • 選択 2: カウンターサービス
    • シングル kv: 9 バイト
    • 毎日 900G の新しいメモリが追加されます (HA を除く)

私たちもいくつかの選択をしました. まず、Redis を使用できるかどうかを直接検討しました. 1 つの KV は 65 バイトです. KV が 8 バイトにできる場合、Value は 1 ビットしかありません. このように計算すると、私の毎日の新しい記憶効率は非常に低いです。新しく開発されたカウンター サービスの 2 番目のタイプには、1 ビットの単一 KV 値があります。1 バイトを節約します。合計 9 バイトで十分です。このようにして、毎日 900G の新しいメモリが追加されます。保存してください。最新の数日しか保存できないかもしれません。3 日でほぼ 3 T を保存するのはかなりストレスですが、Redis よりははるかに優れています。

  • 最終計画:自社開発ファントム
    • テーブルセグメントの事前割り当て、セグメント内ブルームフィルター
    • 各kv:1.2バイト(誤判定1%)
    • 毎日の新しいメモリ: 120G < 800G < 6T

最終的な計画は、Phantom を自分たちで開発することです。まず、共有メモリをセグメントに割り当てます。最終的に使用されるメモリは 120G だけです。アルゴリズムは非常に単純です。各キーは N 回ハッシュできます。ハッシュの特定のビットが1です。ハッシュを3回実行する場合は、3つの数値に対して1を設定し、X2を3回ハッシュします。後でX1が存在するかどうかを判断するときに、3回ハッシュします。すべて1であれば、存在するとみなします。特定のハッシュ X3 のビットが 0 として計算された場合、そのハッシュは存在しないことが 100% 確実です。

  • ファントムシステムアーキテクチャ
    • データは共有メモリに保存されるため、再起動後もデータが失われることはありません。
    • ランディングRDB+AOF
    • Redisプロトコルと互換性あり

実装アーキテクチャは比較的単純です。共有メモリはあらかじめ複数のテーブルに分割されており、そこでオープンな計算が実行され、読み書きされます。実装されている場合は、AOF+RDB 方式が処理に使用されます。プロセス全体が共有メモリに配置されるため、プロセスをアップグレードして再起動してもデータは失われません。外部からアクセスする場合は、新しいプロトコルを直接拡張してサービスにアクセスできる Redis プロトコルを構築します。

6. まとめ

  • フォーカスポイント
    • クラスター内の高可用性
    • クラスター内のスケーラビリティ
    • 高性能コンポーネント
    • 保管コスト

要約すると、これまでキャッシュ クラスター内の高可用性、パフォーマンスを含むスケーラビリティに焦点を当ててきましたが、もう 1 つ特に重要なのはストレージ コストです。 21 日のメンテナンス、Weibo 現在、数千、ほぼ数万のサーバーなどが存在します。

7. さらなる最適化

リソース/コンポーネント管理指向

  • 運用とメンテナンスを簡素化するにはどうすればよいですか?

ローカル設定モード

  • 素早く変更を加えるにはどうすればよいでしょうか?

通常のピークトラフィックとバーストトラフィック

  • いかに早く、低コストで対応するか。

多くのビジネス データ カテゴリ

  • SLAを独立して制御するにはどうすればよいですか?

ビジネス関連のリソースが多すぎる

  • 開発を簡素化するにはどうすればよいでしょうか?

8. サービス化

  • ローカル設定 --> 設定サービス
    • configServer は構成/サービスを管理し、頻繁な再起動を回避します
    • リソース/サービス管理 API
    • 変更方法:スクリプト修正、スマートクライアント非同期更新

最初に採用されたソリューションは、キャッシュ全体をサービスとして管理し、頻繁な再起動を避けるために構成をサービスとして管理し、さらに構成が変更された場合はスクリプトで直接変更することです。

  • キャッシュアクセス
    • Proxy 化
  • IDC データの一貫性
    • 収集/複製

  • クラスターマネージャー
    • スクリプト --> Web インターフェース
    • サービス検証ビジネスSLA
    • サービス指向のリソース管理と制御
  • サービスガバナンス
    • 拡大と縮小
    • SLA保証
    • 監視アラーム
    • トラブルシューティング
  • 開発を簡素化
    • マスクキャッシュリソースの詳細
    • 単一行構成アクセス

Servitization では、外部管理を実現し、インターフェイスを介して管理し、サービス検証を実行するための Cluster Manager も導入されています。サービス管理においては、容量の拡張や削減が可能であり、SLAも十分に保証されます。さらに、開発のために、キャッシュ リソースをブロックできるようになりました。

概要と展望

最後に簡単にまとめると、Weibo キャッシュ アーキテクチャは、データ アーキテクチャ、パフォーマンス、ストレージ コスト、サービス指向のさまざまな側面から最適化および強化する必要があります。

参考文献

https://blog.csdn.net/java_cpp_/article/details/130663371

https://blog.csdn.net/k6T9​​Q8XKs6iIkZPPIFq/article/details/108271182

推奨読書

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

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/132628780