Redis 基礎: https://blog.yexca.net/ja/archives/157/
Redis 分散キャッシュ: 本文
はじめに
結局この2つの記事、同時に書いたのに1年も経ってから投稿してるんだよね
実は当時書きたいものが3つあったんだけど、思い出すたびに何を書こうとしてたか忘れちゃって、気づいたら1年近く経ってたっていう。。。
問題点
スタンドアロン(単一インスタンス)の Redis には以下の課題がある。
- データの紛失:Redis データの永続化を実現する必要がある
- 並行処理能力の問題:主従(マスター・スレーブ)クラスタを構築し、読み書き分離を実現する必要がある
- ストレージ容量の問題:シャーディング(分片)クラスタを構築し、スロット・メカニズムを利用して動的スケーリングを実現する必要がある
- 障害復旧の問題:Redis センチネル(Sentinel)を利用して、ヘルスチェックと自動復旧を実現する必要がある
Redis の永続化
Redis の永続化には RDB と AOF の2つの方法がある。
RDB 永続化
RDB の正式名称は Redis Database Backup file(Redis データバックアップファイル)。Redis データスナップショットとも呼ばれる。簡単に言うと、メモリ内のすべてのデータをディスクに記録すること。Redis インスタンスが故障して再起動したとき、ディスクからスナップショットファイルを読み込んでデータを復元する。スナップショットファイルは RDB ファイルと呼ばれ、デフォルトでは実行ディレクトリに保存される。
RDB は以下の4つのケースで実行される:
saveコマンド:即座に実行される。メインプロセスが RDB を実行するため、他のすべてのコマンドがブロックされる。データ移行時にのみ使われる可能性がある。bgsaveコマンド:非同期で実行される。独立したプロセスを開始して RDB を完了させるため、メインプロセスは影響を受けずにユーザーのリクエストを処理し続けられる。- Redis 停止時:停止時に
saveコマンドが1回実行される。 - RDB 発動条件に達したとき:設定ファイルで以下のように設定する。
| |
その他の設定
| |
RDB の原理
bgsave が始まると、メインプロセスが fork して子プロセスを作成する。子プロセスはメインプロセスのメモリデータを共有する。fork 完了後、メモリデータを読み取って RDB ファイルに書き込む。
fork は copy-on-write 技術を採用している:
- メインプロセスが読み取り操作を行うときは、共有メモリにアクセスする。
- メインプロセスが書き込み操作を行うときは、データのコピーを作成してから書き込みを行う。

RDB の欠点:
- 実行間隔が長く、2回の RDB の間に書き込まれたデータが失われるリスクがある。
- 子プロセスの
fork、圧縮、RDB ファイルの書き出しに時間がかかる。
AOF 永続化
AOF の正式名称は Append Only File(追加専用ファイル)。Redis が処理するすべての書き込みコマンドを記録するファイルで、コマンドログファイルのようなもの。
AOF はデフォルトでオフになっているので、設定ファイルを変更して有効にする。
| |
記録の頻度も redis.conf で設定できる。
| |
設定項目の比較:
| 設定項目 | ディスク書き込みのタイミング | メリット | デメリット |
|---|---|---|---|
| always | 同期書き込み | 信頼性が高く、データがほぼ失われない | パフォーマンスへの影響が大きい |
| everysec | 毎秒書き込み | パフォーマンスはそこそこ | 最大1秒分のデータが失われる可能性がある |
| no | OSが制御 | パフォーマンスが最高 | 信頼性が低く、大量のデータが失われる可能性がある |
ファイルの書き換え(Rewrite)
コマンドを記録するため、AOF ファイルは RDB よりかなり大きくなる。また、同じキーに対する複数の書き込みもすべて記録されるが、実際には最後の書き込みだけが意味を持つ。bgrewriteaof コマンドを実行することで、AOF ファイルを書き換え、最小限のコマンドで同じ状態を再現できるようになる。
例えば、元のコマンドが:
| |
書き換え後は:
| |
Redis は閾値に達したときにも自動的に AOF を書き換える。設定ファイルで指定する:
| |
RDB と AOF の比較
RDB と AOF にはそれぞれメリット・デメリットがある。データの安全性を重視する場合、実際の開発では両方を組み合わせて使うことが多い。
| RDB | AOF | |
|---|---|---|
| 永続化方式 | 定期的にメモリ全体のスナップショットを作成 | 実行されたすべてのコマンドを記録 |
| データの完全性 | 不完全。バックアップの合間にデータが失われる | 比較的完全。書き込み戦略に依存する |
| ファイルサイズ | 圧縮されるため、ファイルサイズは小さい | コマンドを記録するため、サイズは非常に大きくなる |
| 復旧速度 | 非常に速い | 遅い |
| データ復旧の優先順位 | 低い。データの完全性が AOF に劣るため | 高い。データの完全性がより高いため |
| システムリソース占有 | 高い。大量の CPU とメモリを消費 | 低い。主にディスク I/O リソース ただし AOF 書き換え時は大量の CPU とメモリを消費 |
| 使用シーン | 数分間のデータ紛失が許容でき、高速な起動を求める場合 | データの安全性を高く求められる一般的なケース |
Redis 主従アーキテクチャ
単一ノードの Redis の並行処理能力には限界がある。さらに向上させるには、主従(マスター・スレーブ)クラスタを構築して読み書き分離を実現する必要がある。

クラスタ構築
CentOS7 ベースでの手順。
上の図を参考に、合計3つのノードを同一マシン内に配置する。ポートは 7001(master)、7002、7003 とする。
まずディレクトリを作成。
| |
設定を変更している場合は、デフォルトの RDB モードに戻しておく。
| |
設定ファイルを各インスタンスのディレクトリにコピー。
| |
各インスタンスのポートと作業ディレクトリ(ポートの修正、rdb ファイルの保存場所の修正)を変更。
| |
IP を修正。すべてのディレクトリを修正すること (ip_address を実際のIPに置換)。
| |
起動。
| |
停止。
| |