ホームページ  >  記事  >  バックエンド開発  >  Redis での最も一般的な面接の質問

Redis での最も一般的な面接の質問

小云云
小云云オリジナル
2018-03-22 13:31:5711113ブラウズ

Redis での最も一般的な面接の質問

PHP プログラマーの面接中に、Redis に関する面接の質問に遭遇する場合もあります。この記事では、皆さんのお役に立つことを願って、Redis で最も一般的な面接の質問を主に紹介します。

特別な推奨事項: 2020年のredis面接の質問(最新)

2. Reidの特徴

Redisは基本的にKey-Value型のメモリデータベースであり、memcachedとよく似ており、データベース全体がロードされます メモリ内で動作します、ストレージの非同期操作を通じてデータベース データをハードディスクに定期的にフラッシュします。 Redis は純粋なメモリ操作であるため、パフォーマンスが非常に優れており、1 秒あたり 100,000 を超える読み取りおよび書き込み操作を処理できます。これは既知の最速の Key-Value DB です。

Redisの優秀さはパフォーマンスだけではありません、またRedisの最大の魅力は、1MBのデータしか保存できないmemcachedとは異なり、1つの値の最大値が1GBまで保存できることです。 Redis を使用すると、List を使用して FIFO 二重リンク リストを作成したり、軽量で高性能なメッセージ キュー サービスを実装したり、Set を使用して高性能のタグ システムを作成したりするなど、多くの便利な機能を実現できます。 。さらに、Redis は保存された Key-Value の有効期限を設定できるため、memcached の拡張版としても使用できます。

Redis の主な欠点は、データベース容量が物理メモリによって制限され、大量のデータの高パフォーマンスな読み取りと書き込みには使用できないことです。そのため、Redis に適したシナリオは主に高パフォーマンスの操作と計算に限定されます。データ量が少なくなります。

3. Redis を使用する利点は何ですか?

(1) HashMap と同様にデータがメモリに保存されるため高速です。 HashMap の利点は、検索と操作の計算量が O(1) であることです。

(2) 豊富なデータ型をサポートし、文字列をサポートします。 、list、set、sorted set、hash

(3) トランザクションをサポートし、操作はすべてアトミックです。いわゆるアトミック性とは、データへのすべての変更が実行されるか、まったく実行されないことを意味します
(4) 豊富な機能:キャッシュ、メッセージング、プレスに使用されます。キーの有効期限を設定すると、有効期限が切れると自動的に削除されます

4. memcached と比較した Redis の利点は何ですか? (1)Memcachedのすべての値は単純な文字列であり、Redisは、その置換として、Memcached >>(1)Memcachedのすべての値が単純な文字列であることをサポートしますその代わりに、redis はより豊富なデータ型をサポートします

(2) redis は memcached よりもはるかに高速です (3) redis はデータを永続化できます

5. Memcache と Redis の違いは何ですか?


1). 保存方法 Memecache はすべてのデータをメモリに保存します。停電後はデータがメモリ サイズを超えることはありません。 Redis の一部はハードディスクに保存されるため、データの永続性が保証されます。

2) データサポートタイプ Memcache は比較的単純なデータタイプをサポートします。 Redis には複雑なデータ型があります。 3). 使用される基礎となるモデルが異なります。基礎となる実装方法とクライアントとの通信用のアプリケーション プロトコルが異なります。一般的なシステムがシステム関数を呼び出すと、移動やリクエストに一定の時間が無駄になるため、Redis は独自の VM メカニズムを直接構築しました。

6. Redis の一般的なパフォーマンスの問題と解決策:

1) マスターはメモリ スナップショットを書き込み、save コマンドは rdbSave 関数をスケジュールします。これにより、スナップショットが比較的大きい場合、メイン スレッドの作業がブロックされます。パフォーマンスへの影響が非常に大きいため、サービスが断続的に停止されるため、マスターがメモリ スナップショットを書き込まないことをお勧めします。

