配置文件:
port 26379 //哨兵端口号
daemonize yes //守护进程
pidfile "/usr/local/redis-sentinel/redis_sentinel_26379.pid" //pid目录
logfile "/usr/local/redis-sentinel/redis_sentinel_26379.log" //log目录
dir /usr/local/redis-sentinel //运行目录
sentinel monitor master_6379 127.0.0.1 6379 2 //自定义主节点名称、HOST、PORT、2票则认为主死(一般设置为哨兵节点数的一半+1)
sentinel down-after-milliseconds master_6379 30000 //失联30秒后则认定节点出问题
sentinel parallel-syncs master_26379 1 //在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步,设置过多会造成redis主节点压力变大
sentinel failover-timeout master_6379 180000 //故障中每个阶段的最长超时时间
sentinel deny-scripts-reconfig yes //不允许使用SENTINEL SET设置notification-script和client-reconfig-script
sentinel auth-path master_6379 why
port 26380
daemonize yes
pidfile "/usr/local/redis-sentinel/redis_sentinel_26380.pid"
logfile "/usr/local/redis-sentinel/redis_sentinel_26380.log"
dir /usr/local/redis-sentinel
sentinel monitor master_6379 127.0.0.1 6379 2
sentinel down-after-milliseconds master_6379 30000
sentinel parallel-syncs master_6379 1
sentinel failover-timeout master_6379 180000
sentinel deny-scripts-reconfig yes
sentinel auth-path master_6379 why
port 26381
daemonize yes
pidfile "/usr/local/redis-sentinel/redis_sentinel_26381.pid"
logfile "/usr/local/redis-sentinel/redis_sentinel_26381.log"
dir /usr/local/redis-sentinel
sentinel monitor master_6379 127.0.0.1 6379 2
sentinel down-after-milliseconds master_6379 30000
sentinel parallel-syncs master_6379 1
sentinel failover-timeout master_6379 180000
sentinel deny-scripts-reconfig yes
sentinel auth-path master_6379 why
运行:
redis-sentinel /usr/local/redis_sentinel/redis_sentinel_conf
运行后的配置文件:
port 26379
daemonize yes
pidfile "/usr/local/redis-sentinel/redis_sentinel_26379.pid"
logfile "/usr/local/redis-sentinel/redis_sentinel_26379.log"
dir "/usr/local/redis-sentinel"
sentinel myid b65bc8d309545ce496ae749cc7ebd2baed1e8e09
sentinel deny-scripts-reconfig yes
sentinel monitor master_6379 127.0.0.1 6379 2
sentinel config-epoch master_6379 0
sentinel leader-epoch master_6379 0
# Generated by CONFIG REWRITE
sentinel known-sentinel master_6379 127.0.0.1 26380 7f961871e2bce4d7e80e6bf0157614543fc8c92e
sentinel known-sentinel master_6379 127.0.0.1 26381 139b6932dea1161c71c643abf29f26f1a3a4088c
sentinel current-epoch 0
登录客户端:
redis-cli -p 26379
客户端API命令:
- info:查看守护信息
- sentinel masters:获取所有被监控的主节点信息
- sentinel master master_6379:获取某个主节点信息
- sentinel slaves:获取所有被监控从节点信息
- sentinel slaves master_6379:获取某个从节点信息
- sentinel get-master-addr-by-name master_6379:获取指定master name主节点的IP和port
- sentinel reset master_6379:对指定主节点的配置进行重置,包含清楚主节点的相关状态,重新发现从节点和sentinel节点
- sentinel failover master_6379:对指定主节点进行强制故障转移,转移完成后其他sentinel节点按照转移结果更新自身配置
- sentinel ckquorum master_6379:检测当前可用sentinel节点个数是否满足quorum个数
- sentinel flushconfig:将当前sentinel配置强制刷到磁盘上,用于配置文件丢失情况
- sentinel remove master_6379:取消当前sentinel节点对指定master节点的监控
- sentinel monitor master_6379 127.0.0.1 6379 2:添加当前sentinel节点对指定master节点的监控
- sentinel set master_6379 quorum 2:动态修改sentinel节点配置
- sentinel is-master-down-by-addr:sentinel节点之间用来交换对主节点是否下线的判断,根据参数的不同,还可以作为sentinel领导者选举的通信方式。
注意:
sentinel通过监视主节点,执行info replaction命令,从而获得并监视相应的从节点
一般一个主节点需要开启3个sentinel守护,则修改配置文件的主机地址、端口号即可。
一个sentinel可守护多个主节点
主节点出故障后,会推举出新的主节点,然后自动将新主节点配置文件的replicaof去掉,其他从节点的replicaof改为新的主节点,
replica-read-only 不改变,所以旧的从节点仍然只读,但新的主节点由去掉了replicaof配置,所以即使replica-read-only为yes,仍可作为主节点写入。
结论:主节点出故障后,将replica-read-only改为yes,重启即可,replicaof项都会被sentinel自动更改
PHP客户端实现:
<?php
class Sentinel
{
private $connection;
public function __construct()
{
$this->connection = [];
}
private function connect($host, $port)
{
try {
$con = new Redis();
$res = $con->connect($host, $port);
if ($res) {
return $con;
}
} catch (Exception $exception) {
echo "error hosts:" . $host . " port:" . $port . "\n";
}
return false;
}
public function setSentinel($host, $port)
{
$res = $this->connect($host, $port);
if ($res) {
$this->connection[] = $res;
return true;
}
return false;
}
public function getSentinel()
{
if (empty($this->connection)) {
throw new ErrorException("sorry no connection");
}
$masterList = [];
foreach ($this->connection as $con) {
$result = $con->rawCommand('SENTINEL', 'masters');
list(, , , $host, , $port) = $result[0];
$masterList[] = [$host, $port];
}
return $masterList;
}
public function getMaster()
{
$list = $this->getSentinel();
return $list[0];
}
public function getConnection()
{
list($host, $port) = $this->getMaster();
return $this->connect($host, $port);
}
}
$sentinel = new Sentinel();
$sentinel->setSentinel('127.0.0.1',26379);
$sentinel->setSentinel('127.0.0.1',26380);
$sentinel->setSentinel('127.0.0.1',26381);
//获取redis主服务配置
$cfg = $sentinel->getMaster();
print_r($cfg);
$conn = $sentinel->getConnection();
//查看连接是否正常
print_r($conn->ping());