概要: NoSQL の KV データベースの王様である Redis は、その高いパフォーマンス、低レイテンシ、豊富なデータ構造により開発者に好まれています。しかし、Redis の水平スケーラビリティは限られているため、ビジネスに支障をきたすことなく水平拡張を実現する方法は、Redis を使用する多くの開発者が直面する問題です。 Redis 分散ソリューション [codis] のオープンソース製品がこの弱点を補います。
1. 背景生放送元年を迎え、春雨後の竹の子のように生放送作品が次々と登場しています。製品は収益を上げる過程で、ユーザーの消費欲求を刺激するためのさまざまな活動を考えようと全力を尽くしてきましたが、そのような活動の基本的な形はリストです。 2016 年には、cmem とスキャンフローテーブルに基づくリストランキングを実装しました。 2017 年から、元のシステムを再構築し、リストの基本的なストレージとして Redis を使用するようになりました。再構築の過程で、私たちはRedis分散ソリューションを調査するという任務を受け、業界のさまざまなオープンソース製品を比較し、最終的にCodisに決定し、詳細について調査を行いました。 Codis の作者とのコミュニケーションの中で、付加価値製品部門の Simotang が 2 年近くにわたって部門に Codis を導入していたことを知り、Codis の運用と保守に加わりました。現在、部門内には 2T 容量の Codis クラスターが 15 セット導入・保守されており、1 日の総訪問数は 100 億を超えています。インタラクティブビデオ製品部門の基盤ストレージ、運用活動、リスト関連業務を2年以上サポートし、合計100以上の活動と数千のリストを担当。 同時に、codis への接続プロセスにおける指導と支援をしてくれた codis の作者 spinlock に感謝したいと思います。 spinlock github および codis アドレスを参照してください。 2. Redis の基本の概要2.1 Redis の紹介Redis は、メモリをベースとし、データ永続化機能を備えた、高性能で低レイテンシの KV データベースです。値のデータ構造は、文字列、ハッシュ テーブル、リスト、セット、ソート セットのいずれかになります。
2.2 Redisの特徴
2.3 Redis アプリケーション シナリオ2.4 序文: codis と redis の関係codis と redis の関係は、codis が複数の redis インスタンスに基づくルーティング レイヤーを使用してデータをルーティングし、各 redis インスタンスが一定量のデータ シャーディングを担当することです。 2.5 Redis学習教材この記事はRedis分散ソリューションに焦点を当てているため、Redisに関連する基本的な部分については、2冊の本と関連するソースコード分析記事を参照してください。
3. 社内外のRedis分散ソリューションの比較ソリューションを比較する前に、まず、私たちの経験に基づいてソリューションに期待される機能を出力し、選択基準を測定します。 これを踏まえて、社内と社外との比較を以下のように行いました。 【社内コンポーネントの比較】 【外部部品の比較】 上記の比較に基づくと、オープンソース製品である Codis は、運用・保守コストの低さとスムーズな拡張という中核的な利点を直感的に実証できます。 データのセキュリティのため、現在、マシンの 48 時間のローリング バックアップと、会社の Liu Bei バックアップ (毎日スケジュールされたディレクトリ バックアップを備えたシステム) をバックアップとして使用しています。監視には、現在、モニターのスタンドアロン バックアップと MiG 監視アラームを使用しています。 4. Codisのアーキテクチャ設計4.1 Codisの全体的なアーキテクチャ設計[図 codis アーキテクチャ図] 上図に示すように、Codis はプロキシ + ストレージの 2 層アーキテクチャです。 CKV + プロキシなしの設計と比較すると、全体的な設計は比較的シンプルです。同時に、クライアント接続データが徐々に増加した場合、データ層のコピーを拡張する必要はなく、プロキシ層のみを拡張すればよいことになります。この観点から見ると、コストは低くなります。ただし、接続数が多くない場合は別途プロキシを導入する必要があります。この観点から見ると、コストは高くなります。 その中で、オープンソースの codisproxy サービスの登録と検出は zk を通じて実装されており、部門は現在 l5 をベースにしています。 全体的なアーキテクチャ設計図から、codis の全体的なアーキテクチャは比較的明確です。その中でも、codisproxy は分散ソリューション設計の中核部分です。ストレージ ルーティングとシャード移行は、codisproxy と切り離せません。 codisproxy の設計と実装を見てみましょう。 4.2 Codisproxyのアーキテクチャ設計と実装codisproxy のアーキテクチャ実装は、4.2.1 のルート マッピングの詳細と 4.2.2 のプロキシ要求処理の詳細の 2 つの部分に分かれています。 4.2.1 ルートマッピングの詳細下の図に示すように、この部分は主に codis のルーティングの詳細に関係し、主にキーを特定の物理ノードにマップする方法に関係します。 上の図に示すように、この部分は主にcodisのルーティングの詳細に関係しています。 |関連語彙の説明 グループ: 主に仮想ノードであり、複数の Redis マシンで構成され、マスター スレーブ モデルを形成し、論理的な意味でのノードです。 プロキシルートマッピングの詳細をより深く理解していただくために、ルートマッピングに関連する一般的な問題をいくつか整理しました。 質問 1 : プロキシはどのようにしてリクエストを特定の Redis インスタンスにマッピングしますか? 質問 2:プロキシはどのようにして読み取りと書き込みの分離を実現するのでしょうか?上図に示すように、キーを特定の仮想ノードにマッピングすると、その仮想ノードに対応するマスターインスタンスとスレーブインスタンスを感知することができます。このとき、redisproxy レイヤーは特定の redis コマンドを識別し、対応するコマンドを読み取りおよび書き込みとして取得できます。次に、クラスター構成が読み取り/書き込み分離機能をサポートしているかどうかに基づいて、構成がサポートしている場合は、マスター インスタンスとスレーブ インスタンスにランダムにルーティングします。構成がサポートしていない場合は、完了のためにホストにルーティングされます。 質問 3 : プロキシは現在どのようなコマンドをサポートしていますか?バッチコマンドをサポートしていますか?アトミック性を確保するにはどうすればよいでしょうか? コマンドサポート部分: Proxoy でサポートされるコマンドには、未サポートコマンド、半サポートコマンド、サポートコマンドの 3 種類があります。上記の表に示されているコマンド以外にも、プロキシは他のコマンドをサポートしています。サポートされていないコマンドの主な原因は、コマンド パラメータにキーがないため、ルーティング情報を識別できず、どのインスタンスにルーティングするかが不明であることです。準サポートされているコマンドは通常、複数のキーを操作します。 Codis は、最初のキーのルーティングに基づいたシンプルな実装に基づいています。したがって、ビジネス側は複数のキーを同じスロットにルーティングしておく必要があります。もちろん、事業者側もそれを保証することはできず、具体的な結果は事業者側が負担することになります。これは弱い検証モードであり、企業レベルの製品であるckv+は、複数のキー操作に対する強力な検証です。複数のキーが同じスロットにない場合は、エラーの形で返されます。 マルチキー操作とアトミック性: Redis 自体は、mset やその他のコマンドなどの一部のマルチキー操作に対してアトミックです。ただし、分散操作では、複数のキーが複数の Redis インスタンスに分散され、分散トランザクションが発生するため、Codis では簡略化され、複数キー操作は複数の単一キー コマンド操作に分割されます。したがって、Codis の mset マルチキー操作にはアトミック セマンティクスがありません。 質問4:複数のキーが1つのスロットにあることを確認する方法 4.2.2 プロキシリクエスト処理の詳細下の図に示すように、この部分は主にプロキシの処理の詳細に関係し、要求を受け入れて戻りパケットに応答する方法のプロセスに関係します。 上の図に示すように、この部分は主にプロキシの処理の詳細に関係します。 Codisproxy は主に、言語レベルからコルーチンを自然にサポートする言語である Go 言語に基づいて実装されています。 1) プロキシはクライアントの接続を受信すると、新しいセッションを作成し、そのセッションでリーダー コルーチンとライター コルーチンを開始します。リーダーは主に、クライアントのリクエスト データを受信して解析し、マルチキー シナリオでコマンドを分割し、ルーターを介して特定の Redis インスタンスにリクエストを配布し、Redis によって処理されたデータをチャネルに書き込むために使用されます。ライターはチャネルから対応する結果を受信し、それをクライアントに書き戻します。 2) ルータ層は主にCRCコマンドを通じてキーに対応するルーティング情報を取得します。ソースコードから、codis が実際にサポートしているハッシュタグの特性を確認できます。 この時点で、プロキシ関連のルート マッピングと要求処理の詳細が完了しました。全体的にとてもシンプルですよね? 5. データの信頼性、高可用性、災害復旧、フェイルオーバー、スプリットブレイン処理ストレージ層として、データの信頼性とサービスの高可用性は安定性の中核的な指標であり、上位層のコア サービスの安定性に直接影響します。このセクションでは主にこれら 2 つの指標について説明します。 5.1 データの信頼性codis の実装に関しては、データの高い信頼性は主に redis 自体の能力です。通常、ストレージ層のデータの高い信頼性は、主に単一マシンデータの高信頼性 + リモートデータのホットバックアップ + 定期的なコールドバックアップアーカイブによって実現されます。 単一マシン データの高い信頼性は、主に Redis 自体の永続性機能、RDB モード (定期的な DUM)、および AOF モード (実行ログ) に依存します。これを理解するには、前の記事で紹介した 2 冊の本を参照してください。 AOF モードはより安全です。現在、AOF スイッチもオンラインでオンにしていますが、これについては記事の最後で詳しく説明します。 リモート データのホット バックアップは、主に Redis 自体のマスター スレーブ同期機能に依存しており、完全同期と増分同期を実現することで、Redis はリモート ホット バックアップ機能を実現できます。 定期的なコールド バックアップ アーカイブ。データ操作における人為的ミス、コンピュータ室のネットワーク障害、ストレージサービス運用中のハードウェア障害などによりデータ損失が発生する可能性があるため、何らかのバックアップ計画が必要です。現在、当社では主に単一マシンのローリング バックアップを使用して過去 48 時間のデータをバックアップし、SNG の Liu Bei システムを使用してコールド バックアップを行い、予期しない問題によるデータ損失を防ぎ、迅速な復旧を可能にしています。 5.2 高可用性、災害復旧、フェイルオーバーCodis 自体のアーキテクチャは、プロキシ クラスター + Redis クラスターに分かれています。プロキシ クラスターの高可用性はフェイルオーバー用の ZK または L5 をベースにすることができますが、Redis クラスターの高可用性は Redis オープン ソース Sentinel クラスターの助けを借りて実現されます。 Codis は、Redis 以外のコンポーネントとして、Redis Sentinel クラスターをどのように統合するかという問題を解決する必要があります。このセクションでは、問題を 3 つの部分に分割し、Redis Sentinel クラスターが Redis の高可用性を保証する方法、CodisProxy が Redis Sentinel クラスターのフェイルオーバー アクションを認識する方法、および Redis クラスターが「ブレイン スプリット」の可能性を減らす方法について説明します。 5.2.1 Sentinel クラスターはどのようにして Redis の高可用性を確保するのでしょうか?Sentinel は Redis の高可用性ソリューションです。1 つ以上の Sentinel インスタンスで構成される Sentinel システムは、任意の数のマスター サーバーとこれらのマスター サーバーの下にあるすべてのスレーブ サーバーを監視できます。監視対象のマスター サーバーがオフラインになると、オフライン マスター サーバーの下にあるスレーブ サーバーが新しいマスター サーバーに自動的にアップグレードされ、その後、マスター サーバーはオフライン マスター サーバーの代わりにコマンド要求の処理を継続します。 一般的に、サービスの高可用性を実現するには、障害検出とフェイルオーバー(マスターの選択とマスターとスレーブの切り替え)という 2 つのことを行う必要があります。 5.2.2 Codis は Sentinel クラスターのフェイルオーバー アクションをどのように認識しますか?Codis 自体のアーキテクチャは、プロキシ クラスター + Redis クラスターに分かれています。 Redis クラスターの高可用性は、Sentinel クラスターによって保証されます。では、プロキシはどのようにして Redis ホストの障害を認識し、新しいマスターに切り替えてサービスの高可用性を確保するのでしょうか? 上の図に示すように、プロキシ自体はセンチネル クラスターの +switch-master イベントをリッスンします。このイベントが発行された場合、Redis クラスター ホストに問題があることを意味します。センチネル クラスターはホストの選択と切り替えを開始します。プロキシは、センチネルのマスター/スレーブ切り替えイベントをリッスンします。マスター/スレーブ切り替えイベントを受信すると、プロキシは、すべてのセンチネル上のクラスターによって認識されている現在のホストを引き出し、センチネルの半数以上によって現在のクラスター ホストとして認識されているホストを選択するアクションを実行します。 この時点で、構成の保存という問題を見落とす可能性があります。構成センターのストレージは、まだ古いホストのままです。プロキシが再起動されると、障害が発生したホストは引き続きプルされます。実際、ダッシュボードとプロキシは同じことを行います。マスタースレーブ切り替えイベントを受信すると、新しいマスターがストレージ(現在はzk)に保存されます。 5.2.3 スプリットブレイン処理スプリット ブレイン クラスターのスプリット ブレインは通常、クラスター内の一部のノードが到達不能なために発生します。次のような状況が発生すると、分割された異なる小規模クラスターが自律的にマスター ノードを選択し、元のクラスターに同時に複数のマスター ノードが存在することになります。その結果、システムの混乱やデータの破損が発生します。 この問題に関しては、Simotang 氏がすでに大規模 Codis クラスターのガバナンスと実践について非常に詳しく説明しています。ここで簡単にお話させていただきます。 Redis クラスターは単純に多数決モードに依存することはできず、RedisMaster 自体は自身のヘルス ステータスを検出してダウングレードのアクションを実行しないため、マスターのヘルス ステータスに基づいてダウングレードを判断するための支援方法が必要です。具体的な実装は 1) デュアルアクティブダウングレードの確率により、クォーラムの判断がより厳しくなり、ホストのオフライン判断時間もより厳しくなります。大手オペレータの IDC をカバーするために 5 台のセンチネル マシンを導入しましたが、そのうち 4 台だけが、ホストがオフラインであると主観的に判断した場合にホストをオフラインにします。 2) 分離されたマスターがダウングレードされます。共有リソース判定方式に基づき、Redis サーバー上のエージェントは zk が正常かどうかを定期的かつ継続的にチェックします。接続できない場合は、ダウングレード コマンドが Redis に送信され、読み取りおよび書き込みが不可能になり、一貫性を確保するために可用性が犠牲になります。 6. Codis 水平展開の詳細と移行例外の取り扱いCodis は Redis の分散ソリューションであるため、Redis 単一ポイントの容量が不十分な場合は必然的に水平拡張の問題に直面します。このセクションでは、主に Codis の水平拡張と移行例外の詳細について説明します。 2つの質問から始めましょう。質問 1: 移行プロセス中に、移行されるキーの読み取りおよび書き込み要求をどのように処理しますか?質問 2: 移行プロセス中に例外 (障害やタイムアウトなど) を処理する方法。 6.1 Codisの拡張と移行の詳細
上図に示すように、Redis スムーズ移行プロセスは、主に移行準備、移行アクション、移行パフォーマンス保証の 3 つのポイントを実装します。 移行準備 移行アクション 1) キーが存在するかどうかを判断します。存在するが移行バッチにない場合は、キーの実際のメソッドを直接呼び出します。存在するが移行バッチ内にある場合、読み取り操作は許可されますが、書き込み操作は許可されません。 2) キーが存在しない場合は、キーが新しいインスタンスに移行されているか、キーが存在しない可能性があります。その場合、プロキシは操作のために新しいインスタンスに移動するように通知されます。 移行パフォーマンス 6.2 移行例外処理さらに、これを見て、何か質問があるかどうかはわかりませんが、ここでは、codisがどのように処理するか、特に複雑で不安定なネットワーク環境でどのように動作するかを確認するための質問をいくつか用意しました。 質問 1:移行のために大きなキーを小さなバッチに分割します。バッチ移行が失敗したりタイムアウトになったりした場合はどうすればいいですか? 分散シナリオにおけるネットワーク呼び出しには、成功、失敗、タイムアウトの 3 つの状態があることがわかっています。失敗は大したことではありませんが、タイムアウトの場合は盲目的に再試行できますか?明らかにそうではありません。通常、データ レベルでの再試行では、非常に重要な原則であるべき等性を確保する必要があります。ただし、zset、set、hash、および文字列構造を除く Redis 構造では、再試行理論は影響を受けません。リストはどうですか?そのため、Codis はより暴力的な方法を使用します。バッチ移行が正常に再試行されると、再試行する前にターゲット ノードがキーを削除できるように、最初に del コマンドが実行されます。 質問 2 : 有効期限のあるキーの移行中、データが送信される前にターゲット ノードで有効期限を設定する必要がありますか、それとも最初にデータを送信し、最後に有効期限を設定する必要がありますか? まず、データを送信する前にターゲット ノードに有効期限を設定する問題を見てみましょう。マシン B のキーが送信の途中で期限切れになった場合、後続のキーには有効期限がありません。期待に応えられなかった 最初にデータを転送し、最後に有効期限を設定する問題を見てみましょう。Acrash が転送の途中で再開し、この時点でキーの有効期限が切れると、データはマシン B に落ちてゾンビ データになり、期待どおりになりません。それで、Codis はそれをどのように行うのでしょうか? 移行例外が発生した場合に、移行プロセス中のシャードが自動的に破棄されるようにするために、シャードが転送されるたびにキーの有効期限が 90 秒 (タイムアウト時間の 30 秒より大きい) にリセットされ、キーの移行が完了した後に実際の有効期限にリセットされます。この方法では、移行プロセス中にクラッシュ、キーの有効期限切れ、またはその他の例外が発生した場合でも、シャード データはターゲット ノード上で 90 秒間のみ存続し、その後破棄されます。 質問 3:移行プロセス中にクラッシュします。現時点では、対応するシャード データの半分が A にあり、残りの半分が B にあります。どうすればよいでしょうか? 川沿いを頻繁に歩くと、必ず怪我をします。有効期限移行の不適切な実装が原因で、Codis で悲惨な事件が発生しました。幸いなことに、それはテスト環境で発生しました。この時点では、A をプルアップしないでください。A に古いデータが存在する可能性があり、移行されたキーが再移行され、B のデータが失われる可能性があるためです。正しい方法は、A のバックアップ マシンを使用して移行を続行することです。 A のバックアップ マシンは非同期で複製されますが、基本的には A の完全なデータに近いため、問題はそれほど大きくありません。ただし、すべての移行プロセス中は、データの損失を防ぐためにデータとシャード情報をバックアップすることをお勧めします。この時点では、B のデータを A に移行しないでください。移行されたデータの一部が B に残り、A の完全なデータが上書きされる可能性があるためです。 質問 4 : パフォーマンス上の理由から、A をバックアップ サーバーとして使用せず、AOF と RDB を有効にしないことはできませんか? これも絶対に許可されていません。A がクラッシュして Zhiyun によって引き上げられた場合、空のインスタンスと同等になり、バックアップ マシンのデータがクリアされ、データ損失が発生するためです。 7. Codis関連データストレステスト環境: ストレステストサーバー (v4-8-100) + プロキシ (v4-8-100) + redis (B5 (4 -32-100)) 上の図からわかるように、一度に取得されるデータの量が増えると、プロキシのパフォーマンスは急速に低下します。たとえば、ZRANGE_500 の直接接続のパフォーマンスはプロキシの 2 倍です。 8. 操作・保守マニュアルと落とし穴回避ガイド操作メモ: 8.1 マスタースレーブスイッチングマスターとスレーブを切り替えるたびに、切り替えられたマスターまたはバックアップ マシン上の conf ファイルが書き換えられていることを確認します。 8.2 データの移行重要な操作を実行する前に、データをバックアップしてください。スライス情報が関係する場合は、スライス情報をバックアップします。 A から B への移行時間が長すぎる場合は、コマンドを確認してください。Acodisserver に接続し、コマンドラインで slotsmgrt-async-status を実行して、移行中のシャードの情報 (特に大きなキー) を表示し、状況を明確に把握します。数千万個のキーの移行は約 20 秒で完了します。 8.3 例外処理Redisがクラッシュして再起動した後、再起動後にキーがほぼロードされると、ページにエラーが報告されます。 8.4 クライアントのタイムアウトが多発する
8.5 フォークには長い時間がかかる理由: 改善する:
メモリ フォークメモリ消費関連のログ: AOF 書き換え: コピーオンライトで 53 MB のメモリが使用、RDB: コピーオンライトで 5 MB のメモリが使用 巨大ページをオフにしてからオンにすると、コピーページ単位が4KBから2MBに変わり、フォークの負担が増加し、書き込み操作の実行時間が遅くなり、書き込み操作の数が多くなり、クエリが遅くなります。 "sudo echo never>/sys/kernel/mm/transparent_hugepage/enabled ハードディスク 8.6 AOF永続性の詳細一般的に使用されるハードディスク同期戦略は everysec であり、パフォーマンスとデータ セキュリティのバランスを取るために使用されます。この方法では、Redis は別のスレッドを使用して、ハードディスクとの fsync 同期を毎秒実行します。システムのハードディスク リソースがビジー状態の場合、Redis メイン スレッドはブロックされます。 8.7 誤ってflushdbを実行してしまったappendonlyno が設定されている場合は、すぐに rdb トリガー パラメータを増やしてから、rdb ファイルをバックアップします。バックアップが失敗した場合は、すぐに逃げてください。 appedonlyyes が設定されている場合は、AOF 書き換えパラメータ auto-aof-rewrite-percentage および auto-aof-rewrite-minsize を増やすか、プロセスを直接強制終了して、Redis が AOF を自動的に書き換えないようにすることができます。 · 手動の bgrewriteaof を拒否します。 aof ファイルをバックアップし、バックアップした aof ファイルに記述されている flushdb コマンドを削除してから復元します。復元が不可能な場合は、コールド バックアップを使用します。 8.8 オンライン Redis は RDB モードを Aof モードに変更しようとしますconfを直接変更せずに再起動してください IX.参考文献
|
<<: OpenStackセキュリティグループの実装原理の簡単な説明
>>: クラウドコンピューティングで企業が直面するいくつかの問題点
[[429685]]こんにちは、みんな私はあなたの学習と成長のパートナーですキャプテンRocketM...
ジャック・マー氏は数年前、タオバオはSNS(ソーシャル化されコミュニティベース)になるべきだと提案し...
多くのウェブマスターはウェブサイトの URL の最適化を見落としがちですが、ウェブサイトの最適化には...
ロシアのサーバー業者admanは現在、自社のVMware仮想VPS(2年間の支払いが必要)を50%割...
工業情報化省は、虚偽の申告を是正し、ウェブサイトの申告情報の正確性を向上させるために、特別なビデオ会...
近年の電子商取引における2つの大きな波は、 Pinduoduoとライブストリーミングです。 Pind...
習近平総書記は「誰もが学び、どこでも学び、いつでも学べる」学習社会の構築を提案した。同時に、第19回...
現在、クラウド コンピューティングはデジタル インフラストラクチャの重要な部分であり、デジタル経済の...
12月12日にWordPressがメジャーアップグレードされ、バージョン3.5「Elvin」にアップ...
電子商取引業界の発展は、砂を洗い流す波のようなものです。潮が引くと、誰が裸で泳いでいるかがわかります...
[[408405]] 6月25日、中国消費財業界CIO会議が上海で開催されました。このサミットは、「...
みなさんこんにちは。私は外部リンクを投稿する男です。仕事が休みの時は何をしているのでしょうか?80年...
AI がクラウド プラットフォームの成長を加速し、新世代の AI 駆動型ツールがクラウド環境を管理で...
普段はこうした問題にあまり注意を払っていませんが、今日、トラフィックと取引数の間になぜこんなに大きな...
技術の急速な発展により、すべてのソフトウェア開発者、エンジニア、その他の技術者は、常に技術の最前線に...