2) マスター AOF 永続化 AOF ファイルが書き換えられない場合、この永続化方法はパフォーマンスに最小限の影響を与えますが、AOF ファイルが大きすぎると、AOF ファイルの回復速度に影響します。マスター再起動。マスターでは、メモリ スナップショットや AOF ログ ファイルなどの永続化作業を行わないことが最善です。特に、データが重要な場合は、スレーブで AOF バックアップ データを有効にする必要があります。 1 秒に 1 回同期します。

3).マスターはBGREWRITEAOFを呼び出してAOFファイルを書き換えます。AOFは書き換え中に大量のCPUとメモリリソースを占有するため、過剰なサービス負荷が発生し、サービスが短期間停止されます。

4)Redisのマスタースレーブレプリケーションのパフォーマンスの問題、マスタースレーブレプリケーションの速度と接続の安定性のためには、スレーブとマスターが同じLAN内にあるのが最適です

7。 mySQL のデータ、

redis のみ 200,000 データの保存、redis 内のデータが確実にホットデータであることを確認する方法

関連知識:redisメモリデータセットのサイズが一定のサイズに増加すると、データ削除戦略(リサイクル戦略)が実装されます。 Redis は 6 つのデータ削除戦略を提供します:

  • volatile-lru: 削除する有効期限が設定されたデータセット (server.db[i].expires) から最も最近使用されていないデータを選択します

  • volatile-ttl。 : 有効期限が設定されているデータセット(server.db[i].expires)から期限切れにするデータを選択して削除します

  • volatile-random: 有効期限が設定されているデータセット(server.db[i].expires)を選択します。 db[i].expires)

  • allkeys-lru: データセット (server.db[i].dict) から最も最近使用されていないデータを選択して削除します

  • allkeys-random: 最も最近使用されていないデータを選択しますデータセット (server.db) [i].dict) からのデータ 削除するデータを選択してください

  • no-enviction (エビクション): データのエビクトは禁止されています

8。悪意のあるログイン保護コードを実装する言語、 1 時間に制限 各ユーザー ID は最大 5 回までしかログインできません。特定のログイン関数または関数については、空の関数を使用するだけでよく、詳細に記述する必要はありません。

リストで実装: リスト内の各要素は、最後の 5 回目のログイン時刻と現在の時刻の差が 1 時間以内である限り、ログインを禁止します。Python で書かれたコードは次のとおりです。以下:

#!/usr/bin/env python3
import redis  
import sys  
import time  
 
r = redis.StrictRedis(host=’127.0.0.1′, port=6379, db=0)  
try:       
    id = sys.argv[1]
except:      
    print(‘input argument error’)    
    sys.exit(0)  
if r.llen(id) >= 5 and time.time() – float(r.lindex(id, 4)) <= 3600:      
    print(“you are forbidden logining”)
else:       
    print(‘you are allowed to login’)    
    r.lpush(id, time.time())    
    # login_func()

9. なぜ Redis はすべてのデータをメモリに入れる必要があるのでしょうか? 最速の読み取りおよび書き込み速度を達成するために、Redis はすべてのデータをメモリに読み取り、データをディスクに書き込みます。非同期的に。つまり、redis は高速でデータの永続性が高いという特徴を持っています。データがメモリに配置されていない場合、ディスク I/O 速度は Redis のパフォーマンスに重大な影響を与えます。メモリがどんどん安くなっている現在、redis の人気はますます高まるでしょう。
使用される最大メモリが設定されている場合、データレコード数がメモリ制限に達すると、新しい値を挿入できなくなります。

10. Redis はシングルプロセスおよびシングルスレッドです

Redis はキューテクノロジーを使用して同時アクセスをシリアルアクセスに変換し、従来のデータベースシリアル制御のオーバーヘッドを排除します

11. の同時実行競合問題を解決する方法。 redis?

