Redis Sentinelとは?システム安定性を支える重要機能を解説
Redis Sentinelが解決する3つの課題
Redis Sentinelは、Redisクラスター環境における高可用性(HA)を実現するための監視・制御システムです。主に以下の3つの重要な課題を解決します:
- 自動フェイルオーバーの実現
- マスターノードの障害を即時に検知
- スレーブノードから最適な新マスターを自動選出
- クライアントアプリケーションの接続先を自動切り替え
- フェイルオーバー完了までの時間を最小化(通常数秒〜数十秒)
- 継続的な監視とアラート
- 各Redisインスタンスの死活監視
- レプリケーション状態の監視
- ネットワーク分断の検知
- 異常検知時の通知機能
- クラスター構成の自動管理
- マスター/スレーブ関係の動的管理
- 設定変更の自動同期
- クラスタートポロジーの維持と最適化
- 新規ノードの自動検出と統合
従来のRedis構成との比較でわかるメリット
従来のRedis構成と比較して、Sentinelを導入することで以下のような明確なメリットが得られます:
- システム可用性の大幅な向上
| 評価項目 | 従来の構成 | Sentinel構成 |
|---|---|---|
| 障害検知 | 手動または外部監視ツール | リアルタイム自動検知 |
| フェイルオーバー | 手動切り替え必要 | 完全自動化 |
| ダウンタイム | 検知〜復旧まで長時間 | 数秒〜数十秒に短縮 |
| 24時間運用 | 運用チームの常時待機が必要 | 自動化による省人化 |
- 運用管理の効率化
- 監視作業の自動化による運用負荷の軽減
- 障害対応の標準化と自動化
- 構成変更作業の簡素化
- 運用ドキュメントの簡略化
- システムの信頼性向上
- 単一障害点の排除
- 分散アーキテクチャによる耐障害性の向上
- データ整合性の自動検証
- 障害復旧時間の予測可能性
- スケーラビリティの確保
- 読み取りスケールアウトの容易な実現
- ノードの動的追加・削除のサポート
- 地理分散構成への対応
- 段階的な性能拡張の実現
Sentinelノードは以下のような分散構成を取ることで、監視システム自体の信頼性も確保しています:
+----------------+
| Sentinel Node 1|
+----------------+
|
+----------+ | +----------+
| Redis |----+----+ Redis |
| Master | | | Slave |
+----------+ | +----------+
|
+----------------+
| Sentinel Node 2|
+----------------+
このように、Redis Sentinelは単なる監視ツールではなく、Redisクラスターの自律的な運用を実現する統合管理システムとして機能します。特に重要な業務システムやサービスレベルアグリーメント(SLA)の厳しい環境において、その価値を最大限に発揮します。
Redis Sentinelのアーキテクチャ詳解
マスター・スレーブ構成の仕組み
Redis Sentinelにおけるマスター・スレーブ構成は、以下の要素で構成されています:
- 基本構成要素
- マスターノード:書き込み/読み取り可能な主ノード
- スレーブノード:読み取り専用の複製ノード
- Sentinelノード:監視・制御を行う管理ノード
- データレプリケーションの流れ
[クライアント] → [マスターノード]
↓ レプリケーション
[スレーブノード1]
[スレーブノード2]
- 同期の仕組み
- 初期同期:スレーブ追加時のフルデータ同期
- 差分同期:通常運用時の変更データのみ同期
- バックログ管理:切断時の再同期用データ保持
フェイルオーバーの動作プロセス
フェイルオーバーは以下の5つのステップで実行されます:
- 障害検知フェーズ
- Sentinelによる定期的なヘルスチェック
- PING応答のタイムアウト監視
- 主観的ダウン(SDOWN)状態の判定
- 合意形成フェーズ
- 複数のSentinelによる状態確認
- 客観的ダウン(ODOWN)状態の判定
- クォーラム達成の確認
- リーダー選出フェーズ
- Raft合意アルゴリズムによるリーダーSentinel選出
- 選出されたSentinelがフェイルオーバーを主導
- 二重フェイルオーバーの防止
- 新マスター選出フェーズ
選出基準: 1. レプリケーション遅延が最小 2. 優先度が最高 3. レプリケーションIDが最新 4. ランタイムID(数値的に小さい方)
- 構成変更フェーズ
- 新マスターの昇格処理
- 他スレーブの再接続
- クライアント接続の切り替え
Sentinelノードの役割と必要数
- 主要な役割
- 監視:各Redisノードの状態監視
- 通知:管理者への障害通知
- 自動フェイルオーバー:障害時の自動復旧
- 構成プロバイダー:クライアントへの接続情報提供
- 推奨されるノード数 デプロイメント規模 推奨Sentinel数 クォーラム値 開発環境 3 2 小規模本番環境 3〜5 2〜3 大規模本番環境 5〜7 3〜4 地理分散環境 7以上 4以上
- 配置の考慮点
- 異なる物理サーバーへの分散配置
- ネットワークセグメントの分散
- 電源系統の分散
- データセンターをまたぐ配置
- パフォーマンスへの影響
監視間隔:1秒 タイムアウト:30秒(デフォルト) ネットワーク帯域:約1KB/秒/ノード CPU使用率:1%未満(通常時)
- 高度な設定オプション
- ダウン検知のタイムアウト調整
- フェイルオーバー実行の条件設定
- スクリプトによる外部連携
- カスタム通知の設定
このようなアーキテクチャにより、Redis Sentinelは高い信頼性と可用性を実現しています。適切な構成とパラメータ設定により、さまざまな運用要件に対応することが可能です。
Redis Sentinel環境の構築手順
基本的なセットアップ手順と設定ファイル
- Redis本体のインストール
# Ubuntuの場合 sudo apt-get update sudo apt-get install redis-server # CentOSの場合 sudo yum install epel-release sudo yum install redis
- マスターノードの設定(redis.conf)
# 基本設定 bind 0.0.0.0 port 6379 daemonize yes pidfile /var/run/redis/redis-server.pid # レプリケーション関連 requirepass "master_password" masterauth "master_password" # 永続化設定 appendonly yes appendfilename "appendonly.aof"
- スレーブノードの設定
# 基本設定(redis.conf) port 6380 daemonize yes pidfile /var/run/redis/redis-server.pid # レプリケーション設定 replicaof 192.168.1.100 6379 masterauth "master_password"
- Sentinelの設定(sentinel.conf)
# Sentinelの基本設定 port 26379 daemonize yes sentinel monitor mymaster 192.168.1.100 6379 2 sentinel auth-pass mymaster master_password # フェイルオーバー関連設定 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1
PHPアプリケーションからの接続設定
- Predisを使用した接続設定
// Composerでのインストール
// composer require predis/predis
// Sentinelを使用した接続設定
$sentinels = [
'tcp://192.168.1.100:26379',
'tcp://192.168.1.101:26379',
'tcp://192.168.1.102:26379'
];
$options = [
'replication' => 'sentinel',
'service' => 'mymaster',
'parameters' => [
'password' => 'master_password'
]
];
try {
$client = new Predis\Client($sentinels, $options);
// 接続テスト
$client->ping();
} catch (Exception $e) {
// エラーハンドリング
error_log('Redis接続エラー: ' . $e->getMessage());
}
- PhpRedisを使用した接続設定
// PhpRedisのインストール
// pecl install redis
// Sentinelを使用した接続
$redis = new Redis();
$sentinel = new RedisSentinel('192.168.1.100', 26379);
try {
// マスターの取得
$master = $sentinel->getMasterAddrByName('mymaster');
// マスターへの接続
$redis->connect($master[0], $master[1]);
$redis->auth('master_password');
} catch (RedisException $e) {
error_log('Sentinel接続エラー: ' . $e->getMessage());
}
動作確認とテスト方法
- 基本的な動作確認
# Sentinelの状態確認 redis-cli -p 26379 sentinel master mymaster # マスターの状態確認 redis-cli -h 192.168.1.100 -p 6379 info replication # スレーブの状態確認 redis-cli -h 192.168.1.101 -p 6380 info replication
- フェイルオーバーテスト
// PHPでのフェイルオーバーテストスクリプト
<?php
$redis = new Redis();
$sentinel = new RedisSentinel('192.168.1.100', 26379);
// 接続維持ループ
while (true) {
try {
$master = $sentinel->getMasterAddrByName('mymaster');
$redis->connect($master[0], $master[1]);
$redis->auth('master_password');
// データ書き込みテスト
$redis->set('test_key', date('Y-m-d H:i:s'));
echo "書き込み成功: " . $redis->get('test_key') . "\n";
sleep(1);
} catch (Exception $e) {
echo "エラー発生: " . $e->getMessage() . "\n";
echo "再接続を試みます...\n";
sleep(1);
}
}
- チェックリスト
| 確認項目 | 確認方法 | 期待値 |
|---|---|---|
| レプリケーション状態 | info replication | role:master/slave |
| Sentinel監視状態 | sentinel master mymaster | flags:master |
| フェイルオーバー動作 | マスター停止テスト | 自動切り替え |
| データ整合性 | キー値の比較 | 全ノードで一致 |
| 性能 | レイテンシチェック | 1ms以下 |
- 監視項目の設定
# Sentinelの詳細な監視設定 sentinel notification-script mymaster /etc/redis/notify.sh sentinel client-reconfig-script mymaster /etc/redis/reconfig.sh sentinel down-after-milliseconds mymaster 5000
このような構成で、高可用性を備えたRedis Sentinel環境を構築することができます。実運用では、ネットワークの分離やセキュリティ設定なども考慮に入れる必要があります。
Redis Sentinelの運用ベストプラクティス
効果的なモニタリング方法
- システムメトリクスの監視
| メトリクス | 監視項目 | 警告閾値 | 危険閾値 |
|---|---|---|---|
| メモリ使用率 | used_memory_rss | 80% | 90% |
| CPU使用率 | cpu_sys | 70% | 85% |
| レプリケーション遅延 | master_repl_offset | 1000 | 5000 |
| クライアント接続数 | connected_clients | 5000 | 8000 |
- Prometheusによる監視設定例
# prometheus.yml
scrape_configs:
- job_name: 'redis_exporter'
static_configs:
- targets: ['localhost:9121']
metrics_path: /metrics
relabel_configs:
- source_labels: [__address__]
target_label: instance
- Grafanaダッシュボードの推奨パネル
- マスター/スレーブの状態
- フェイルオーバーの発生回数
- コマンド実行レイテンシ
- メモリ使用状況
- ネットワークI/O
パフォーマンスチューニングのポイント
- メモリ管理の最適化
# redis.conf maxmemory 8gb maxmemory-policy allkeys-lru maxmemory-samples 10 # システム設定 vm.overcommit_memory = 1 vm.swappiness = 0
- ネットワーク設定の最適化
# システム設定 net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.tcp_keepalive_time = 300 # redis.conf tcp-keepalive 300 tcp-backlog 65535
- 永続化設定の調整
# AOF設定 appendonly yes appendfsync everysec no-appendfsync-on-rewrite yes auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # RDB設定 save 900 1 save 300 10 save 60 10000
障害検知の閾値設定
- Sentinel基本設定のチューニング
# sentinel.conf # ダウン検知の基本設定 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 # クォーラム設定 sentinel monitor mymaster 192.168.1.100 6379 2 # 並列同期数 sentinel parallel-syncs mymaster 1 # 通知スクリプト sentinel notification-script mymaster /etc/redis/notify.sh
- 環境別の推奨閾値
| 環境 | down-after-milliseconds | failover-timeout | parallel-syncs |
|---|---|---|---|
| 開発 | 5000 | 60000 | 1 |
| ステージング | 10000 | 180000 | 1 |
| 本番(標準) | 15000 | 300000 | 1 |
| 本番(大規模) | 30000 | 600000 | 2 |
- カスタムスクリプトの実装例
#!/bin/bash
# /etc/redis/notify.sh
# 障害通知スクリプト
EVENT_TYPE=$1
EVENT_DESC=$2
MASTER_NAME=$3
MASTER_IP=$4
MASTER_PORT=$5
# Slack通知
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"Redis Sentinel Event\nType: $EVENT_TYPE\nDesc: $EVENT_DESC\nMaster: $MASTER_NAME ($MASTER_IP:$MASTER_PORT)\"}" \
https://hooks.slack.com/services/YOUR/WEBHOOK/URL
# メール通知
echo "Redis Sentinel Event\nType: $EVENT_TYPE\nDesc: $EVENT_DESC\nMaster: $MASTER_NAME ($MASTER_IP:$MASTER_PORT)" | \
mail -s "Redis Sentinel Alert" admin@example.com
- 異常検知のベストプラクティス
- 複数のSentinelノードでの合意形成を確認
- ネットワーク分断を考慮した閾値設定
- 誤検知を防ぐための適切な遅延設定
- 環境に応じた段階的な閾値調整
- 監視設定の例(Zabbix)
# Zabbixトリガー設定
- 名前: Redis Sentinelマスターダウン
条件: {redis.sentinel.master.status} = 0
重要度: 高
- 名前: Redis Sentinelクォーラム未達
条件: {redis.sentinel.quorum.status} < {$MIN_QUORUM}
重要度: 警告
- 名前: Redisレプリケーション遅延
条件: {redis.replication.delay} > 1000
重要度: 警告
これらの設定と監視により、Redis Sentinelの安定運用が可能となります。実際の運用では、システムの規模や要件に応じて適切にカスタマイズすることが重要です。
PHPでのRedis Sentinel活用例
Predisを使用した実装例
- 基本的な接続設定
<?php
require 'vendor/autoload.php';
class RedisSentinelConnection {
private $client;
private $sentinels = [
'tcp://192.168.1.100:26379',
'tcp://192.168.1.101:26379',
'tcp://192.168.1.102:26379'
];
private $options = [
'replication' => 'sentinel',
'service' => 'mymaster',
'parameters' => [
'password' => 'master_password',
'database' => 0
],
'prefix' => 'app:',
];
public function __construct() {
try {
$this->client = new Predis\Client($this->sentinels, $this->options);
} catch (Exception $e) {
$this->handleConnectionError($e);
}
}
private function handleConnectionError($e) {
error_log("Redis接続エラー: " . $e->getMessage());
// リトライロジックやフォールバック処理を実装
}
public function getClient() {
return $this->client;
}
}
- セッション管理での活用例
<?php
class RedisSessionHandler implements SessionHandlerInterface {
private $redis;
private $ttl;
public function __construct(RedisSentinelConnection $connection, $ttl = 3600) {
$this->redis = $connection->getClient();
$this->ttl = $ttl;
}
public function open($path, $name): bool {
return true;
}
public function close(): bool {
return true;
}
public function read($id): string {
$data = $this->redis->get("session:$id");
return $data ?: '';
}
public function write($id, $data): bool {
return $this->redis->setex("session:$id", $this->ttl, $data);
}
public function destroy($id): bool {
$this->redis->del("session:$id");
return true;
}
public function gc($max_lifetime): bool {
return true; // Redisの有効期限機能により自動的に処理
}
}
// 使用例
$connection = new RedisSentinelConnection();
$handler = new RedisSessionHandler($connection);
session_set_save_handler($handler, true);
session_start();
- キャッシュシステムの実装例
<?php
class RedisCache {
private $redis;
private $defaultTtl;
public function __construct(RedisSentinelConnection $connection, $defaultTtl = 3600) {
$this->redis = $connection->getClient();
$this->defaultTtl = $defaultTtl;
}
public function get($key) {
try {
$value = $this->redis->get($key);
return $value ? json_decode($value, true) : null;
} catch (Exception $e) {
error_log("キャッシュ取得エラー: " . $e->getMessage());
return null;
}
}
public function set($key, $value, $ttl = null) {
try {
$ttl = $ttl ?: $this->defaultTtl;
$serialized = json_encode($value);
return $this->redis->setex($key, $ttl, $serialized);
} catch (Exception $e) {
error_log("キャッシュ設定エラー: " . $e->getMessage());
return false;
}
}
}
PhpRedisでの接続方法
- 基本的な接続処理
<?php
class RedisSentinelManager {
private $sentinels = [
['host' => '192.168.1.100', 'port' => 26379],
['host' => '192.168.1.101', 'port' => 26379],
['host' => '192.168.1.102', 'port' => 26379]
];
private $masterName = 'mymaster';
private $password = 'master_password';
public function getMasterConnection(): Redis {
$redis = new Redis();
foreach ($this->sentinels as $sentinel) {
try {
$sentinel = new RedisSentinel($sentinel['host'], $sentinel['port']);
$master = $sentinel->getMasterAddrByName($this->masterName);
if ($master) {
$redis->connect($master[0], $master[1]);
$redis->auth($this->password);
return $redis;
}
} catch (RedisException $e) {
continue;
}
}
throw new Exception('利用可能なマスターが見つかりません');
}
}
エラーハンドリングのベストプラクティス
- リトライメカニズムの実装
<?php
class RedisRetryWrapper {
private $connection;
private $maxRetries;
private $retryDelay;
public function __construct($connection, $maxRetries = 3, $retryDelay = 100) {
$this->connection = $connection;
$this->maxRetries = $maxRetries;
$this->retryDelay = $retryDelay;
}
public function executeWithRetry(callable $operation) {
$attempts = 0;
$lastException = null;
while ($attempts < $this->maxRetries) {
try {
return $operation($this->connection);
} catch (Exception $e) {
$lastException = $e;
$attempts++;
if ($attempts < $this->maxRetries) {
usleep($this->retryDelay * 1000 * $attempts);
$this->reconnect();
}
}
}
throw new Exception(
"操作が失敗しました。試行回数: $attempts, " .
"最後のエラー: " . $lastException->getMessage()
);
}
private function reconnect() {
// 再接続ロジックの実装
}
}
// 使用例
$wrapper = new RedisRetryWrapper($redisConnection);
$result = $wrapper->executeWithRetry(function($redis) {
return $redis->get('important_key');
});
- サーキットブレーカーパターンの実装
<?php
class RedisCircuitBreaker {
private $failureThreshold;
private $resetTimeout;
private $failures = 0;
private $lastFailureTime = 0;
private $state = 'CLOSED';
public function __construct($failureThreshold = 5, $resetTimeout = 60) {
$this->failureThreshold = $failureThreshold;
$this->resetTimeout = $resetTimeout;
}
public function execute(callable $operation) {
$this->checkState();
if ($this->state === 'OPEN') {
throw new Exception('Circuit Breaker is OPEN');
}
try {
$result = $operation();
$this->recordSuccess();
return $result;
} catch (Exception $e) {
$this->recordFailure();
throw $e;
}
}
private function checkState() {
if ($this->state === 'OPEN' &&
time() - $this->lastFailureTime >= $this->resetTimeout) {
$this->state = 'HALF-OPEN';
}
}
private function recordSuccess() {
if ($this->state === 'HALF-OPEN') {
$this->state = 'CLOSED';
$this->failures = 0;
}
}
private function recordFailure() {
$this->failures++;
$this->lastFailureTime = time();
if ($this->failures >= $this->failureThreshold) {
$this->state = 'OPEN';
}
}
}
これらの実装例により、PHPアプリケーションでRedis Sentinelを効果的に活用することができます。実際の運用では、システムの要件に応じて適切にカスタマイズすることが重要です。
Redis Sentinelのトラブルシューティング
よくある障害パターンと対処法
- フェイルオーバーの失敗
| 症状 | 考えられる原因 | 対処方法 |
|---|---|---|
| フェイルオーバーが開始されない | クォーラム不足 | Sentinelの稼働数確認と復旧 |
| フェイルオーバーが途中で停止 | ネットワーク分断 | ネットワーク状態の確認と修復 |
| 誤ったフェイルオーバー発生 | タイムアウト設定が厳しすぎる | down-after-millisecondsの調整 |
# フェイルオーバーの状態確認 redis-cli -p 26379 sentinel masters # マスターの状態確認 sentinel slaves mymaster # スレーブの状態確認 # クォーラムの確認 redis-cli -p 26379 sentinel ckquorum mymaster
- レプリケーション遅延
確認コマンド:
# マスターでの確認 redis-cli -h master_host info replication # スレーブでの確認 redis-cli -h slave_host info replication | grep -E "master_repl_offset|slave_repl_offset"
対処方法:
# redis.conf(スレーブ側) client-output-buffer-limit slave 256mb 64mb 60 repl-backlog-size 512mb
- メモリ関連の問題
# メモリ使用状況の確認 redis-cli info memory # メモリポリシーの確認と設定 redis-cli config get maxmemory-policy redis-cli config set maxmemory-policy allkeys-lru
ログ解析のポイント
- 重要なログパターン
# Sentinelログ +sdown # 主観的ダウンの検知 +odown # 客観的ダウンの検知 +try-failover # フェイルオーバー試行 +failover-state # フェイルオーバー状態の変更 +switch-master # マスター切り替えの実行
- ログ収集と分析ツール設定
# fluent.conf
<source>
@type tail
path /var/log/redis/sentinel.log
tag redis.sentinel
<parse>
@type regexp
expression /(?<time>\d{1,2}:\d{1,2}:\d{1,2}) (?<pid>\d+):(?<role>[X,C,S]) (?<message>.*)/
</parse>
</source>
<match redis.sentinel>
@type elasticsearch
host elasticsearch.example.com
port 9200
index_name redis-sentinel-logs
type_name redis_log
</match>
- 監視すべきログメッセージ
| ログパターン | 重要度 | 対応方法 |
|---|---|---|
| +sdown | 警告 | 対象ノードの状態確認 |
| +odown | 重要 | 即時対応が必要 |
| -sdown | 情報 | 復旧の確認 |
| +switch-master | 重要 | フェイルオーバーの検証 |
| +tilt | 緊急 | Sentinelの状態確認 |
パフォーマンス低下時の改善手順
- 性能診断手順
# レイテンシの確認 redis-cli --latency-history # スロークエリの特定 redis-cli slowlog get 10 # クライアント接続状況 redis-cli info clients # メモリ断片化の確認 redis-cli info memory | grep fragmentation
- パフォーマンス改善設定
# redis.conf # メモリ最適化 maxmemory-policy allkeys-lru maxmemory-samples 10 # レプリケーション最適化 repl-backlog-size 512mb repl-backlog-ttl 3600 # 永続化設定の調整 appendfsync everysec no-appendfsync-on-rewrite yes
- システムチューニング
# システム設定の最適化 echo never > /sys/kernel/mm/transparent_hugepage/enabled echo 1 > /proc/sys/vm/overcommit_memory echo 512 > /proc/sys/net/core/somaxconn # ディスクI/O設定 echo deadline > /sys/block/sda/queue/scheduler
- モニタリングスクリプト例
<?php
// パフォーマンスモニタリングスクリプト
function checkRedisPerformance($host, $port) {
$redis = new Redis();
$redis->connect($host, $port);
$metrics = [
'latency' => microtime(true),
'memory' => $redis->info('memory'),
'clients' => $redis->info('clients'),
'stats' => $redis->info('stats')
];
// レイテンシチェック
$redis->ping();
$metrics['latency'] = (microtime(true) - $metrics['latency']) * 1000;
// 結果の解析と報告
if ($metrics['latency'] > 100) {
error_log("High latency detected: {$metrics['latency']}ms");
}
if ($metrics['memory']['used_memory_rss'] > 8589934592) { // 8GB
error_log("High memory usage detected");
}
return $metrics;
}
- パフォーマンス改善チェックリスト
- [ ] メモリ使用率の確認と最適化
- [ ] ネットワークレイテンシの測定
- [ ] クライアント接続数の適正化
- [ ] スロークエリの特定と改善
- [ ] レプリケーション遅延の確認
- [ ] システムリソースの確認
- [ ] ディスクI/Oの最適化
- [ ] バックグラウンド処理の影響確認
これらのトラブルシューティング手法を活用することで、Redis Sentinelの安定運用が可能となります。定期的なログ解析とモニタリングを行い、問題の早期発見と対応を心がけることが重要です。
Redis Sentinelの発展的な使い方
大規模システムでの構成例
- マルチデータセンター構成
[データセンターA]
Master Redis
└── Slave Redis
└── Sentinel (3台)
[データセンターB]
Slave Redis
└── Sentinel (3台)
[データセンターC]
Slave Redis
└── Sentinel (3台)
設定例:
# sentinel.conf (DC-A) sentinel monitor mymaster 10.0.1.100 6379 5 sentinel known-sentinel mymaster 10.0.2.100 26379 dc2 sentinel known-sentinel mymaster 10.0.3.100 26379 dc3 # データセンター間の通信設定 sentinel announce-ip 10.0.1.100 sentinel announce-port 26379
- シャーディング構成
<?php
// シャーディング実装例
class RedisShardedSentinel {
private $shards;
private $totalShards;
public function __construct($shardConfigs) {
$this->totalShards = count($shardConfigs);
foreach ($shardConfigs as $shardId => $config) {
$this->shards[$shardId] = new RedisSentinelConnection(
$config['sentinels'],
$config['master_name']
);
}
}
public function get($key) {
$shardId = $this->getShardId($key);
return $this->shards[$shardId]->get($key);
}
private function getShardId($key) {
return crc32($key) % $this->totalShards;
}
}
クラウド環境での構築ポイント
- AWS環境での構成例
# Terraform設定例
resource "aws_elasticache_replication_group" "redis_cluster" {
replication_group_id = "redis-sentinel-cluster"
replication_group_description = "Redis with Sentinel"
node_type = "cache.r5.large"
number_cache_clusters = 3
automatic_failover_enabled = true
cluster_mode {
replicas_per_node_group = 2
num_node_groups = 1
}
}
resource "aws_security_group" "redis_security_group" {
name = "redis-sentinel-sg"
description = "Security group for Redis Sentinel"
ingress {
from_port = 6379
to_port = 6379
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
ingress {
from_port = 26379
to_port = 26379
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
}
- Kubernetes環境での構成
# redis-sentinel-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-sentinel
spec:
serviceName: redis-sentinel
replicas: 3
selector:
matchLabels:
app: redis-sentinel
template:
metadata:
labels:
app: redis-sentinel
spec:
containers:
- name: redis
image: redis:6.2
ports:
- containerPort: 6379
volumeMounts:
- name: redis-data
mountPath: /data
- name: sentinel
image: redis:6.2
command: ["redis-sentinel", "/etc/redis/sentinel.conf"]
volumeMounts:
- name: sentinel-config
mountPath: /etc/redis
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
監視システムとの連携方法
- Prometheusとの連携
# prometheus.yml
scrape_configs:
- job_name: 'redis_exporter'
static_configs:
- targets:
- 'redis-exporter:9121'
metrics_path: /metrics
relabel_configs:
- source_labels: [__address__]
target_label: instance
# Grafanaダッシュボード設定
{
"panels": [
{
"title": "Redis Sentinel Status",
"type": "stat",
"targets": [
{
"expr": "redis_sentinel_masters",
"legendFormat": "Masters"
}
]
},
{
"title": "Failover Events",
"type": "graph",
"targets": [
{
"expr": "rate(redis_sentinel_failover_total[5m])",
"legendFormat": "Failovers/min"
}
]
}
]
}
- アラート設定
# alertmanager.yml
groups:
- name: redis_sentinel_alerts
rules:
- alert: RedisSentinelQuorumLost
expr: redis_sentinel_quorum < 2
for: 1m
labels:
severity: critical
annotations:
summary: "Sentinel quorum lost"
description: "Redis Sentinel quorum is below minimum threshold"
- alert: RedisSentinelNoMaster
expr: redis_sentinel_masters == 0
for: 1m
labels:
severity: critical
annotations:
summary: "No Redis master available"
- カスタム監視スクリプト
<?php
// Sentinelヘルスチェックスクリプト
class SentinelHealthCheck {
private $sentinels;
private $masterName;
public function __construct($sentinels, $masterName) {
$this->sentinels = $sentinels;
$this->masterName = $masterName;
}
public function check() {
$health = [
'quorum' => 0,
'master_status' => false,
'slaves_count' => 0
];
foreach ($this->sentinels as $sentinel) {
try {
$redis = new RedisSentinel(
$sentinel['host'],
$sentinel['port']
);
$master = $redis->master($this->masterName);
if ($master) {
$health['quorum']++;
$health['master_status'] = true;
$health['slaves_count'] = count(
$redis->slaves($this->masterName)
);
}
} catch (Exception $e) {
error_log("Sentinel health check error: " . $e->getMessage());
}
}
return $health;
}
}
// 使用例
$checker = new SentinelHealthCheck([
['host' => '10.0.1.100', 'port' => 26379],
['host' => '10.0.1.101', 'port' => 26379],
['host' => '10.0.1.102', 'port' => 26379]
], 'mymaster');
$health = $checker->check();
これらの発展的な使用方法により、Redis Sentinelを大規模システムやクラウド環境で効果的に活用することができます。実際の導入時には、システムの要件や規模に応じて適切な構成を選択することが重要です。