大手IT面接Redis頻出15問:データ構造・永続化・クラスタリングを完全網羅
データ構造、永続化、クラスタリング、キャッシュ問題などRedisの高頻出面接15問を網羅。各問題に出題ポイントと回答方向付きで、Redis面接を全面的に準備できる。
背景紹介
Redisについては本当に苦い経験がある。以前スタートアップでプロジェクトをしていた時、キャッシュ方案をすべて自分で模索し、何度も本番障害を起こした——キャッシュ雪崩の際はサービスが30分間利用不能になった。その後、大手企業への転職面接に向けて、Redisをデータ構造からクラスタ方案まで2週間かけて整理し、最もよく出る15問をまとめた。正直、Redis面接はパターン性が高く、しっかり準備すれば基本的に答えられる。
一、データ構造(4問)
1. Redisの5つの基本データ型とその内部実装?
出題ポイント:データ構造の内部原理
Stringの内部はSDS(Simple Dynamic String)で、C文字列に比べてlenとfreeフィールドが追加され、O(1)で長さを取得、バイナリセーフ、動的拡張をサポート。Listの内部は3.2より前はziplist+linkedlist、その後quicklist(ziplist+双方向リスト)に統一。Hashの内部はziplistまたはhashtableで、要素が少ない時はziplistでメモリを節約。Setの内部はintsetまたはhashtableで、すべて整数で数が少ない時はintset。ZSetの内部はziplistまたはskiplist+hashtable。面接官が最も掘り下げるのは:いつziplistから他の構造に変換されるか?答えは要素数または個別要素サイズが閾値を超えた時。
2. スキップリストとは?なぜRedisは赤黒木ではなくスキップリストを使うのか?
出題ポイント:ソート済みセットの内部実装
スキップリストは多層リスト構造で、ランダムなレベル数によりO(logN)の検索、挿入、削除を実現。Redisが赤黒木ではなくスキップリストを選んだ理由:実装がシンプルでコードの可読性が良い;範囲クエリがより便利で、リスト構造が順次走査を自然にサポート;並行シナリオで変更が容易(Redisはシングルスレッドだが)。スキップリストの各ノードは1-32層をランダムに生成し、層が高いほど確率は低い。面接でスキップリストの検索過程を図示したら、面接官から「理解が非常に明確だ」と言われた。
3. 圧縮リスト(ziplist)とは?
出題ポイント:メモリ最適化メカニズム
ziplistは連続メモリに格納されるリスト構造で、メモリ節約のために設計された。各entryはprevlen(前のノードの長さ、逆方向走査用)とencoding(エンコード方式)を含む。利点はメモリがコンパクトでキャッシュフレンドリー;欠点はカスケード更新問題——中間のノードの長さが変化すると、後続のすべてのノードのprevlenフィールドの拡張が必要になる可能性がある。Redis 7.0ではlistpackがziplistに代わり、カスケード更新問題を解決した。この詳細は面接官がよく聞く。
4. Redis Streamとは?
出題ポイント:新データ構造の理解
StreamはRedis 5.0で導入されたデータ型で、Kafkaのメッセージキュー設計に似ている。コンシューマグループ、メッセージ確認、永続化をサポートし、Pub/Subより信頼性が高い。核心概念:メッセージID(タイムスタンプ+シーケンス番号)、Consumer Group、Pending Entries List(PEL)。軽量メッセージキューのシナリオに適しており、KafkaやRabbitMQを導入する必要がない。注意点:Streamのメッセージ蓄積はメモリに影響するため、MAXLENで制限を設定する必要がある。
二、永続化(3問)
5. RDBとAOFの違い?
出題ポイント:永続化ソリューションの比較
RDBはバイナリスナップショットファイルで、forkした子プロセスで生成、リカバリ速度は速いが、最後のスナップショット以降のデータが失われる可能性がある。AOFは追記書き込みの操作ログで、デフォルトで毎秒fsync、データ安全性は高いが、ファイルサイズが大きくリカバリが遅い。RDBはコールドバックアップに適し、AOFはホットバックアップに適する。面接官がよく聞く:RDBとAOFを同時に有効にした場合、Redis再起動時にどちらを読み込むか?答えはAOFで、AOFの方がデータが完全だから。
6. ハイブリッド永続化とは?
出題ポイント:永続化最適化ソリューション
Redis 4.0で導入:AOFリライト時にRDB形式のデータをAOFファイルの先頭に書き込み、その後の増分データはAOF形式。これによりリカバリ速度(RDB部分の高速読み込み)とデータ完全性(AOF部分の増分記録)の両方を保証。aof-use-rdb-preamble yesで有効化。追問:AOFリライトの過程は?メインプロセスが子プロセスをfork→子プロセスがリライト→メインプロセスは同時に新コマンドをAOFリライトバッファに書き込み→子プロセス完了後、メインプロセスがバッファデータを新AOFファイルに追加→旧ファイルを置換。
7. 本番環境で永続化ソリューションをどう選ぶ?
出題ポイント:実運用経験
純キャッシュシナリオは永続化を無効にして最高性能を得る;データ安全性が必要なシナリオはハイブリッド永続化を推奨;データ損失に極めて敏感な場合はAOF+毎秒fsyncを使用。主要設定の推奨:RDBのsave戦略はビジネスに応じて調整;AOFのfsync戦略はeverysecを選択(性能と安全性のバランス);ハイブリッド永続化を有効化;RDBファイルをリモートストレージに定期バックアップ。以前、本番環境でAOFファイルが大きすぎて再起動リカバリが遅かったが、ハイブリッド永続化を有効にしてリカバリ時間を30分から2分に削減した。
三、クラスタ(3問)
8. Redisマスタスレーブレプリケーションの原理?
出題ポイント:高可用性インフラ
フルレプリケーション:スレーブが初めて接続するか長時間切断された場合、マスタがRDBを生成してスレーブに送信、送信中の新コマンドはreplication bufferに書き込み、RDB送信後にbuffer内のコマンドを送信。部分レプリケーション:スレーブが短時間切断された場合、マスタはrepl_backlogリングバッファを維持し、スレーブがoffsetを持って増分データを要求。主要パラメータ:repl-backlog-sizeはデフォルト1MB、256MB以上に増やすことを推奨し、頻繁なフルレプリケーションを回避。追問:マスタスレーブ遅延の対応方法は?読み書き分離時にスレーブが古いデータを読む可能性があるが、重要なビジネスはマスタから強制読み取り可能。
9. センチネルモードの原理?
出題ポイント:自動フェイルオーバー
センチネルクラスタはRedisマスタスレーブノードを監視し、ハートビートチェックでマスタのダウンを判断。主観的ダウン:単一センチネルがマスタを利用不可と判断;客観的ダウン:過半数のセンチネルがマスタを利用不可と判断。フェイルオーバー過程:リーダーセンチネルを選出→新マスタを選択(優先度>レプリケーションオフセット>最小runid)→スレーブに新マスタからのレプリケーションを通知→クライアントに新マスタアドレスを通知。面接官が最も聞く:センチネル同士はどうやって発見するか?マスタのpub/subチャンネル__sentinel__:helloで互相発見。
10. Redis Clusterシャーディングの原理?
出題ポイント:分散アーキテクチャ
Redis Clusterには16384個のハッシュスロットがあり、各マスタノードが一部を担当。キーのスロットはCRC16(key) % 16384で計算。キーが現在のノードにない場合、MOVEDリダイレクトが返される。クラスタは高可用性のため最低6ノード(3マスタ+3スレーブ)が必要。よくある問題:クラスタはマルチキー操作をサポートしない(同じスロットにある場合はhash tagで解決可能);スケールイン/アウトには手動でスロットを移行する必要がある。追問:なぜ16384スロットなのか?ノード間のハートビートパケットにスロット情報を含める必要があり、16384スロットなら2KBで表現できるが、スロット数が多いとネットワークオーバーヘッドが増加する。
四、応用(3問)
11. キャッシュ貫通、キャッシュアタック、キャッシュ雪崩とは?解決方法は?
出題ポイント:キャッシュのよくある問題
貫通:存在しないデータをクエリし、キャッシュにもデータベースにもなく、リクエストがデータベースに直行。解決策:ブルームフィルタ、空値のキャッシュ。アタック:ホットキーの期限切れ瞬間に大量のリクエストがデータベースに到達。解決策:ミューテックスロック、ホットキーの期限切れなし。雪崩:大量のキーが同時に期限切れまたはRedisがダウンし、リクエストがすべてデータベースに到達。解決策:期限時間にランダム値を追加、Redisクラスタの高可用性、レート制限とグレードダウン。以前遭遇した本番障害は雪崩——大量のキーが同時に期限切れになり、期限時間にランダムオフセットを追加して解決した。
12. Redis分散ロックの実装方法?
出題ポイント:分散ロックソリューション
基本アプローチ:SET key value NX EX seconds、NXで相互排除を保証、EXでデッドロック防止の有効期限を設定。解放時はLuaスクリプトで原子性を保証(valueが自分の設定したものか確認してから削除)。Redlockアルゴリズム:複数の独立したRedisインスタンスで同時にロックを取得し、過半数で成功ならロック取得。本番推奨:Redissonフレームワークを使用、ウォッチドッグメカニズムで自動延長をカプセル化し、ロック期限切れでもビジネスが未完了の問題を解決。追問:Redlockは常に安全か?Martin Kleppmannが記事で疑問を呈し、クロックジャンプ等のシナリオで安全ではないと主張。この論争は理解していれば十分。
13. Redisでメッセージキューを実装する方法?
出題ポイント:メッセージキューソリューション
3つのアプローチ:List+LPUSH/BRPOPでシンプルなキューを実現、ブロック待機をサポートするがコンシューマグループは不可;Pub/Subは複数コンシューマをサポートするが永続化なし、メッセージ損失はリカバリ不可;Streamはコンシューマグループ、メッセージ確認、永続化をサポートし、Redis 5.0+の推奨方案。選択のアドバイス:シンプルなシナリオはList、パブリッシュ/サブスクライブが必要な場合はPub/Sub、信頼性の高いメッセージが必要な場合はStream。ただしRedisのメッセージキューは軽量シナリオにのみ適しており、大規模ならKafkaやRabbitMQを使用すべき。
五、その他(2問)
14. メモリ退去戦略にはどのようなものがある?
出題ポイント:メモリ管理メカニズム
8つの戦略:noeviction(デフォルト、退去せずエラーを返す);allkeys-lru(全キーから最も最近使用されていないものを退去);volatile-lru(期限付きキーからLRUで退去);allkeys-lfu(全キーから使用頻度が最も低いものを退去、Redis 4.0+);volatile-lfu(期限付きキーからLFUで退去);allkeys-random(ランダム退去);volatile-random(期限付きキーからランダム退去);volatile-ttl(残り時間が最も短いものを退去)。本番推奨:allkeys-lruまたはallkeys-lfu。LFUはLRUより優れている。アクセス頻度を考慮するため、最近のアクセス時間だけではない。
15. 期限削除メカニズムとは?
出題ポイント:キーの期限処理
Redisは遅延削除+定期削除の二重戦略を採用。遅延削除:キーにアクセスする時に期限切れかチェックし、期限切れなら削除。定期削除:100msごとに期限設定されたキーをランダムにサンプリングしてチェックし、期限切れなら削除、期限切れキーが25%を超える場合はチェックを継続。この組み合わせはCPUとメモリのバランスを取る——遅延削除のみでは長期間アクセスされない期限切れキーがメモリを無駄にする;定期削除のみではフルスキャンがCPUを過度に消費する。追問:大量のキーが同時に期限切れになったらどうなる?定期削除が複数ラウンド継続実行され、通常リクエストの応答時間に影響する可能性がある。
心得とアドバイス
Redis面接準備のポイント:データ構造は内部実装を理解し、「5つの型」の表面的なレベルにとどまらないこと;永続化とクラスタ方案は実際の運用経験と結びつけて回答し、できれば自分が踏んだ罠を話すこと;キャッシュ問題(貫通/アタック/雪崩)は必須問題で、解決策を即座に言えるようにすること。また、Redis 7.0の新機能(FunctionによるLuaスクリプトの代替、listpackによるziplistの代替、マルチAOFファイル)も注目に値し、技術の最先端を意識していることを示せる。
FAQ
Q:Redis面接にソースコードの理解は必要?
ソースコードを深く読む必要はないが、主要なデータ構造の実装(SDS、スキップリスト、ziplistなど)を理解していると大きくプラスになる。
Q:なぜシングルスレッドのRedisがこれほど速いのか?
純インメモリ操作、IO多重化、コンテキストスイッチとロック競合の回避。注意:Redis 6.0ではネットワークIOのマルチスレッド化が導入されたが、コマンド実行は依然としてシングルスレッド。
Q:本番環境のRedisのモニタリング方法は?
重点項目:メモリ使用率、ヒット率、接続数、スロークエリ、マスタスレーブ遅延。Redis Exporter+Prometheus+Grafanaでモニタリングを構築可能。