Redisはシングルプロセスシングルスレッドモードで、キューモードを使用して同時アクセスをシリアルアクセスに変換します。 Redis 自体にはロックの概念がありませんが、Jedis クライアントが同時に Redis にアクセスすると、接続のタイムアウト、データ変換エラー、クライアントによる接続の切断などの問題が発生する可能性があります。これらはすべてクライアント接続の混乱によって引き起こされます。この問題には 2 つの解決策があります: 1. クライアントの観点から見ると、各クライアントが通常かつ秩序ある方法で Redis と通信することを保証するために、接続がプールされ、同期された内部ロックがクライアントの読み取りと読み取りに使用されます。 Redis オペレーションの書き込み。

2. サーバーの観点から、setnx を使用してロックを実装します。

注: 最初のタイプでは、アプリケーションがリソースの同期を独自に処理する必要があります。使用できるメソッドは比較的一般的で、synchronized または lock を使用できます。2 番目のタイプでは、Redis の setnx コマンドを使用する必要があります。いくつかの問題に注意する必要があります。

12. Redis のことについて理解する CAS (check-and-set 操作で楽観的ロックを実装)?


他の多くのデータベースと同様に、Redis も NoSQL データベースとしてトランザクション メカニズムを提供します。 Redis では、MULTI/EXEC/DISCARD/WATCH の 4 つのコマンドがトランザクション実装の基礎となります。この概念は、リレーショナル データベース開発の経験がある開発者にとっては馴染みのないものではないと思いますが、Redis のトランザクションの実装機能を簡単にリストします。

1) コマンドは、トランザクションの実行中に逐次実行されます。 , Redis は他のクライアント要求に対してサービスを提供しないため、トランザクション内のすべてのコマンドがアトミックに実行されます。

2). リレーショナルデータベースのトランザクションと比較すると、Redisトランザクションではコマンドの実行に失敗しても、後続のコマンドが実行され続けます。 3) MULTI コマンドでトランザクションを開始できますが、これはリレーショナル データベース開発の経験がある人なら「BEGIN TRANSACTION」ステートメントとして理解できます。このステートメントの後に実行されるコマンドは、トランザクション内の操作とみなされます。最後に、EXEC/DISCARD コマンドを実行することで、トランザクション内のすべての操作をコミット/ロールバックできます。この二人

Redis コマンドは、リレーショナル データベースの COMMIT/ROLLBACK ステートメントと同等であると考えることができます。
4). トランザクションが開始される前に、クライアントとサーバー間の通信障害が発生し、ネットワークが切断された場合、その後実行されるすべてのステートメントはサーバーによって実行されません。ただし、クライアントが EXEC コマンドを実行した後にネットワーク中断イベントが発生した場合、トランザクション内のすべてのコマンドがサーバーによって実行されます。
5). Append-Only モードを使用する場合、Redis はシステム関数 write を呼び出すことで、トランザクション内のすべての書き込み操作をディスクに書き込みます。ただし、電源障害によるダウンタイムなど、書き込みプロセス中にシステム クラッシュが発生した場合、その時点ではデータの一部だけがディスクに書き込まれ、データの他の部分が失われる可能性があります。

Redis サーバーは再起動時に必要な一連の整合性チェックを実行し、同様の問題が見つかるとすぐに終了し、対応するエラー プロンプトを表示します。現時点では、Redis ツールキットで提供されている redis-check-aof ツールを最大限に活用する必要があります。このツールは、データの不整合エラーを特定し、書き込まれたデータの一部をロールバックするのに役立ちます。修復後、Redis サーバーを再度再起動できます。

13.WATCH コマンドと CAS ベースの楽観的ロック:

Redis トランザクションでは、WATCH コマンドを使用して CAS (チェックアンドセット) 機能を提供できます。トランザクションが実行される前に、WATCH コマンドを通じて複数のキーを監視すると仮定します。WATCH 後にいずれかのキーの値が変更された場合、EXEC コマンドによって実行されたトランザクションは放棄され、呼び出し元に通知するために Null マルチバルク応答が返されます。トランザクションの

