Redis に関する 20 の典型的な面接質問の要約と共有 (回答分析付き)
ゴールデン ナインとシルバー 10 が間もなく登場します。この記事では、Redis の典型的な面接の質問 20 個を紹介します。皆さんのお役に立てれば幸いです。
#1. Redis とは何ですか?主に何に使用されますか?
Redis は、正式な英語名は Remote Dictionary Server (リモート辞書サービス) で、ANSI C 言語で書かれたオープンソースで、ネットワークをサポートし、メモリベースにすることができます。永続的なログ タイプ、Key-Value データベースを備え、複数の言語で API を提供します。 [関連する推奨事項: Redis ビデオ チュートリアル ]
MySQL データベースとは異なり、Redis データはメモリに保存されます。読み取りおよび書き込み速度は非常に高速で、1 秒あたり 100,000 回を超える読み取りおよび書き込み操作を処理できます。したがって、Redis はキャッシュに広く使用されているだけでなく、分散ロックにもよく使用されます。さらに、Redis はトランザクション、永続性、LUA スクリプト、LRU 駆動イベント、およびさまざまなクラスター ソリューションをサポートします。
2. Redis の基本的なデータ構造タイプについて話しましょうRedis には次の 5 つの基本的なタイプがあることはほとんどの友人が知っています:
String (文字列)
- Hash (ハッシュ)
- List (リスト)
- Set (セット)
- zset (順序付きセット) )
- これには、3 つの特殊なデータ構造タイプもあります。
- ハイパーログログ
- ビットマップ
- 2.1 5 つRedis の基本データ型
#String (string)
- 簡単な使用例: set key value
- 、
get key
などアプリケーション シナリオ: 共有セッション、分散ロック、カウンター、電流制限。
- 内部エンコードには int (8 バイト長の整数)/embstr (39 バイト以下の文字列)/raw (39 バイトを超える文字列)の 3 種類があります
-
##C 言語の文字列は
char[]
SDS (単純な動的文字列) カプセル化を使用します。sds のソース コードは次のとおりです。 :
struct sdshdr{ unsigned int len; // 标记buf的长度 unsigned int free; //标记buf中未使用的元素个数 char buf[]; // 存放元素的坑 }
C 言語ネイティブであるのに、Redis が SDS
char[] いい匂いしませんか? たとえば、SDS では、文字列の長さは O(1) の時間計算量で取得できますが、C 文字列の場合は、文字列全体を走査する必要があり、時間計算量は O です。 (n)
Hash (ハッシュ)
はじめに: Redis では、ハッシュ タイプは、キーと値のペア (k-v) である v (値) 自体を指します。構造
- 簡単な使用例:
- hset キー フィールド値 、
- hget キー フィールド
#内部エンコーディング:
ziplist (圧縮リスト)
, hashtable (ハッシュ テーブル) アプリケーション シナリオ: ユーザー情報のキャッシュなど。
Note- : hgetall を開発に使用し、ハッシュ要素が多い場合、Redis がブロックされる可能性があります。hscan を使用できます。一部のフィールドのみを取得したい場合は、hmget を使用することをお勧めします。
- 文字列型とハッシュ型の比較は次のとおりです:
- lpush key value [value ...]
- , lrange key start end
内部エンコーディング: ziplist (圧縮リスト) )、linkedlist (リンク リスト)
アプリケーション シナリオ: メッセージ キュー、記事リスト、
リスト タイプの挿入とポップアップを理解するための 1 つの図:
lpush lpop=Stack (スタック)
lpush rpop=Queue (キュー)
- lpsh ltrim=Capped Collection (限定コレクション)
- lpush brpop=Message Queue (メッセージキュー)
- Set (コレクション)
- はじめに: set タイプは複数の文字列要素を保存するためにも使用されますが、要素の重複は許可されません
- 簡単な使用例:
sadd key element [element ... ]
, smembers key
- 内部エンコード:
intset (整数セット)
, hashtable (ハッシュ テーブル)
- Note: smembers、lrange、hgetall はいずれも比較的重いコマンドですが、要素が多すぎて Redis がブロックされる可能性がある場合は、sscan を使用して完了できます。
- アプリケーション シナリオ: ユーザー タグ、宝くじ用の乱数生成、およびソーシャル ニーズ。
順序付きセット (zset)
- 概要: ソートされた文字列のセット。要素は繰り返すことができません。
- 簡単な形式の例:
zadd キー スコア メンバー [スコア メンバー ...]
、zrank キー メンバー
- 基になる内部エンコード:
ziplist (圧縮リスト)
、skiplist (ジャンプ テーブル)
- アプリケーション シナリオ: ランキング、ソーシャル ニーズ (ユーザーの好みなど)。
2.2 Redis の 3 つの特別なデータ型
- Geo: Redis3.2 によって開始された地理的位置測位は、地理的位置情報を保存し、情報の実行操作を保存するために使用されます。
- HyperLogLog: 統計 Web サイトの UV など、カーディナリティ統計アルゴリズムに使用されるデータ構造。
- ビットマップ: 1 ビットを使用して要素のステータスをマップします。Redis では、その最下層は文字列型に基づいて実装されます。ビットマップはビット単位の配列に変換できます。
3. Redis はなぜそれほど速いのでしょうか?
sadd key element [element ... ]
, smembers key
intset (整数セット)
, hashtable (ハッシュ テーブル)
zadd キー スコア メンバー [スコア メンバー ...]
、zrank キー メンバー
ziplist (圧縮リスト)
、skiplist (ジャンプ テーブル)
3.1 メモリ ストレージに基づく実装
メモリの読み取りと書き込みがディスクよりもはるかに高速であることは誰もが知っています。メモリ ストレージ。データはディスク上の MySQL データベースに保存されるため、ディスク I/O の消費がなくなります。
3.2 効率的なデータ構造
効率を向上させるために、Mysql インデックスは B ツリー データ構造を選択することがわかっています。実際、合理的なデータ構造により、アプリケーション/プログラムを高速化できます。まず、Redis のデータ構造と内部エンコード図を見てみましょう。
#SDS 単純な動的文字列
- #文字列の長さの処理: Redis は文字列の長さを取得します。時間計算量は O(1) ですが、C 言語では最初からたどる必要があり、計算量は O(n);
- スペースの事前割り当て : 文字列が変更される頻度が高くなるほど、メモリの割り当ても頻繁になり、パフォーマンスが消費されます。SDS の変更とスペースの拡張により、追加の未使用スペースが割り当てられ、パフォーマンスの損失が軽減されます。
- Lazy space release: SDS が短縮されると、余分なメモリ領域をリサイクルする代わりに、free に余分な領域が記録されます。その後変更があった場合、free に記録された領域は割り当てを削減するために直接使用されます。
- バイナリ セーフティ: Redis はバイナリ データを保存できます。C 言語では、文字列は '\0' に遭遇すると終了しますが、SDS では、len 属性が文字列の終わりをマークします。
Dictionary
Redis は K-V 型のメモリ データベースであり、すべてのキー値は辞書に格納されます。ディクショナリは HashMap などのハッシュ テーブルであり、キーを通じて対応する値を直接取得できます。ハッシュテーブルの特徴としては、O(1)の計算量で対応する値が得られる。
ジャンプ テーブル
- スキップ テーブルは Redis の独自のデータ構造であり、リンク リストに基づいて複数のデータを追加します。 -レベルインデックスの改善、検索効率。
- スキップ テーブルは、平均 O(logN) および最悪の場合の O(N) 複雑さによるノード検索をサポートし、順次操作を通じてノードをバッチで処理することもできます。
3.3 合理的なデータ エンコーディング
Redis は複数のデータ型をサポートしており、各基本型は複数のデータ構造を持つことができます。いつ、どのようなデータ構造を使用するか、どのエンコーディングを使用するかは、Redis デザイナーの要約と最適化の結果です。
3.4 合理的なスレッド モデル##I/O 多重化
- 文字列: 数値が格納される場合は、int 型のエンコードが使用されます。数値以外が格納される場合は、39 バイト以下の文字列は embstr です。39 バイトより大きい場合は、embstr になります。は生のエンコーディングです。
- リスト: リスト内の要素の数が 512 未満で、リスト内の各要素の値が 64 バイト (デフォルト) 未満の場合は、ziplist エンコードを使用します。それ以外の場合は、リンクリスト エンコードを使用します。
- Hash: Ha ハッシュ型要素の数が 512 未満で、すべての値が 64 バイト未満の場合は ziplist エンコーディングを使用し、それ以外の場合はハッシュテーブル エンコーディングを使用します。
- Set: セット内の要素がすべて整数で、要素の数が 512 未満の場合は、intset エンコーディングを使用します。それ以外の場合は、ハッシュテーブル エンコーディングを使用します。
#Zset: 順序付きセット内の要素の数が 128 未満で、各要素の値が 64 バイト未満の場合は、ziplist エンコーディングを使用します。それ以外の場合は、skiplist (スキップ リスト) エンコーディングを使用します
##複数の I/O 多重化このテクノロジーにより、単一のスレッドで複数の接続リクエストを効率的に処理できるようになり、Redis は I/O 多重化テクノロジーの実装として epoll を使用します。さらに、Redis 独自のイベント処理モデルは、ネットワーク I/O にあまり時間を費やすことなく、epoll での接続、読み取り、書き込み、およびシャットダウンをイベントに変換します。
I/O: ネットワーク I/OI/O 多重化とは何ですか?
マルチチャネル: 複数のネットワーク接続多重化: 同じスレッドを再利用します。 IO 多重化は実際には同期 IO モデルであり、複数のファイル ハンドルを監視できるスレッドを実装します。ファイル ハンドルの準備が完了すると、対応する読み取りおよび書き込み操作を実行するようにアプリケーションに通知できます。ファイル ハンドルがない場合は、準備ができている場合、アプリケーションはブロックされ、CPU が引き渡されます。
シングル スレッド モデル
Redis はシングル スレッド モデルであり、シングル スレッドにより不必要なコンテキストの切り替えや競合が回避されます。 CPU ロックの消費量。シングルスレッドであるため、特定のコマンド(hgetallコマンドなど)を長時間実行するとブロッキングが発生します。 Redis は、高速実行シナリオのためのデータベースです。 、そのため、smembers、lrange、hgetall などのコマンドは注意して使用する必要があります。
- Redis 6.0 では高速化のためにマルチスレッドが導入されていますが、コマンドとメモリ操作の実行は引き続きシングル スレッドです。
- 3.5 仮想メモリ機構
Redis の仮想メモリ メカニズムとは何ですか?
仮想メモリ メカニズムは、アクセス頻度の低いデータ (コールド データ) をメモリからディスクに一時的に交換し、アクセスする必要がある他のデータ (ホット データ) のために貴重なメモリ領域を解放します。 。 データ)。 VM 機能は、ホット データとコールド データの分離を実現できるため、ホット データはメモリ内に残り、コールド データはディスクに保存されます。これにより、メモリ不足によるアクセス速度の低下の問題を回避できます。
4.1 キャッシュの侵入の問題 まず、キャッシュの一般的な使用方法を見てみましょう: 読み取りリクエストが来たとき、最初にキャッシュを確認します。キャッシュに値がヒットした場合、キャッシュは直接返されます。 ; キャッシュが見つからない場合は、データベースをチェックし、データベースの値をキャッシュに更新してから戻ります。4. キャッシュ ブレークダウン、キャッシュ ペネトレーション、キャッシュ アバランチとは何ですか?
キャッシュ侵入
平たく言えば、読み取りリクエストがアクセスされるとき、キャッシュにもデータベースにも特定の値がないため、この値に対する各クエリ リクエストがデータベースに侵入します。これがキャッシュの侵入です。 . .
不合理なビジネス設計キャッシュの侵入は通常、次の状況によって発生します。
- 。たとえば、ほとんどのユーザーは Guard を有効にしていませんが、すべてのユーザーが Guard を有効にしていません。作成したリクエストはキャッシュに保存され、特定のユーザー ID が保護されているかどうかがチェックされます。
- ビジネス/運用/メンテナンス/開発エラー (キャッシュやデータベース データが誤って削除されるなど)。
- ハッカーによる違法なリクエスト攻撃 たとえば、ハッカーは、存在しないビジネス データを読み取るための大量の違法なリクエストを意図的にでっち上げます。
- キャッシュの侵入を回避するにはどうすればよいですか?
- 1. 不正なリクエストの場合は、API 入口でパラメータを検証し、不正な値を除外します。
- 2. クエリ データベースが空の場合は、キャッシュに null 値またはデフォルト値を設定できます。ただし、書き込み要求が来た場合は、キャッシュの整合性を確保するためにキャッシュを更新する必要があり、同時に、最終的にキャッシュに適切な有効期限が設定されます。 (ビジネスでよく使用され、シンプルで効果的です)
- 3. ブルーム フィルターを使用して、データが存在するかどうかをすばやく判断します。つまり、クエリリクエストが来ると、まずブルームフィルターを通して値が存在するかどうかを判断し、その後も存在するかどうかを確認し続けます。
ブルーム フィルターの原理: 初期値 0 のビットマップ配列と N 個のハッシュ関数で構成されます。キーに対して N 個のハッシュ アルゴリズムを実行して N 個の値を取得します。これらの N 個の値をビット配列でハッシュし、1 に設定します。次に、チェック時に、これらの特定の位置がすべて 1 であれば、ブルーム フィルター処理が行われます。サーバーはキーが存在すると判断します。 。
4.2 キャッシュ スノー ランの問題
キャッシュ スノー ラン: とは、キャッシュ内の大量のデータ バッチの有効期限とクエリ データの量を指します。は巨大で、すべてのリクエストはデータベースに直接アクセスされるため、データベースに過剰な負荷がかかったり、マシンがダウンしたりすることがあります。
- キャッシュスノースノーは一般に、大量のデータが同時に期限切れになることで発生するため、有効期限を均等に設定する、つまり有効期限を比較的離散的に設定することで解決できます。 。たとえば、より大きな固定値とより小さなランダム値 (5 時間、0 ~ 1800 秒) を使用します。
- Redis の障害により、キャッシュ スノー雪が発生する可能性もあります。これには、Redis 高可用性クラスターを構築する必要があります。
4.3 キャッシュ ブレークダウンの問題
キャッシュ ブレークダウン: とは、ホットスポット キーが特定の時点で期限切れになることを指し、まさにその時点で、このキーには多数の同時リクエストがあるため、大量のリクエストがデータベースにヒットします。
キャッシュのブレークダウンは少し似ています。実際、それらの違いは、キャッシュの降雪は、データベースに過度の圧力がかかっているか、さらにはダウンしていることを意味することです。キャッシュのブレークダウンは、単に DB データベースへの同時リクエストの数が多いだけです。レベル。ブレークダウンはキャッシュ スノーランのサブセットであると考えることができます。一部の記事では、この 2 つの違いは、ブレークダウンが特定のホット キー キャッシュを対象としているのに対し、Xuebeng は多くのキーを対象としている点であると考えられています。
解決策は 2 つあります:
- 1. ミューテックス ロック スキームを使用します。キャッシュが失敗した場合、データベース データをすぐにロードするのではなく、まず (Redis の setnx) など、成功した場合のアトミック操作コマンドを使用して操作し、成功したら db データベース データをロードしてキャッシュを設定します。それ以外の場合は、キャッシュを再度取得してみてください。
- 2.「期限切れにならない」 は、有効期限が設定されていないが、ホットスポット データの有効期限が近づくと、非同期スレッドが更新されて有効期限を設定することを意味します。
5. ホット キーの問題とその解決方法
ホット キー とは何ですか? Redisではアクセス頻度の高いキーをホットスポットキーと呼びます。
ホットスポット キーのリクエストがサーバー ホストに送信されると、リクエスト量が特に多いため、ホスト リソースが不足したり、ダウンタイムが発生したりして、通常のサービスに影響を与える可能性があります。
ホットスポット キーはどのように生成されますか?主な理由は 2 つあります。
- ユーザーが消費するデータは、速報セール、話題のニュース、その他のシナリオなど、より多くの読み取りとより少ない書き込みが必要なシナリオなど、生成されるデータよりもはるかに大きいためです。
- リクエストシャーディングが集中し単一のRediサーバーの性能を超え、例えば固定名のキーとハッシュが同一サーバーに落ちてしまうとインスタントアクセス量が膨大になりマシンのボトルネックを超えてしまい、ホットキーの問題を引き起こします。
では、日々の開発においてホットキーを特定するにはどうすればよいでしょうか?
- どのホット キーがエクスペリエンスに基づいているかを決定する;
- クライアント統計をレポートする;
- サービス エージェント層にレポートする
ホットキーの問題を解決するにはどうすればよいですか?
- Redis クラスターの拡張: シャード コピーを追加して読み取りトラフィックのバランスをとる;
- ホット キーをさまざまなサーバーに配布する;
- セカンダリ キャッシュを使用する、つまり、 JVM ローカル キャッシュにより、Redis 読み取りリクエストが削減されます。
6. Redis の有効期限戦略とメモリ削除戦略
6.1 Redis の有効期限戦略
現在set key
の場合、expire key 60
のように有効期限を設定できます。このキーが 60 秒後に期限切れになるように指定します。60 秒後に Redis はそれをどのように処理しますか?まず、いくつかの有効期限戦略を紹介します。
スケジュールされた有効期限
# 有効期限のあるキーごとにタイマーを作成する必要があり、有効期限に達するとキーはすぐにクリアされます。 。この戦略は期限切れのデータを即座にクリアでき、メモリに非常に優しいですが、期限切れのデータを処理するために大量の CPU リソースを占有するため、キャッシュの応答時間とスループットに影響します。
遅延有効期限
キーにアクセスしたときのみ、キーの有効期限が切れているかどうかを判定し、有効期限が切れたらキーをクリアします。この戦略は CPU リソースを最大限に節約できますが、メモリには非常に優しくありません。極端な場合には、期限切れの多数のキーに再度アクセスできなくなり、クリアされずに大量のメモリを占有してしまうことがあります。
定期的な有効期限
一定の時間ごとに、特定の数のデータベースの有効期限切れディクショナリ内の特定の数のキーがスキャンされ、期限切れのキーがクリアされます。 。この戦略は、最初の 2 つの戦略の折衷案です。スケジュールされたスキャンの時間間隔と各スキャンの制限された消費時間を調整することにより、さまざまな状況下で CPU とメモリのリソース間の最適なバランスを実現できます。
expires ディクショナリは、有効期限が設定されたすべてのキーの有効期限データを保存します (key はキー空間内のキーへのポインタ、value はミリ秒精度のキーの UNIX タイムスタンプ)。 。キースペースは、Redis クラスターに保存されているすべてのキーを指します。
Redis は、遅延有効期限と定期有効期限の両方を使用します2 つの有効期限戦略を使用します。
- Redis には現在 300,000 個のキーが保存されており、すべてに有効期限が設定されていると仮定します。100 ミリ秒ごとにすべてのキーをチェックすると、CPU の負荷が非常に高くなり、最終的にはハングする可能性があります。
- したがって、redis は定期的な有効期限を使用し、特定の数のキーをランダムに選択して 100 ミリ秒ごとにチェックして削除します。
- ただし、最終的には、削除されずに期限切れのキーが多数存在する可能性があります。現時点では、redis は遅延削除を使用します。キーを取得すると、redis がそれをチェックします。キーに有効期限が設定されており、有効期限が切れている場合は、この時点で削除されます。
ただし、通常の削除で期限切れのキーが多数失われる場合、遅延削除は実行されません。メモリには期限切れのキーが大量に蓄積され、メモリの爆発の直接の原因となります。あるいは、業務量が増加すると、Redis キーが頻繁に使用され、単純にメモリが不足し、運用保守担当者がメモリの増設を忘れることもあります。 Redis はこのままハングアップしてしまうのでしょうか?しない! Redis は、自身を保護するために 8 つのメモリ削除戦略を使用します~
6.2 Redis のメモリ削除戦略
- volatile-lru: メモリが新しく書き込まれたデータを収容するのに十分でない場合、有効期限が切れたキーには LRU (最も最近使用されていない) アルゴリズムを使用します;
- allkeys-lru: メモリが新しく書き込まれたデータを収容するのに不十分な場合は、すべてのキーから LRU (最も最近使用されていない) アルゴリズムを使用します消去法を実行します。
- volatile-lfu: バージョン 4.0 で新たに追加され、メモリが新しく書き込まれたデータを収容するのに不十分な場合、LFU アルゴリズムを使用して期限切れのキーの中からキーを削除します。
- allkeys-lfu: バージョン 4.0 で新たに追加され、メモリが新しく書き込まれたデータを収容するのに十分でない場合、LFU アルゴリズムを使用してすべてのキーが削除されます;
- volatile-random:メモリが不足している場合 新しく書き込まれたデータを収容する場合、有効期限を設定してキーからデータをランダムに削除します。
- allkeys-random: メモリが新しく書き込まれたデータを収容するのに不十分な場合、データはすべてのキーからランダムに削除されます。
- volatile-ttl: メモリが新しく書き込まれたデータを収容するのに十分ではない場合、有効期限が設定されているキーは有効期限に従って削除され、有効期限の早いキーが最初に削除されます。
- noeviction: デフォルト ポリシー。メモリが新しく書き込まれたデータを収容するのに十分でない場合、新しい書き込み操作はエラーを報告します。
7. Redis の一般的なアプリケーション シナリオについて説明します
- キャッシュ
- ランキング
- カウンター アプリケーション
- 共有セッション
- 分散ロック
- ソーシャル ネットワーク
- メッセージ キュー
- ビット操作
7.1 キャッシュ
redis というと当然キャッシュが思い浮かびますが、国内外の中大規模の Web サイトはキャッシュと切っても切れない関係にあります。ホットスポット データのキャッシュなど、キャッシュを適切に使用すると、Web サイトのアクセス速度が向上するだけでなく、データベース DB への負荷も軽減されます。さらに、memcached と比較して、Redis は豊富なデータ構造も提供し、RDB や AOF などの最も強力な永続化メカニズムも提供します。
7.2 ランキング
現在のインターネットアプリケーションには、ECサイトの月次売上ランキング、ソーシャルAPPのプレゼントランキング、ミニプログラムの投票ランキングなど、さまざまなランキングが存在します。すぐ。 Redis が提供する zset
データ型は、これらの複雑なランキングを実装できます。
たとえば、ユーザーが毎日ビデオをアップロードする場合、「いいね!」のランキング リストは次のように設計できます。
- 1.用户Jay上传一个视频,获得6个赞,可以酱紫:
zadd user:ranking:2021-03-03 Jay 3
- 过了一段时间,再获得一个赞,可以这样:
zincrby user:ranking:2021-03-03 Jay 1
- 如果某个用户John作弊,需要删除该用户:
zrem user:ranking:2021-03-03 John
- 展示获取赞数最多的3个用户
zrevrangebyrank user:ranking:2021-03-03 0 2
7.3 计数器应用
各大网站、APP应用经常需要计数器的功能,如短视频的播放数、电商网站的浏览数。这些播放数、浏览数一般要求实时的,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。
7.4 共享Session
如果一个分布式Web服务将用户的Session信息保存在各自服务器,用户刷新一次可能就需要重新登录了,这样显然有问题。实际上,可以使用Redis将用户的Session进行集中管理,每次用户更新或者查询登录信息都直接从Redis中集中获取。
7.5 分布式锁
几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源的并发访问的技术难题,如秒杀、下单减库存等场景。
- 用synchronize或者reentrantlock本地锁肯定是不行的。
- 如果是并发量不大话,使用数据库的悲观锁、乐观锁来实现没啥问题。
- 但是在并发量高的场合中,利用数据库锁来控制资源的并发访问,会影响数据库的性能。
- 实际上,可以用Redis的setnx来实现分布式的锁。
7.6 社交网络
赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适保存 这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。
7.7 消息队列
消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。
7.8 位操作
用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多。这里要用到位操作——使用setbit、getbit、bitcount命令。原理是:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统。
8. Redis 的持久化机制有哪些?优缺点说说
Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。
Redis提供了RDB和AOF两种持久化机制,它持久化文件加载流程如下:
8.1 RDB
RDB,就是把内存数据以快照的形式保存到磁盘上。
什么是快照?可以这样理解,给当前时刻的数据,拍一张照片,然后保存下来。
RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb
文件,Redis 重启的时候,通过加载dump.rdb
文件来恢复数据。RDB触发机制主要有以下几种:
RDB 的优点
- 适合大规模的数据恢复场景,如备份,全量复制等
RDB缺点
- リアルタイムの永続性/第 2 レベルの永続性を実現する方法はありません。
- 古いバージョンと新しいバージョンには RDB 形式の互換性の問題があります
AOF
##AOF (追加のみのファイル) ログ形式の永続性各書き込み操作を記録してファイルに追加し、AOF ファイル内のコマンドを再実行して、再起動時にデータを回復します。これは主にデータの永続性に関するリアルタイムの問題を解決します。デフォルトでは有効になっていません。
AOF のワークフローは次のとおりです。AOF の利点
- データの一貫性とより高い整合性
AOF の欠点
- AOF が記録するコンテンツが増えると、ファイルが大きくなり、データの回復が遅くなります。
マスター/スレーブ モード、センチネル モード、およびクラスター モードという 3 つのデプロイメント モードがあります。
9.1 マスター/スレーブ モードマスター/スレーブ モードでは、Redis は複数のマシンをデプロイします。マスター ノードは読み取りおよび書き込み操作を担当し、スレーブ ノードは読み取り操作のみを担当します。スレーブ ノードのデータはマスター ノードから取得されます。実装原理は次のとおりです。マスター/スレーブ レプリケーション メカニズム
マスター/スレーブ レプリケーションには、フル レプリケーションと増分レプリケーションが含まれます。一般に、スレーブが初めてマスターに接続を開始する場合、または初めての接続とみなされる場合は、フル コピーが使用されます。フル コピー プロセスは次のとおりです:
- 1.スレーブはマスターに同期コマンドを送信します。 2. マスターは SYNC コマンドを受信した後、bgsave コマンドを実行して完全な RDB ファイルを生成します。 3. マスターはバッファを使用して、RDB スナップショットの生成中にすべての書き込みコマンドを記録します。 4. マスターは bgsave を実行した後、RDB スナップショット ファイルをすべてのスレーブに送信します。 5. スレーブは RDB スナップショット ファイルを受信した後、受信したスナップショットをロードして解析します。 6. マスターはバッファを使用して、RDB 同期中に生成されたすべての書き込みコマンドを記録します。 7.マスター スナップショットが送信された後、バッファ内の書き込みコマンドをスレーブに送信し始めます。8.salve はコマンド リクエストを受け入れ、マスターからの書き込みコマンドを実行します。 buffer
psync が sync の代わりに使用されています。
スレーブがマスターと完全に同期した後、マスター上のデータが再度更新されると、増分レプリケーションがトリガーされます。
マスター ノードでデータが増加または減少すると、replicationFeedSalves() 関数がトリガーされます。その後マスター ノードで呼び出される各コマンドは、
replicationFeedSlaves()スレーブノードと同期します。この関数を実行する前に、マスターノードはユーザーが実行したコマンドにデータ更新があるかどうかを判断し、データ更新があり、スレーブノードが空でなければ、この関数が実行されます。この関数の機能は次のとおりです。
ユーザーが実行したコマンドをすべてのスレーブ ノードに送信します。そして、スレーブ ノードに実行させます。プロセスは次のとおりです。
Sentinel モード: 1 つ以上の Sentinel インスタンスで構成される Sentinel システム。すべての Redis マスター ノードとスレーブ ノードを監視でき、監視対象のマスター ノードが は、オフライン マスター サーバーの下のスレーブ ノードを新しいマスター ノード に自動的にアップグレードします。ただし、センチネル プロセスが Redis ノードを監視する場合、問題が発生する可能性があります (単一点の問題 )。そのため、複数のセンチネルを使用して Redis ノードを監視することができ、各センチネル間で継続的な通信が行われます。
- コマンドを送信し、Redis サーバー (マスター サーバーとスレーブを含む) を待ちます。サーバー) を返し、その実行ステータスを監視します。 Sentinel はマスター ノードがダウンしていることを検出し、スレーブ ノードからマスター ノードに自動的に切り替え、パブリッシュおよびサブスクライブ モードを通じて他のスレーブ ノードに通知します。構成ファイルを変更してホストを切り替えます。 Sentinel は高可用性を実現するために相互監視も行います。
フェイルオーバー プロセスとは何ですか?
メイン サーバーがダウンし、Sentinel 1 がこの結果を最初に検出すると仮定します。システムはすぐにフェイルオーバー プロセスを実行しません。これは、Sentinel 1 が主観的にメイン サーバーが利用できないと信じているだけです。この現象は、主観的なオフライン。後続のセンチネルもメイン サーバーが利用できないことを検出し、その数が特定の値に達すると、センチネル間で投票が行われ、投票の結果に従って 1 つのセンチネルがフェイルオーバー操作を実行します。切り替えが成功すると、各センチネルはパブリッシュ/サブスクライブ モードを使用して、監視するスレーブ サーバーをホストに切り替えます。このプロセスは、客観的オフラインと呼ばれます。このようにして、クライアントに対してすべてが透過的になります。
Sentinel の動作モードは次のとおりです:
各 Sentinel は、マスター、スレーブ、および既知の他の Sentinel インスタンスに 1 秒に 1 回程度メッセージを送信します。 PING コマンド。
PING コマンドに対する最後の有効な応答からの時間が、down-after-milliseconds オプションで指定された値を超えた場合、インスタンスは Sentinel によって主観的にオフラインとしてマークされます。
マスターが主観的オフラインとしてマークされている場合、マスターを監視しているすべてのセンチネルは、マスターが実際に主観的オフライン状態に入ったことを 1 秒に 1 回確認する必要があります。
十分な数のセンチネル (設定ファイルで指定された値以上) が、マスターが指定された時間範囲内に実際に主観的オフライン状態に入ったことを確認すると、マスターはオフラインの目標としてマークされます。
通常の状況では、各センチネルは、10 秒に 1 回、知っているすべてのマスターとスレーブに INFO コマンドを送信します。
マスターが Sentinel によって客観的にオフラインとしてマークされると、Sentinel がオフライン マスターのすべてのスレーブに INFO コマンドを送信する頻度が 10 秒に 1 回から 1 秒に 1 回に変更されます
マスターがオフラインであることに同意する十分なセンチネルがいない場合、マスターの客観的なオフライン ステータスは削除されます。マスターがセンチネルの PING コマンドに対して有効な応答を返した場合、マスターの主観的なオフライン ステータスは削除されます。オフラインステータスが削除されます。ステータスが削除されます。
9.3 クラスタクラスタモード
センチネルモードは、マスター/スレーブモードをベースにしており、読み取りと書き込みの分離を実現しており、自動的に切り替えることもでき、システムの可用性を向上させることができます。より高い。ただし、各ノードに保存されるデータは同じであるため、メモリを無駄に消費し、オンラインで拡張するのは簡単ではありません。 そこで、Redis3.0 で追加され、Redis の 分散ストレージ が実装された Cluster クラスターが登場しました。データをセグメント化します。これは、オンライン拡張の問題を解決するために、 各 Redis ノードが異なるコンテンツを格納することを意味します。さらに、レプリケーションおよびフェイルオーバー機能も提供します。
クラスタークラスターノードの通信Redisクラスターは複数のノードで構成されます。各ノードはどのように通信しますか? ゴシッププロトコルを通じて!
Redis Cluster クラスターは Gossip プロトコルを通じて通信します。ノードは継続的に情報を交換します。交換される情報には、ノードの障害、新しいノードの参加、マスター/スレーブ ノードの変更情報、スロット情報などが含まれます。一般的に使用されるゴシップ メッセージは、ping、pong、meet、fail の 4 つのタイプに分類されます。#meet メッセージ: 新しいノードに参加するよう通知します。メッセージ送信者は受信者に現在のクラスタへの参加を通知し、meet メッセージ通信が正常に完了すると、受信ノードはクラスタに参加し、定期的な ping および pong メッセージ交換を実行します。クラスターバス(クラスターバス)特に、各ノードは
- Ping メッセージ: クラスター内で最も頻繁に交換されるメッセージ。クラスター内の各ノードは、他の複数のノードに毎秒 ping メッセージを送信します。これは、ノードがオンラインかどうかを検出し、ステータス情報を相互に交換するために使用されます。 。
- pong メッセージ: ping または meets メッセージを受信すると、メッセージが正常に通信されたことを確認するための応答メッセージとして送信者に返信します。 pong メッセージは、独自のステータス データを内部的にカプセル化します。ノードは、自身の pong メッセージをクラスターにブロードキャストして、クラスター全体にステータスを更新するように通知することもできます。
- 失敗メッセージ: ノードは、クラスター内の別のノードがオフラインであると判断すると、クラスターに失敗メッセージをブロードキャストします。失敗メッセージを受信した後、他のノードは、対応するノードをオフライン状態に更新します。
を介して他のノードと通信します。通信する場合は、外部サービスのポート番号に 10000 を加えた特別なポート番号を使用します。たとえば、ノードのポート番号が 6379 の場合、他のノードとの通信に使用するポート番号は 16379 になります。ノード間の通信には特別なバイナリ プロトコルが使用されます。 ハッシュ スロット スロット アルゴリズム
分散ストレージなので、クラスター クラスターで使用される分散アルゴリズムは
Consistent Hash ですか?いいえ、ただし ハッシュ スロット スロット アルゴリズム 。 スロット アルゴリズムデータベース全体は 16384 個のスロット (スロット) に分割されており、Redis に入力される各キーと値のペアはキーに従ってハッシュされ、16384 個のスロットの 1 つに割り当てられます。使用されるハッシュ マップも比較的単純で、CRC16 アルゴリズムを使用して 16 ビット値を計算し、その後 16384 を法とします。データベース内の各キーはこれら 16384 個のスロットの 1 つに属し、クラスター内の各ノードはこれらの 16384 個のスロットを処理できます。 クラスター内の各ノードは、ハッシュ スロットの一部を担当します。たとえば、現在のクラスターにはノード A、B、および C があり、各ノードのハッシュ スロットの数 = 16384/3、 Redis Cluster クラスターでは、16384 スロットに対応するノードが正常に動作していることを確認する必要があります。場合、担当するスロットも失敗し、クラスター全体が機能しなくなります。 したがって、高可用性を確保するために、クラスター クラスターではマスター/スレーブ レプリケーションが導入され、1 つのマスター ノードが 1 つ以上のスレーブ ノードに対応します。他のマスター ノードがマスター ノード A に ping を実行するときに、マスター ノードの半分以上が A との通信がタイムアウトになると、マスター ノード A はダウンしていると見なされます。マスター ノードがダウンすると、スレーブ ノードが有効になります。 Redis の各ノードには 2 つのものがあり、1 つはスロットで、その値の範囲は 016383 です。もう 1 つはクラスターで、クラスター管理プラグインとして理解できます。アクセスするキーが到着すると、Redis は CRC16 アルゴリズムに基づいて 16 ビット値を取得し、結果のモジュロ 16384 を取得します。 Jiangzi の各キーは、016383 の間の番号が付けられたハッシュ スロットに対応します。この値を使用して、対応するスロットに対応するノードを見つけ、アクセスするために対応するノードに自動的にジャンプします。 データは異なるノードに個別に保存されますが、クライアントにとってはクラスター全体が 1 つの全体として認識されます。クライアントは任意のノードに接続し、Redis の単一インスタンスを操作しているように見えます。クライアントが操作したキーが正しいノードに割り当てられていない場合、Redis はリダイレクト命令を返し、最終的に正しいノードをポイントします。これはブラウザー ページの 302 リダイレクト ジャンプに似ています。 Redis クラスターは高可用性を実現します。クラスター内のノードに障害が発生した場合、フェイルオーバーを使用して、クラスターが確実にサービスを提供できるようにします。通常は外部サービス。 redis クラスターは、ping/pong メッセージを通じて障害の検出を実現します。この環境には、主観的なオフラインと客観的なオフラインが含まれます。 主観的オフライン: ノードは、別のノードが利用できない、つまりオフライン状態であると考えます。この状態は最終的な障害判断ではなく、1 つのノードの意見のみを表すことができます。状況判断を誤る。 目標オフライン: ノードが実際にオフラインであることを示します。クラスター内の複数のノードは、そのノードが利用できないと考えており、コンセンサスに達します。結果。スロットを保持しているマスター ノードに障害が発生した場合、そのノードに対してフェイルオーバーを実行する必要があります。 プロセスは次のとおりです: 障害回復: 障害が発見された後、オフライン ノードがクラスターの高可用性を確保するには、マスター ノードのいずれかを選択して置き換える必要があります。プロセスは次のとおりです。 分散ロックは、分散システム内のさまざまなプロセスを制御して共有リソースに共同でアクセスするロックの実装です。ビジネス シナリオ (フラッシュ販売注文の発行、赤い封筒の取得など) ではすべて、分散ロックの使用が必要です。Redis は、私たちのプロジェクトで分散ロックとしてよく使用されます。 选了Redis分布式锁的几种实现方法,大家来讨论下,看有没有啥问题哈。 如果执行完 笔者看过有开发小伙伴是这么实现分布式锁的,但是这种方案也有这些缺点: 这个方案可能存在这样的问题: 在这里,判断当前线程加的锁和释放锁是不是一个原子操作。如果调用jedis.del()释放锁的时候,可能这把锁已经不属于当前客户端,会解除他人加的锁。 一般也是用lua脚本代替。lua脚本如下:Redis Cluster Cluster
フェイルオーバー
10. Redis 分散ロックを使用したことがありますか?注意すべき点は何ですか?
10.1 命令setnx + expire分开写
if(jedis.setnx(key,lock_value) == 1){ //加锁
expire(key,100); //设置过期时间
try {
do something //业务请求
}catch(){
}
finally {
jedis.del(key); //释放锁
}
}
setnx
加锁,正要执行expire设置过期时间时,进程crash掉或者要重启维护了,那这个锁就“长生不老”了,别的线程永远获取不到锁啦,所以分布式锁不能这么实现。10.2 setnx + value值是过期时间
long expires = System.currentTimeMillis() + expireTime; //系统时间+设置的过期时间
String expiresStr = String.valueOf(expires);
// 如果当前锁不存在,返回加锁成功
if (jedis.setnx(key, expiresStr) == 1) {
return true;
}
// 如果锁已经存在,获取锁的过期时间
String currentValueStr = jedis.get(key);
// 如果获取到的过期时间,小于系统当前时间,表示已经过期
if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
// 锁已过期,获取上一个锁的过期时间,并设置现在锁的过期时间(不了解redis的getSet命令的小伙伴,可以去官网看下哈)
String oldValueStr = jedis.getSet(key_resource_id, expiresStr);
if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
// 考虑多线程并发的情况,只有一个线程的设置值和当前值相同,它才可以加锁
return true;
}
}
//其他情况,均返回加锁失败
return false;
}
jedis.getSet()
,最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖。10.3: set的扩展命令(set ex px nx)(注意可能存在的问题)
if(jedis.set(key, lock_value, "NX", "EX", 100s) == 1){ //加锁
try {
do something //业务处理
}catch(){
}
finally {
jedis.del(key); //释放锁
}
}
10.4 set ex px nx + 校验唯一随机值,再删除
if(jedis.set(key, uni_request_id, "NX", "EX", 100s) == 1){ //加锁
try {
do something //业务处理
}catch(){
}
finally {
//判断是不是当前线程加的锁,是才释放
if (uni_request_id.equals(jedis.get(key))) {
jedis.del(key); //释放锁
}
}
}
if redis.call('get',KEYS[1]) == ARGV[1] then
return redis.call('del',KEYS[1])
else
return 0
end;
这种方式比较不错了,一般情况下,已经可以使用这种实现方式。但是存在锁过期释放了,业务还没执行完的问题(实际上,估算个业务处理的时间,一般没啥问题了)。
11. 使用过Redisson嘛?说说它的原理
分布式锁可能存在锁过期释放,业务没执行完的问题。有些小伙伴认为,稍微把锁过期时间设置长一些就可以啦。其实我们设想一下,是否可以给获得锁的线程,开启一个定时守护线程,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。
当前开源框架Redisson就解决了这个分布式锁问题。我们一起来看下Redisson底层原理是怎样的吧:
只要线程一加锁成功,就会启动一个watch dog
看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了锁过期释放,业务没执行完问题。
12. 什么是Redlock算法
Redis一般都是集群部署的,假设数据在主从同步过程,主节点挂了,Redis分布式锁可能会有哪些问题呢?一起来看些这个流程图:
如果线程一在Redis的master节点上拿到了锁,但是加锁的key还没同步到slave节点。恰好这时,master节点发生故障,一个slave节点就会升级为master节点。线程二就可以获取同个key的锁啦,但线程一也已经拿到锁了,锁的安全性就没了。
为了解决这个问题,Redis作者 antirez提出一种高级的分布式锁算法:Redlock。Redlock核心思想是这样的:
搞多个Redis master部署,以保证它们不会同时宕掉。并且这些master节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个master实例上,是与在Redis单实例,使用相同方法来获取和释放锁。
我们假设当前有5个Redis master节点,在5台服务器上面运行这些Redis实例。
RedLock的实现步骤:如下
- 1. 現在時刻をミリ秒単位で取得します。
- 2. 5 つのマスター ノードに順番にロックを要求します。クライアントはネットワーク接続と応答のタイムアウトを設定します。タイムアウトはロックの有効期限よりも短くする必要があります。 (自動ロックの有効期限が 10 秒であると仮定すると、タイムアウト時間は通常 5 ~ 50 ミリ秒の間になります。タイムアウト時間が 50 ミリ秒であると仮定します)。タイムアウトになった場合は、マスター ノードをスキップして、できるだけ早く次のマスター ノードを試してください。
- 3. クライアントは、現在時刻からロックの取得を開始した時刻 (つまり、手順 1 で記録された時刻) を引いた時刻を使用して、ロックの取得に使用された時間を取得します。 Redis マスター ノードの半分以上 (N/2 1、ここでは 5/2 1 = 3 ノード) がロックを取得し、使用時間がロックの有効期限よりも短い場合に限り、ロックは正常に取得されます。 (上の図に示すように、10 秒 > 30 ミリ秒 40 ミリ秒 50 ミリ秒 4 分 0 秒 50 ミリ秒)
- ロックが取得されると、キーの実際の有効時間が変化するため、ロックを取得するのに費やした時間を差し引く必要があります。
- ロックの取得が失敗した場合 (少なくとも N/2 1 マスター インスタンスでロックが取得されなかった場合、またはロックの取得時間が有効時間を超えた場合)、クライアントはすべてのマスター ノードでロックを解除する必要があります (たとえ一部のマスター ノードは正常にロックされていないため、魚がネットをすり抜けるのを防ぐためにロックを解除する必要があります)。
簡略化された手順は次のとおりです:
- 5 つのマスター ノードに順番にロックを要求します
- 設定されたタイムアウト時間に基づいて判断します。マスターノードをスキップしたいですか?
- 3 ノード以上のロックが成功し、使用時間がロックの有効期間未満であれば、ロックは成功したと見なされます。
- ロックの取得に失敗した場合は、ロックを解除してください。
- ジャンプ テーブルは、順序付きセット zset
- # の基礎となる実装の 1 つです。 # #スキップ テーブルは、平均 O(logN)
- 、最悪の場合 O(N) の複雑さのノード検索をサポートし、順次操作を通じてノードをバッチで処理することもできます。 スキップ テーブルの実装は、 zskiplist と zskiplistNode
- の 2 つの構造で構成されます。zskiplist はスキップ テーブル情報 (ヘッダー ノード、テール ノード、長さなど) を保存するために使用され、zskiplistNode は使用されます。 to スキップテーブルノードを表します。 スキップ リストはリンク リストに基づいており、検索効率を向上させるためにマルチレベルのインデックスが追加されています。
- #14. MySQL と Redis が二重書き込みの一貫性を確保する方法
キャッシュの遅延二重削除
- キャッシュの再試行メカニズムの削除
- Read biglog はキャッシュを非同期的に削除します
- 14.1 二重削除が遅延していますか?
#最初にキャッシュを削除します
次にデータベースを更新します
しばらく(たとえば 1 秒)スリープして、再度キャッシュを削除します。
これは一体どれくらいの時間眠るのでしょうか?全部1秒ですか?
このソリューションは悪くありません。スリープ期間中 (たとえば、わずか 1 秒) に限り、ダーティ データが存在する可能性がありますが、一般の企業はそれを受け入れます。しかし、2 番目のキャッシュの削除が失敗した場合はどうなるでしょうか
キャッシュとデータベースのデータがまだ不整合である可能性がありますよね?キーに自然な有効期限を設定して、自動的に期限切れになるようにしてはどうでしょうか?企業は有効期限内にデータの不整合を受け入れる必要がありますか?それとも他にもっと良い解決策があるのでしょうか?
14.2 キャッシュ削除の再試行メカニズム遅延二重削除はキャッシュ削除の 2 番目のステップで失敗し、データの不整合が発生する可能性があるためです。このソリューションを使用して最適化できます。削除が失敗した場合は、さらに数回削除して、キャッシュの削除が確実に成功するようにします。したがって、削除キャッシュの再試行メカニズムを導入できます
#データベース更新リクエストの書き込み
- 何らかの理由でキャッシュの削除に失敗しました
- 失敗したキーを入力してくださいメッセージ キューへ
- メッセージ キューからメッセージを消費し、削除するキーを取得します #削除キャッシュ操作を再試行します
- 14.3 biglog の読み取りとキャッシュの非同期削除
-
削除キャッシュ メカニズムの再試行は問題ありませんが、大量の
ビジネス コード侵入 を引き起こすことになります。実際、データベースのバイナリログを通じてキーを非同期的に削除するという方法で最適化することもできます。
mysql を例に挙げます
- Alibaba の運河を使用して binlog ログを収集し、MQ キューに送信できます。
- その後、ACK メカニズムを通じてこの更新メッセージを確認して処理し、キャッシュを削除し、データ キャッシュの一貫性を確保します
15. Redis 6.0 以降でマルチスレッドが変更されたのはなぜですか?
- Redis 6.0 より前は、Redis がソケットの読み取り、解析、実行、ソケットの書き込みなどのクライアント リクエストを処理する場合、それらはすべてシーケンシャルでシリアルなメイン スレッドによって処理されていました。 「シングルスレッド」と呼ばれます。
- Redis6.0 より前にマルチスレッドが使用されなかったのはなぜですか? Redis を使用する場合、CPU がボトルネックになる状況はほとんどなく、主にメモリとネットワークによって制限されます。たとえば、通常の Linux システムでは、Redis はパイプライン処理を使用して 1 秒あたり 100 万のリクエストを処理できるため、アプリケーションが主に O(N) または O(log(N)) コマンドを使用する場合、CPU をほとんど消費しません。
Redis によるマルチスレッドの使用は、シングル スレッドを完全に放棄するわけではありません。Redis は依然としてシングル スレッド モデルを使用してクライアント要求を処理します。データの読み取りと書き込みを処理するためにのみマルチ スレッドを使用します。コマンドを実行するには、依然としてシングルスレッドが使用されます。
この目的は、Redis のパフォーマンスのボトルネックが CPU ではなくネットワーク IO にあるためです。マルチスレッドを使用すると、IO の読み取りと書き込みの効率が向上し、それによって Redis の全体的なパフォーマンスが向上します。
16. Redis トランザクション メカニズムについて話しましょう
Redis は、MULTI、EXEC、WATCH などの一連のコマンドを通じてトランザクション メカニズムを実装します。トランザクションは一度に複数のコマンドの実行をサポートしており、トランザクション内のすべてのコマンドはシリアル化されます。トランザクション実行処理中、キュー内のコマンドは順番に実行され、他のクライアントから送信されたコマンド要求はトランザクション実行コマンドシーケンスに挿入されません。
つまり、Redis トランザクションは、キュー内の一連のコマンドを 順次、1 回限り、排他的に実行するものです。
Redis トランザクション実行のプロセスは次のとおりです。- トランザクション開始 (MULTI)
- コマンドエンキュー
- トランザクション実行 (EXEC)、トランザクションのキャンセル (DISCARD)
説明 | |
---|---|
トランザクション ブロック内のすべてのコマンドを実行します | |
トランザクションをキャンセルし、トランザクション ブロック内のすべてのコマンドの実行を中止します | |
トランザクション ブロックの開始をマークします | |
WATCH コマンドによるすべてのキーの監視をキャンセルします。 | |
キーを監視します。トランザクションの実行前に他のコマンドによってキーが変更された場合、トランザクションは中断されます。 |
以上がRedis に関する 20 の典型的な面接質問の要約と共有 (回答分析付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











1. [スタート]メニューを起動し、[cmd]と入力し、[コマンドプロンプト]を右クリックし、[管理者として実行]を選択します。 2. 次のコマンドを順番に入力します (注意してコピーして貼り付けてください): SCconfigwuauservstart=auto、Enter キーを押す SCconfigbitsstart=auto、Enter キーを押す SCconfigcryptsvcstart=auto、Enter キーを押す SCconfigtrustedinstallerstart=auto、Enter キーを押す SCconfigwuauservtype=share、Enter キーを押す netstopwuauserv 、enter netstopcryptS を押す

PHP 関数のボトルネックはパフォーマンスの低下につながります。これは、ボトルネック関数を特定し、パフォーマンス分析ツールを使用するという手順で解決できます。結果をキャッシュして再計算を減らします。タスクを並列処理して実行効率を向上させます。文字列の連結を最適化し、代わりに組み込み関数を使用します。カスタム関数の代わりに組み込み関数を使用します。

GolangAPI のキャッシュ戦略により、パフォーマンスが向上し、サーバーの負荷が軽減されます。一般的に使用される戦略は、LRU、LFU、FIFO、TTL です。最適化手法には、適切なキャッシュ ストレージの選択、階層型キャッシュ、無効化管理、監視とチューニングが含まれます。実際には、データベースからユーザー情報を取得する API を最適化するために LRU キャッシュが使用されます。それ以外の場合は、データベースからデータを取得した後にキャッシュを更新できます。

Erlang と Go にはパフォーマンスの違いがあります。 Erlang は同時実行性に優れていますが、Go はより高いスループットとより高速なネットワーク パフォーマンスを備えています。 Erlang は高い同時実行性を必要とするシステムに適しており、Go は高スループットと低遅延を必要とするシステムに適しています。

PHP 開発では、キャッシュ メカニズムにより、頻繁にアクセスされるデータがメモリまたはディスクに一時的に保存され、データベース アクセスの数が削減され、パフォーマンスが向上します。キャッシュの種類には主にメモリ、ファイル、データベース キャッシュが含まれます。キャッシュは、組み込み関数またはサードパーティのライブラリ (cache_get() や Memcache など) を使用して PHP に実装できます。一般的な実用的なアプリケーションには、データベース クエリ結果をキャッシュしてクエリ パフォーマンスを最適化したり、ページ出力をキャッシュしてレンダリングを高速化したりすることが含まれます。キャッシュ メカニズムにより、Web サイトの応答速度が効果的に向上し、ユーザー エクスペリエンスが向上し、サーバーの負荷が軽減されます。

Redis キャッシュを使用すると、PHP 配列ページングのパフォーマンスを大幅に最適化できます。これは、次の手順で実現できます。 Redis クライアントをインストールします。 Redisサーバーに接続します。キャッシュ データを作成し、データの各ページをキー「page:{page_number}」を持つ Redis ハッシュに保存します。キャッシュからデータを取得し、大規模な配列での高コストの操作を回避します。

まず、システム言語を簡体字中国語表示に設定して再起動する必要があります。もちろん、以前に表示言語を簡体字中国語に変更したことがある場合は、この手順をスキップできます。次に、レジストリ regedit.exe の操作を開始し、左側のナビゲーション バーまたは上部のアドレス バーで HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNlsLanguage に直接移動し、InstallLanguage キーの値と Default キーの値を 0804 に変更します (英語に変更する場合)。まずシステムの表示言語を en-us に設定し、システムを再起動してから、すべてを 0409 に変更します) この時点でシステムを再起動する必要があります。

はい、Navicat は Redis に接続できます。これにより、ユーザーはキーの管理、値の表示、コマンドの実行、アクティビティの監視、問題の診断が可能になります。 Redis に接続するには、Navicat で「Redis」接続タイプを選択し、サーバーの詳細を入力します。
