こんにちは!Redisの世界へようこそ。
世界最高峰のアーキテクトなんて紹介されちゃうと少し身構えちゃうかもしれないけれど、今日はおいしいコーヒーでも飲みながら、リラックスして聞いてほしいな。
初心者や初学者のうちは、「Redisってメモリ上で動くから超高速なんでしょ?」って覚えるよね。大正解!その通りなんだ。
でも、システムを運用するうえで避けて通れないのが「データの永続化(ディスクに保存すること)」。
「メモリにあるデータをハードディスクに書き出すだけじゃん?」って軽く見ていると、ある日突然、本番環境で「なんだか最近、アプリのレスポンスがすごく遅いぞ……?」という悪夢を見る羽目になるんだ。
今回は、この永続化プロセスが裏側でどうやって動いていて、なぜディスクのI/O(読み書き)負荷がRedisのパフォーマンスに牙を剥くのか、そしてどうやってそれを華麗にかわすのかを、日常の例え話を交えながら分かりやすく紐解いていこう。ここをクリアすれば、君もRedisの裏側をグッと深く理解できるマスターになれるよ!
—
1. カフェのカウンターに例えるRedisの基本
まず、Redisが普段どうやって動いているかをイメージしてみよう。
君がすごく人気のカフェの店長だと想像してね。
お客さん(=クライアントアプリ)が次々とやってきて、「コーヒー1つ!」「サンドイッチ!」「お会計!」って注文を投げてくる。
Redisは、カウンターにいるめちゃくちゃ手際の良い一人の店員さんだと思ってほしい。この店員さんは頭の回転が速くて、メモ帳(=メモリ)だけでものすごいスピードでお客さんの注文をさばいていく。だからカフェ全体が爆速で回るんだ。
これが、Redisが「シングルスレッド(1人で作戦をこなす)」でメモリ上で動く本質だよ。
2. 「忘れないためのメモ」:RDBとAOFの正体
さて、この店員さん、あまりに頭の中(メモリ)だけで仕事を覚えているから、もしお店が突然停電したり、夜中に泥棒が入ったりしたら、今日稼いだ売上も常連さんの注文も、ぜーんぶ忘れちゃうよね。それは困る。
だから、データを消えないようにどこかに残しておく必要がある。これが「永続化」だ。
Redisには主に2つの方法がある。
1. RDB(Redis Database)方式
- 例え: お店の営業時間の一番盛り上がっている時に、「ちょっとごめんね!」と言って、今の店内の状態をデジカメでパシャリと1枚の写真(スナップショット)に撮る方法。
2. AOF(Append Only File)方式
- 例え: お客さんが注文するたびに、店員さんが「コーヒー1つ追加」「お会計1000円」と、ノートに一部始終をリアルタイムでメモ(追記)していく方法。
どちらの方法もデータが守られて安心なんだけど、ここに「ディスクI/O(ハードディスクへの書き込み)」という大きな罠が潜んでいるんだ。
—
3. ディスクI/O負荷という「見えない敵」の正体
さあ、ここからが本題だ。
「写真を撮る(RDB)」にしても、「ノートに書き留める(AOF)」にしても、最終的にはそのデータはコンピュータの中にあるハードディスク(SSDやHDDなど)に保存される。
ここで問題が起きる。「メモリへの書き込み」と「ディスクへの書き込み」では、スピードが天と地ほど違うんだ。
- メモリのスピード:新幹線のぞみ号(超高速)
- ディスクのスピード:歩いてお使いに行く(めちゃくちゃ遅い)
RDBで起きる悲劇:「コピーのコピー」の裏側
RDBで写真を撮る時、店員さんはどうすると思う?
「今の手元のメモ帳をそのまま写すぞー」って言って、裏でそっくりそのままコピーを作るんだ(専門用語で`fork`って言うよ)。
この時、もしディスクの書き込みが遅かったり、ハードディスクがいっぱいいっぱいだったりするとどうなる?
店員さんは写真をディスクに書き込んでいる間、「ディスクへの書き込みが終わるのを待たなきゃいけない時間(I/O待ち)」が発生する。
「ちょっと待ってね、今ディスクにデータを保存しているから、次の注文を受けられないんだ……」
――そう、これが「メインスレッドのブロック(一時停止)」だ。爆速だったカフェの列が、急にピタッと止まってしまう。お客さんはイライラ、「おっそいなぁ!」ってクレームの嵐さ。
AOFで起きる悲劇:「常にノートに書き続ける」代償
じゃあ、AOFはどうだろう? 注文ごとにノートに書いていくから安心……と思いきや、これまた大変。
設定で「1秒に1回は確実にディスクに書き込んでね(`fsync`)」なんて厳しく指定していると、1秒に1回、店員さんは手を止めて「よいしょ、よいしょ」と重いディスクにノートのデータを押し付けに行く。
この「重いディスクへの書き込み(I/O)」が頻発すると、ディスクの入り口が大渋滞を起こしてしまうんだ。
—
4. 現場で使える!ディスクI/O負荷を防ぐ対策と知見
「じゃあ、永続化なんて怖くて使えないよ!」って思った?
安心して。先輩エンジニアが現場で使っている、このディスクI/O負荷を華麗にかわすための実践的なアプローチを授けよう。ここをマスターすればバッチリだよ!
対策①:永続化の役割分担を見直す(そもそも本当にRedisでディスク保存すべき?)
もしあなたのシステムが、「Redisはあくまでキャッシュ(一時的な置き場所で、消えてもデータベースから再取得できる)」として使っているなら、思い切ってRDBもAOFもオフにするという選択肢がある。
ディスクへの書き込みを一切やめれば、ディスクI/O負荷はゼロになり、Redisは本来のモンスター級のスピードを取り戻す。永続化は、真に失いたくないデータ(セッション情報やカウンターなど)を扱うときだけに絞るのが、プロの設計だ。
対策②:RDBの保存タイミング(スナップショット)を調整する
RDBを使う場合、あまりに高頻度で写真を撮るとディスクが悲鳴を上げる。
例えば、`redis.conf`の設定ファイルで以下のように「何秒以内に何回データが変わったら写真を撮る」という条件を指定できる。
例:900秒(15分)以内に1回以上データが変わったら保存
save 900 1
例:300秒(5分)以内に10回以上データが変わったら保存
save 300 10
例:60秒以内に10000回以上データが変わったら保存
save 60 10000
- ここが知見: アクセスが猛烈に多い時間帯に、低すぎる閾値(例:1秒ごとに保存など)を設定すると、ディスクI/Oが常にフルの状態になり、アプリ全体のレイテンシ(遅延)が跳ね上がる。トラフィックの特性に合わせて、このスナップショットの頻度をチューニングするのが腕の見せ所だよ。
対策③:ハードウェア(ストレージ)の選定に妥協しない
当たり前だけど、すごく大事なこと。
古いHDD(ハードディスクドライブ)や、性能の低いクラウドのストレージを使っていると、ちょっとしたAOFの書き込みでもすぐにボトルネック(渋滞)になる。
Redisを本番運用するなら、NVMe対応の高速なSSDを選ぶこと。これが一番手っ取り早くて確実な解決策だったりするんだ。
—
まとめ
いかがだった?
Redisの永続化とディスクI/Oの関係について、イメージがつかめたかな?
- メモリは爆速、ディスクはスローペース。
- 永続化(RDBやAOF)を行うと、そのスピード差によってディスクI/Oの渋滞が起きる。
- 渋滞が起きると、Redisのメインスレッドが待たされて、クライアントへの応答が遅くなる(ブロックされる)。
- だからこそ、用途に合わせて永続化の必要性を考え、適切な保存頻度や高速なストレージを選ぶことがエンジニアの腕の見せ所。
この仕組みさえ頭に入っていれば、将来「なんだかRedisが重いぞ」というトラブルに直面した時も、「おっ、これはディスクの書き込みが渋滞しているな?設定やストレージを疑ってみよう」と冷静に原因を突き止められるはずだ。
君なら絶対に大丈夫。これからも一緒に、最高にイケてるシステムを作っていこうね!
コメント