実行に失敗しました。たとえば、キー値のアトミックなインクリメントを完了するための incr コマンドが Redis に提供されていないと再び仮定します。この関数を実装したい場合は、対応するコードを自分で記述するしかありません。疑似コードは次のとおりです。

val = GET mykey

val = val + 1
SET mykey $val
上記のコードは、複数のクライアントが存在する場合、単一の接続の場合にのみ実行結果が正しいことを保証できます。同時に このコードが同時に実行されると、マルチスレッド プログラムでよく発生するエラー シナリオ、つまり競合状態が発生します。たとえば、クライアント A と B の両方が、mykey の元の値を同時に読み取り、その値が 10 であるとします。その後、両方のクライアントが値に 1 を追加して、その値を Redis サーバーに設定し直します。結果は 11 であり、予想していた 12 ではありません。同様の問題を解決するには、WATCH コマンドの助けが必要です。次のコードを参照してください:
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
前のコードとは異なります新しいコードは、mykey の値を取得する前に、まず WATCH コマンドを通じてキーを監視し、次にトランザクション内で set コマンドを囲みます。これにより、各接続が実行される前に、現在のメソッドによって mykey の値が取得されたかどうかを効果的に確認できます。接続が他のクライアントによって変更されました 接続されているクライアントが変更された場合、現在の接続の EXEC コマンドは実行に失敗します。このようにして、呼び出し元は戻り値を判断して、val が正常にリセットされたかどうかを知ることができます。

14. Redis の永続化のいくつかの方法

1. スナップショット

デフォルトでは、Redis はデータ スナップショットをディスク上のバイナリ ファイルに保存します。ファイル名は dump.rdb です。たとえば、N 秒ごとにデータ セットに M を超える更新がある場合、データがディスクに書き込まれるか、コマンド SAVE または BGSAVE を手動で呼び出すことができます。

動作原理
. Redis フォーク
. 子プロセスは一時 RDB ファイルへのデータの書き込みを開始します。
. 子プロセスが RDB ファイルの書き込みを完了したら、古いファイルを新しいファイルに置き換えます。
. この方法により、Redis はコピーオンライト テクノロジを使用できるようになります。
2. AOF
スナップショット モードはあまり堅牢ではなく、システムが停止したり、Redis が誤って終了したりすると、Redis に書き込まれた最後のデータが失われます。一部のアプリケーションではこれは大きな問題にならないかもしれませんが、高い信頼性が必要なアプリケーションの場合、
Redis は適切な選択ではありません。
追加専用ファイルモードも別のオプションです。
設定ファイルで AOF モードをオンにすることができます
3. 仮想メモリ モード
キーが小さく、値が大きい場合、より多くのメモリを節約できるため、VM を使用する効果が高くなります。しばらくの間、大きなキーを大きな値に変換するいくつかの特別な方法を使用することを検討できます。たとえば、キーと値を組み合わせて新しい値を作成することを検討できます。
スワップにアクセスするために vm-max-threads パラメーターを設定できます。スレッドの数はマシンのコア数を超えてはなりません。0 に設定すると、スワップ ファイルに対するすべての操作がシリアル化されます。ただし、データの整合性は向上します。 .

自分でテストしてみたところ、仮想メモリを使用した場合のパフォーマンスも良好であることがわかりました。データの量が大きい場合は、分散データベースまたは他のデータベースを検討できます

15. Redis キャッシュの無効化戦略と主キーの無効化メカニズム

