シリーズ記事の目次
- 2024 Java インタビュー (1) – 春の章
- 2024 Java インタビュー (2) – 春の章
- 2024 Java インタビュー (3) – 春の章
- 2024 Java インタビュー (4) – 春の章
記事ディレクトリ
序文
Redisのデータ型
タイプ | 1階 | アプリケーションシナリオ |
---|---|---|
弦 | SDSアレイ | 検証コード、カウンター、注文繰り返し送信トークン、人気商品カード、分散ロック |
リスト | クイックリスト | 簡易キュー、最新コメント一覧、非リアルタイムランキング一覧:スケジュールランキング計算 |
ハッシュ | ハッシュ | ショッピングカート、個人情報、商品詳細 |
セット | インセット | 友人関係や重複排除などの交差、結合、および差分の操作 |
ソートされたセット | ジャンプ台 | 重複排除後のソート、ランキングシナリオに適した |
Redis の可用性
1. Redis の永続化
永続化とは、サーバーがダウンしたときにメモリ データが失われるのを防ぐために、メモリ内のデータをローカル ディスクに永続化することです。
Redis は、RDB (デフォルト) と AOF メカニズムの 2 つの永続性メカニズムを提供します。Redis 4.0 以降では、ハイブリッド永続性を採用しており、データ回復の最初の選択肢として AOF を使用してデータが失われないようにし、さまざまなレベルのコールド バックアップに RDB を使用します。
RDB : Redis DataBase スナップショットの略称です
RDB は Redis のデフォルトの永続化メソッドです。メモリデータは一定期間ごとにスナップショット形式でハードディスクに保存され、対応するデータファイルがdump.rdbとして生成されます。スナップショットの期間は、構成ファイルの save パラメーターによって定義されます。
利点:
1) ファイル dump.rdb は 1 つだけあり、永続化に便利です。
2) 耐災害性が高く、ファイルを安全なディスクに保存できます。
3) パフォーマンスを最大化するには、子プロセスをフォークして永続的な書き込み操作を実行し、メイン プロセスがコマンドの処理を続行できるようにします。リクエストに対するミリ秒レベルの無応答のみが発生します。
4) データセットが大きい場合、AOF よりも起動効率が高くなります。
デメリット:
データの
セキュリティが低い RDB は一定の間隔で永続化されるため、永続化の間に Redis に障害が発生するとデータの損失が発生します。
AOF: 永続性
AOF 永続性 (つまり、Append Only File 永続性) は、Redis によって実行された各書き込みコマンドを別のログ ファイルに記録します。Redis が再起動されると、永続ログ ファイル内のデータが復元されます。
利点:
1) データ セキュリティ、aof 永続性は appendfsync 属性で設定できます。常に存在する場合、各コマンド操作は aof ファイルに記録されます。
2) 追加モードでファイルを書き込みます。サーバーが途中でダウンした場合でも、redis-check-aof ツールを使用してデータの一貫性の問題を解決できます。
短所:
1) AOF ファイルは RDB ファイルよりも大きく、回復速度が遅くなります。
2) データセットが大きい場合、RDBに比べて起動効率が低くなります。
2.redisトランザクション
トランザクションは単一の分離された操作です。トランザクション内のすべてのコマンドはシリアル化され、順番に実行されます。トランザクションの実行中、他のクライアントから送信されたコマンド要求によって中断されることはありません。トランザクションはアトミックな操作です。トランザクション内のすべてのコマンドが実行されるか、まったく実行されないかのどちらかです。
Redis トランザクションの概念
Redis トランザクションの本質は、MULTI、EXEC、WATCH などのコマンドの集合です。トランザクションは一度に複数のコマンドの実行をサポートしており、トランザクション内のすべてのコマンドはシリアル化されます。トランザクション実行処理中、キュー内のコマンドは順番に実行され、他のクライアントから送信されたコマンド要求はトランザクション実行コマンドシーケンスに挿入されません。要約すると、redis トランザクションは、キュー内の一連のコマンドを 1 回限り、順次、排他的に実行します。
Redis トランザクションには常に ACID の整合性と分離があり、他の機能はサポートされていません。サーバーが AOF 永続モードで実行されており、appendfsync オプションの値が always である場合も、トランザクションは永続的です。
Redis トランザクション機能は、MULTI、EXEC、DISCARD、WATCH の 4 つのプリミティブによって実装されます。
トランザクションコマンド:
MULTI : トランザクションの開始に使用され、常に OK を返します。MULTI の実行後、クライアントはサーバーに任意の数のコマンドを送信し続けることができます。これらのコマンドはすぐには実行されず、キューに入れられます。EXEC コマンドが呼び出されると、キュー内のすべてのコマンドが実行されます。
EXEC : すべてのトランザクション ブロック内でコマンドを実行します。トランザクションブロック内のすべてのコマンドの戻り値をコマンド実行順に並べて返します。操作が中断されると、空の値 nil が返されます。
WATCH : Redis トランザクションにチェック アンド セット (CAS) 動作を提供できるオプティミスティック ロックです。1 つ以上のキーを監視できます。キーの 1 つが変更 (または削除) されると、それ以降のトランザクションは実行されず、EXEC コマンドが実行されるまで監視が継続されます。(フラッシュセールシーン)
DISCARD : このコマンドを呼び出すと、クライアントはトランザクション キューをクリアしてトランザクションの実行を放棄し、トランザクション状態から終了します。
UNWATCH : このコマンドは、すべてのキーの監視をキャンセルできます。
3. Redis 障害戦略
記憶除去戦略
1) グローバルキースペースの選択的削除
noeviction : メモリが新しく書き込まれたデータを収容するのに不十分な場合、新しい書き込み操作はエラーを報告します。(辞書ライブラリでよく使用されます)
allkeys -lru : キー空間で、最も最近使用されていないキーを削除します。(一般的にキャッシュに使用されます)
allkeys-random : キー空間内のキーをランダムに削除します。
2) 有効期限を設定したキースペースの選択的な削除
volatile-lru : 有効期限が設定されたキー空間で、最も最近使用されていないキーを削除します。
volatile -random : 有効期限を設定してキースペース内のキーをランダムに削除します。
volatile-ttl : 有効期限が設定されているキー空間では、有効期限が早いキーが最初に削除されます。
キャッシュ無効化戦略
スケジュールされたクリア: 有効期限が設定されたキーごとに指定されたタイマーを作成します。
遅延クリア: アクセス中に判断され、メモリに優しくありません
スケジュールされたスキャンとクリア: 20 個の期限切れ辞書が 100 ミリ秒ごとにランダムにチェックされ、25% を超える辞書が存在する場合、ループで削除され続けます。
4. Redis 読み取りおよび書き込みモード
CacheAside バイパスキャッシュ
書き込みリクエストによってデータベースが更新された後、キャッシュされたデータを削除します。読み取りリクエストはクエリ データベースにヒットせず、クエリは完了してキャッシュに書き込まれます。
ビジネスエンドはすべてのデータアクセスの詳細を処理し、レイジーコンピューティングのアイデアを使用し、DBを更新した後、キャッシュを直接削除し、DBを介して更新することで、データがDBの結果に確実に従うようにし、コストを大幅に削減できます。キャッシュと DB の間のデータ不整合の可能性。特殊なストレージ サービスで
ない高度なデータ整合性要件がある企業、または複雑なキャッシュ データ更新を必要とする企業は、キャッシュ アサイド モードの使用に適しています。たとえば、Weibo の開発初期には、多くの企業がこのモデルを採用しました。
// 延迟双删,用以保证最终一致性,防止小概率旧数据读请求在第一次删除后更新数据库
public void write(String key,Object data){
redis.delKey(key);
db.updateData(data);
Thread.sleep(1000);
redis.delKey(key);
}
高い同時実行性で絶対的な一貫性を確保するには、まずキャッシュを削除してからデータを更新します。これには、非同期シリアル化用のメモリ キューを使用する必要があります。同時実行性が高くないシナリオでは、最初にデータを更新してからキャッシュを削除します。遅延二重削除戦略は基本的に満たされます。
- まずデータベースを更新してから redis を削除します。redis の削除に失敗すると問題が発生します。
- まず redis を削除してからデータベースを更新します。redis が削除されるとすぐに、古いデータが redis にバックフィルされます。
- まず redis を削除してからデータベースを更新します 休止状態後に redis を削除する: 2 番目の点と同様に、休止状態後に redis を削除するとダウンタイムが発生する可能性があります。
- Java 内部 jvm キュー: 分散シナリオには適しておらず、同時実行性が低下します。
読み取り/書き込みスルー (読み取りおよび書き込みスルー)
まず、キャッシュ内のデータが存在するかどうかをクエリします。存在する場合は、直接返されます。存在しない場合は、キャッシュコンポーネントがデータベースからデータを同期的にロードします。
まず、書き込まれるデータがキャッシュに既に存在するかどうかをクエリします。既に存在する場合は、キャッシュ内のデータを更新し、キャッシュ コンポーネントによってデータベースと同期します。
ユーザーによる読み取り操作が多いため、キャッシュと比較すると、キャッシュ一貫性のあるシナリオに適しています。単純な使用では、基礎となるデータベースの操作が保護され、キャッシュのみが操作されます。
シナリオ:
Weibo フィードの Outbox Vector (つまり、ユーザーの最新の Weibo リスト) はこのモデルを採用しています。ファンの少ない非アクティブなユーザーが Weibo を投稿した後、Vector サービスはまず Vector キャッシュにクエリを実行します。キャッシュにユーザーの送信トレイ レコードがない場合、ユーザーのキャッシュ データは書き込まれず、DB に直接書き込まれます。キャッシュのみ ファイル内に存在する場合のみ CAS 命令を通じて更新されます。
5. マルチレベルキャッシュ
ブラウザのローカル メモリ キャッシュ: 特別なイベントがオンラインになると、イベント中に自由に変更されることはありません。
ブラウザのローカルディスクキャッシュ: ロゴキャッシュ、大きな画像の遅延読み込み
サーバー側のローカルメモリキャッシュ: 永続性がないため、再起動時に
サーバー側のネットワークメモリキャッシュを突き破る: Redisなど、万が一に備えて階層化し続けることが可能データベースが過負荷にならないようにする必要があります。
サーバーのローカル ディスクをキャッシュに使用しないのはなぜでしょうか?
システムが大量のディスク IO 操作を処理する場合、CPU とメモリの速度がディスクの速度よりもはるかに高いため、CPU はディスクが処理結果を返すまでの待機に長時間を費やす可能性があります。CPU の IO オーバーヘッドのこの部分をiowaitと呼びます。
1. キャッシュなだれ
キャッシュの大規模な障害も同時に発生するため、後続のリクエストがデータベースに降りかかり、短期間に大量のリクエストに耐えてデータベースが崩壊してしまうことを指します。解決策:
- Redis の高可用性、マスター/スレーブ + センチネル、Redis クラスター、完全崩壊の回避
- ローカルの ehcache キャッシュ + hystrix の電流制限とダウングレードにより、MySQL が強制終了されるのを防ぎます。
- キャッシュされたデータの有効期限は、大量のデータが同時に期限切れになるのを防ぐためにランダムに設定されます。
- 論理的に有効期限はなく、キャッシュされた各データに対応するキャッシュ タグが追加されます。キャッシュ タグの有効期限が切れると、データ キャッシュが更新されます。
- マルチレベル キャッシュ。失敗すると、最初のレベルが 2 番目のレベルを通じて更新され、2 番目のレベルのキャッシュがサードパーティのプラグインによって更新されます。
2. キャッシュの侵入
キャッシュの侵入とは、キャッシュにもデータベースにも存在しないデータを指し、すべてのリクエストがデータベースに落ち、データベースが短期間に大量のリクエストに耐えられなくなり、データベースが崩壊します。
解決策:
1)ユーザー認証検証、ID の基本検証、ID<=0 の直接傍受などの検証をインターフェイス層に追加します。
2) キャッシュから取得できないデータはデータベースから取得されませんが、このときキーと値のペアをkey-nullとして記述することもでき、キャッシュの有効時間を 30 秒など短く設定することもできます。これにより、攻撃者が同じ ID を繰り返し使用してブルート フォース攻撃を行うことがなくなります。
3)ブルーム フィルターを使用して、考えられるすべてのデータを十分な大きさのビットマップにハッシュし、存在してはいけないデータはこのビットマップによってインターセプトされるため、基盤となるストレージ システムに対するクエリのプレッシャーが回避されます。(1人を逃がすよりは、誤って1000人を殺したほうがマシです)
3. キャッシュの内訳
このとき、同時ユーザー数が非常に多いため、リードキャッシュへのデータの読み込みが同時に行われず、データベースからのデータフェッチも同時に行われるため、データベースへの負荷が瞬間的に増大し、過度のプレッシャー。キャッシュ雪崩とは異なり、キャッシュ ブレークダウンは同じデータに対する同時クエリを指します。キャッシュ雪崩とは、異なるデータの有効期限が切れ、大量のデータが見つからないため、データベースが検索されることを意味します。
解決策:
1)ホットスポット データが期限切れにならず、非同期スレッドによって処理されるように設定します。
2)ライトバック操作とミューテックス ロックを追加すると、クエリが失敗した場合にすぐにデフォルト値が返されます。
3) キャッシュのウォームアップ
システムがオンラインになると、関連性があり予測可能な (ランキングなど)ホットスポット データがキャッシュに直接ロードされます。
キャッシュを書き込んでページを更新し、オンラインおよびオフラインでホット データ (広告プロモーションなど) を手動で操作します。
4. データの不整合
キャッシュマシンの帯域幅がいっぱいになったり、コンピュータルームのネットワークが変動したりすると、キャッシュの更新に失敗し、新しいデータがキャッシュに書き込まれず、キャッシュとDBの間でデータの不整合が発生します。再ハッシュをキャッシュする際、特定のキャッシュ マシンが異常を繰り返し、オンラインとオフラインを複数回繰り返し、再ハッシュされるリクエストを複数回更新しました。このように、1 つのデータが複数のノードに存在し、各再ハッシュでは特定のノードのみが更新されるため、一部のキャッシュ ノードでダーティ データが生成されます。
- キャッシュの更新が失敗した後、再試行して、再試行に失敗したキーを mq に書き込むことができます。キャッシュ アクセスが回復すると、これらのキーはキャッシュから削除されます。これらのキーが再度クエリされると、データの一貫性を確保するために DB から再ロードされます。
- データの最終的な整合性を確保するために、キャッシュされたデータが早期に期限切れになり、DB から再ロードできるように、キャッシュ時間を適切に短縮する必要があります。
- リハッシュ ドリフト戦略は使用されませんが、ダーティ データの生成を可能な限り回避するためにキャッシュ階層化戦略が使用されます。
5. データ同時実行性の競争
データの同時実行性の競合は、発券システムなどの高トラフィック システムでも一般的であり、特定の列車旅行のキャッシュ情報の有効期限が切れても、依然として多数のユーザーがその列車旅行情報をクエリしている場合があります。別の例として、Weibo システムでは、ある Weibo がたまたまキャッシュから削除されたとしても、この Weibo には依然として大量のリツイート、コメント、いいねが残っています。上記の状況はすべて、同時競合読み取りの問題を引き起こします。
- ライトバック操作にミューテックス ロックを追加すると、クエリが失敗した場合にすぐにデフォルト値が返されます。
- 同時実行競合の可能性を減らすために、キャッシュされたデータの複数のバックアップを維持します。
6. ホットキーの問題
有名人の結婚、離婚、不倫などの特別な緊急事態、オリンピックや春節などの主要なイベントやお祭り、フラッシュセール、ダブル12、618などのオンラインプロモーションでは、ホットキーな状況が発生しやすい。
ホットキーを事前に確認するにはどうすればよいですか?
- 重要な休日やオンライン プロモーションなど、事前にわかっていることについては、可能性のあるホット キーを事前に評価できます。
- 事前に評価できない緊急事態の場合、Spark を使用して、対応するストリーミング タスクのリアルタイム分析を実行し、新しくリリースされたホット キーをタイムリーに検出できます。以前に送信され、徐々にホット キーになったものについては、Hadoop を使用してバッチ処理タスクでオフライン計算を実行し、最近の履歴データで高頻度のホット キーを見つけることができます。
解決策:
- これらの n 個のキーは複数のキャッシュ ノードに分散されており、クライアントがリクエストすると、特定のサフィックスを持つホットキーにランダムにアクセスされるため、ホット キーのリクエストが分散され、キャッシュ ノードの過負荷が回避されます。
- キャッシュ クラスターは、単一ノード上でマスター/スレーブ レプリケーションと垂直拡張を実行できます。
- アプリ内プリキャッシュを利用しますが、上限を設定する必要があることに注意してください
- リアルタイム認識のための遅延の影響を受けない、スケジュールされた更新、アクティブな更新
- キャッシュ侵入と同様に、エスケープ トラフィックを制限し、単一のリクエストでデータをソースに返し、フロントエンドを更新します。
- どのように設計しても、数千万のトラフィックをすぐに利用できるように、最終的には徹底的なロジックを作成する必要があります。
7. BigKey 問題
たとえば、インターネット システムでは、基本情報、関係グラフの数、フィード統計などを含むユーザーの個人情報キャッシュなど、ユーザーの最新の 10,000 人のファンを保存する必要があります。Weiboのフィードコンテンツのキャッシュも発生しやすく、一般的にユーザーのWeibo投稿は140ワード以内ですが、多くのユーザーは1,000ワード以上のWeiboコンテンツを投稿するため、これらの長文Weibo投稿が大きな鍵となっています。
- まず、Redis の基盤となるデータ構造では、Value の違いに基づいてデータ構造が再選択されます。
- 新しいデータ構造を拡張、シリアル化、構築し、復元を通じて 1 回の実行で書き込むことができます。
- 大きなキーを複数のキーに分割し、有効期限を長く設定します。