キャッシュ システムは無効なデータを定期的にクリーンアップする必要があるため、主キーの無効化と消去戦略
Redis では、有効期間を持つキーは揮発性と呼ばれます。キャッシュを作成するときは、特定のキーの有効期間を設定します。キーの有効期限が切れると (有効期間は 0)、削除される可能性があります。
1. 生存時間に影響を与える一部の操作
生存時間は、DEL コマンドを使用してキー全体を削除することで削除できます。または、元のデータは SET および GETSET コマンドで上書きする、つまり、に対応する値を変更することによって削除できます。キーと別の同一のキーを使用すると、キーと値が上書きされた後、現在のデータの生存時間が異なります。
例えば、キーに対して INCR コマンドを実行する、リストに対して LPUSH コマンドを実行する、またはハッシュ テーブルに対して HSET コマンドを実行する、これらの操作はキー自体の生存時間は変更しません。一方、RENAME を使用してキーの名前を変更した場合、名前を変更したキーの生存時間は名前を変更する前と同じになります。
RENAME コマンドのもう 1 つの可能性は、生存時間を持つキーの名前を生存時間を持つ another_key に変更しようとすることです。このとき、古い another_key (およびその生存時間) は削除され、古いキーの名前が変更されます。 . は another_key であるため、新しい another_key の生存時間は元のキーと同じになります。 PERSIST コマンドを使用すると、キーを削除せずにキーの有効期間を削除し、キーを再び永続キーにします。
2. 生存時間の更新方法
すでに生存時間が設定されているキーに対して EXPIRE コマンドを実行すると、新しく指定した生存時間が古い生存時間に置き換わります。有効期限の精度は 1ms 以内に制御されており、主キー障害の時間計算量は O(1) です。
EXPIRE コマンドと TTL コマンドを併用すると、キーの現在の生存時間を確認できます。設定が成功した場合は 1 を返し、キーが存在しない場合、またはキーに生存時間を設定できない場合は 0 を返します。
最大キャッシュ構成
redisでは、ユーザーは最大メモリサイズを設定できます
server.maxmemory
デフォルトは0で、最大キャッシュは指定されていません 新しいデータが追加されて最大メモリを超えると、redisはクラッシュします。必ず設定してください。 Redis メモリ データ セットのサイズが特定のサイズに増加すると、データ削除戦略が実装されます。
Redis は 6 つのデータ削除戦略を提供します:
. volatile-lru: 有効期限が設定されたデータセット (server.db[i].expires) から最も最近使用されていないデータを選択して削除します
. volatile-ttl: 有効期限が設定されたデータセット(server.db[i].expires)から削除対象の有効期限が近づいているデータを選択します
. volatile-random: 有効期限を設定してデータセット(server.db[i].expires)から削除するデータをランダムに選択します
. allkeys-lru: 削除するデータセット (server.db[i].dict) から最も最近使用されていないデータを選択します
. allkeys-random: データセット(server.db[i].dict)から削除するデータを任意に選択します
. no-enviction (エビクション): データの追放は禁止されています
ここで、Volatile と allkeys は、有効期限付きのデータ セットからデータを削除するか、またはすべてのデータ セットからデータを削除するかを指定します。ランダムは 3 つの異なる除去戦略と、決してリサイクルされない非羨望戦略です。
利用ポリシールール:
1. データがべき乗則分布を示す場合、つまり、一部のデータアクセス頻度が高く、一部のデータアクセス頻度が低い場合は、allkeys-lru を使用します
2. データが均等な分布を示す場合、つまり、すべてのデータ アクセス頻度がすべて同じである場合は、allkeys-random を使用します。
3 つのデータ除去戦略:
ttl と random は理解しやすく、実装も簡単です。主な理由は、Lru が少なくとも最近は削除戦略を使用しており、有効期限に従ってキーをソートし、最初の無効なキーを削除するためです

16。 Redis は、メモリ内のすべてのデータに最適なシナリオです。Redis は永続化機能も提供しますが、実際にはディスクベースの機能であり、従来の意味での永続化とはまったく異なります。 Redis は Memcached の拡張バージョンに近いので、いつ Memcached を使用するか、いつ Redis を使用するか?

Redis と Memcached の違いを単純に比較すると、ほとんどの人は次のような意見を得るでしょう: 1. Redis はサポートするだけではありません。シンプルな k/v タイプのデータ。リスト、セット、zset、ハッシュ、その他のデータ構造のストレージも提供します。

2. Redisはデータバックアップ、つまりマスタースレーブモードでのデータバックアップをサポートしています。
3. Redis はデータの永続化をサポートしており、データをディスク上のメモリに保持し、再起動時に再度ロードして使用できます。
(1)、セッションキャッシュ

Redis を使用するために最も一般的に使用されるシナリオの 1 つはセッション キャッシュです。 Redis を使用して他のストレージ (Memcached など) 上でセッションをキャッシュする利点は、Redis が永続性を提供することです。整合性を厳密に要求しないキャッシュを維持する場合、ユーザーのショッピング カート情報がすべて失われると、ほとんどの人は不満を抱くでしょう。さて、

それでもこのままでしょうか。

幸いなことに、Redis は長年にわたって改良されてきたため、Redis を適切に使用してセッション ドキュメントをキャッシュする方法を見つけるのは簡単です。有名な商用プラットフォーム Magento でも Redis プラグインが提供されています。

(2)、フル ページ キャッシュ (FPC)
基本的なセッション トークンに加えて、Redis は非常にシンプルな FPC プラットフォームも提供します。一貫性の問題に戻りますが、Redis インスタンスが再起動されても、ディスクの永続性により、ユーザーはページの読み込み速度が低下することはありません。これは、PHP ローカル FPC と同様に、大きな改善です。
再び Magento を例に挙げると、Magento は Redis をフルページ キャッシュ バックエンドとして使用するためのプラグインを提供します。
さらに、WordPress ユーザーにとって、Pantheon には非常に優れたプラグイン wp-redis があり、閲覧したページをできるだけ早く読み込むのに役立ちます。
(3) キュー
メモリストレージエンジンの分野における Redis の大きな利点の 1 つは、リスト操作とセット操作を提供し、これにより Redis を優れたメッセージキュープラットフォームとして使用できることです。 Redis によってキューとして使用される操作は、ローカル プログラミング言語 (Python など) のリストのプッシュ/ポップ操作に似ています。
Google で「Redis キュー」をすぐに検索すると、すぐに多数のオープンソース プロジェクトが見つかります。これらのプロジェクトの目的は、Redis を使用して、さまざまなキューのニーズを満たす非常に優れたバックエンド ツールを作成することです。たとえば、Celery には Redis をブローカーとして使用するバックエンドがあります。ここから確認できます。
(4)、ランキング/カウンター
Redis はメモリ内の数値を増減する操作を非常にうまく実装しています。 Set と Sorted Set を使用すると、これらの操作を非常に簡単に実行できます。Redis はこれら 2 つのデータ構造を提供するだけです。したがって、ソートされたセットから上位 10 人のユーザーを取得したいとします。これを「user_scores」と呼びます。次のように実行するだけです。 もちろん、これはユーザーに基づいていることを前提としています。スコアは昇順でソートされています。注文。ユーザーとユーザーのスコアを返したい場合は、次のように実行する必要があります:

ZRANGE user_scores 0 10 WITHSCORES


Agora Games は良い例で、Ruby で実装されており、そのランキングは Redis を使用してデータを保存します。ここで見ることができます。
(5)、パブリッシュ/サブスクライブ
最後に (もちろん重要ですが) Redis のパブリッシュ/サブスクライブ機能です。パブリッシュ/サブスクライブには実際に多くの使用例があります。人々がこれをソーシャル ネットワーク接続で使用したり、パブリッシュ/サブスクライブ ベースのスクリプトのトリガーとして使用したり、Redis のパブリッシュ/サブスクライブ機能を使用してチャット システムを構築したりしているのを見てきました。 (いいえ、これは真実です。検証できます)。
Redis が提供するすべての機能の中で、これはユーザーにこれほど多機能を提供しているにもかかわらず、最も人々に好まれていない機能だと私は感じています。

関連する推奨事項:


phpでのredisの詳細な説明

phpでのredisの応用例

Redisの一般的な使用シナリオの共有

以上がRedis での最も一般的な面接の質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。