一、redis.conf 配置项说明如下:
1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
     daemonize no
2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
     pidfile /var/run/redis.pid
3. 指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字
     port 6379
4. 绑定的主机地址
    bind 127.0.0.1
5.当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
     timeout 300
6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
     loglevel verbose
7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
     logfile stdout
8. 设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id
     databases 16
9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
     save <seconds> <changes>
    Redis默认配置文件中提供了三个条件:
    save 900 1
    save 300 10
    save 60 10000
    分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
 
10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
     rdbcompression yes
11. 指定本地数据库文件名,默认值为dump.rdb
     dbfilename dump.rdb
12. 指定本地数据库存放目录
     dir ./
13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
     slaveof <masterip> <masterport>
14. 当master服务设置了密码保护时,slav服务连接master的密码
     masterauth <master-password>
15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
    requirepass foobared
16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
    maxclients 128
17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
     maxmemory <bytes>
18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
     appendonly no
19. 指定更新日志文件名,默认为appendonly.aof
      appendfilename appendonly.aof
20. 指定更新日志条件,共有3个可选值: 
    no:表示等操作系统进行数据缓存同步到磁盘(快) 
    always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全) 
    everysec:表示每秒同步一次(折衷,默认值)
     appendfsync everysec
 
21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)
      vm-enabled no
22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享
      vm-swap-file /tmp/redis.swap
23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0
      vm-max-memory 0
24. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值
      vm-page-size 32
25. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。
      vm-pages 134217728
26. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4
      vm-max-threads 4
27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启
     glueoutputbuf yes
28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法
     hash-max-zipmap-entries 64
    hash-max-zipmap-value 512
29. 指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)
     activerehashing yes
30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
     include /path/to/local.conf
 
二、redis-sentinel.conf配置项说明如下:
1. sentinel监听端口,默认是26379,可以修改。
port 26379
 
2.sentinel monitor <master-name> <ip> <redis-port> <quorum>
告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效。master-name只能包含英文字母,数字,和“.-_”这三个字符需要注意的是master-ip 要写真实的ip地址而不要用回环地址(127.0.0.1)。
配置示例:
sentinel monitor mymaster 192.168.0.5 6379 2
 
3. sentinel auth-pass <master-name> <password>
设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
配置示例:
sentinel auth-pass mymaster 0123passw0rd
 
4.sentinel down-after-milliseconds <master-name> <milliseconds> 
这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
配置示例:
sentinel down-after-milliseconds mymaster 30000
 
5.sentinel parallel-syncs <master-name> <numslaves> 
这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
配置示例:
sentinel parallel-syncs mymaster 1
 
6. sentinel failover-timeout <master-name> <milliseconds>
failover-timeout 可以用在以下这些方面: 
      1. 同一个sentinel对同一个master两次failover之间的间隔时间。
      2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
      3.当想要取消一个正在进行的failover所需要的时间。  
      4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。
配置示例:
sentinel failover-timeout mymaster1 20000
 
7.sentinel的notification-script和reconfig-script是用来配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。对于脚本的运行结果有以下规则:
        若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
        若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
        如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
        一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
1).sentinel notification-script <master-name> <script-path> 
通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,一个是事件的类型,一个是事件的描述。如果sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无法正常启动成功。
  配置示例:
 sentinel notification-script mymaster /var/redis/notify.sh
 
2).sentinel client-reconfig-script <master-name> <script-path>
 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。以下参数将会在调用脚本时传给脚本:
       <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
目前<state>总是“failover”, <role>是“leader”或者“observer”中的一个。 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通信的。这个脚本应该是通用的,能被多次调用,不是针对性的。
   配置示例:
   sentinel client-reconfig-script mymaster /var/redis/reconfig.sh


----------------------------------------------------------------------------
Redis sentinel 主从自动切换配置

配置sentinel至少需要两个redis服务实例
10.118.220.137 6380 master
10.118.220.138 6380 slave1
10.118.220.139 6380 slave2

主从配置,在从数据库添加 slaveof 10.118.220.137 6380
# 查看主从状态 info replication
[root@mycat02 src]# ./redis-cli -h 10.118.220.137 -p 6380
10.118.220.137:6380>
10.118.220.137:6380> AUTH redis123
OK
10.118.220.137:6380> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.118.220.139,port=6380,state=online,offset=13411096,lag=1
slave1:ip=10.118.220.138,port=6380,state=online,offset=13411096,lag=1
master_repl_offset:13411096
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:12362521
repl_backlog_histlen:1048576

# ---redis-cli -h 10.118.220.137 -p 6380 -a password info Replication -- #
# 查询Sentinel状态 info sentinel
# -- redis-cli -h 10.118.220.137 -p 26379 -a password info Sentinel -- #
[root@mycat02 src]# ./redis-cli -h 10.118.220.137 -p 26380
10.118.220.137:26380> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=master,status=ok,address=10.118.220.137:6380,slaves=2,sentinels=4
看到status=ok 说明正常sentinel配置
创建sentinel配置文件
vim /usr/local/redis-master/sentinel.conf
port 26379
#sentinel需要监控的master信息
sentinel monitor master 127.0.0.1 6380 2
#master password
sentinel down-after-milliseconds master 5000
#master被当前sentinel实例认定为“失效”(SDOWN)的间隔时间
sentinel failover-timeout master 60000
sentinel auth-pass master password
sentinel config-epoch master 12
--------------------------------------------------------------
[root@mycat02 src]# cat /usr/local/redis-3.2.5/sentinel.conf
port 26380
#sentinel需要监控的master信息
sentinel myid 9a6fa49fe77d656e3d4536513b9faa6aced3d88d
--当启动后,系统自动添加唯一标示
sentinel monitor master 10.118.220.137 6380 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 60000
sentinel auth-pass master redis123

sentinel config-epoch master 13
dir "/usr/local/redis-3.2.5"
protected-mode yes
bind 10.118.220.137

# Generated by CONFIG REWRITE
sentinel leader-epoch master 0
sentinel known-slave master 10.118.220.139 6380
sentinel known-slave master 10.118.220.138 6380
sentinel known-sentinel master 10.118.220.139 26380 7324b2e8aa00bc51caf7e2ef8ac16537602322ac
sentinel known-sentinel master 10.118.220.139 0 97e531d20c528418c065fc9ed381ddad69067fa0
sentinel known-sentinel master 10.118.220.138 26380 a10dab2cafd172a889229f056e13b4597ce071bb
sentinel current-epoch 13
--以上为系统自动添加,在自动启动后。
---------------------------------------------------------------------

创建其他两个配置文件 端口分别为26479 26579
/usr/local/redis-slave1/sentinel.conf
/usr/local/redis-slave2/sentinel.conf
启动sentinel
nohup /usr/local/redis-master/redis-server /usr/local/redis-master/sentinel.conf --sentinel &
nohup /usr/local/redis-slave1/redis-server /usr/local/redis-slave1/sentinel.conf --sentinel &
nohup /usr/local/redis-slave2/redis-server /usr/local/redis-slave2/sentinel.conf --sentinel &
主从切换测试关掉主命令redis-cli -h 127.0.0.1 -p 6380 -a password shutdown
自动切换后sentinel、主、从的配置文件都会发生改变,会在配置文件的最后增加信息
哨兵启动和主数据库建立连接后,会定时执行下面3个操作
1、每10秒哨兵会向主数据库和从数据库发送INFO命令
2、每2秒哨兵会向主数据库和从数据库的_sentinel_:hello 频道发送自己的信息
3、每1秒哨兵会向主数据库、从数据库和其他哨兵节点发送PING命令
redis命令
slaveof no one 全当前数据库停止接收其他数据库同步并转换成主数据库
min-slaves-to-write 3 只有三个或三个以上从数据库连接到主数据库时,主数据库才是可写的,否则会返回错误
repl-diskless-sync yes 启用无硬盘复制
slave-priority 100 slave优先级
Redis Sentinel配置手记


Sentinel是一个管理多个redis实例的工具,它可以实现对redis的监控、通知、自动故障转移。sentinel不断的检测redis实例是否可以正常工作,通过API向其他程序报告redis的状态,如果redis master不能工作,则会自动启动故障转移进程,将其中的一个slave提升为master,其他的slave重新设置新的master实例。也就是说,它提供了:

监控(Monitoring): Sentinel 会不断地检查你的主实例和从实例是否正常。

通知(Notification): 当被监控的某个 Redis 实例出现问题时, Sentinel 进程可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover): 当一个主redis实例失效时, Sentinel 会开始记性一次failover, 它会将失效主实例的其中一个从实例升级为新的主实例, 并让失效主实例的其他从实例改为复制新的主实例; 而当客户端试图连接失效的主实例时, 集群也会向客户端返回新主实例的地址, 使得集群可以使用新主实例代替失效实例。

Redis Sentinel自身也是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程, 这些进程使用流言协议(gossip protocols)来接收关于主Redis实例是否失效的信息, 然后使用投票协议来决定是否执行自动failover,以及评选出从Redis实例作为新的主Redis实例。
1.启动sentinel的方法

当前Redis stable版已经自带了redis-sentinel这个工具。虽然 Redis Sentinel 已经提供了一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis实例, 你可以在启动一个普通 Redis实例时通过给定 –sentinel 选项来启动 Redis Sentinel 实例。也就是说:
redis-sentinel /path/to/sentinel.conf

等同于
redis-server /path/to/sentinel.conf --sentinel

其中sentinel.conf是redis的配置文件,Redis sentinel会需要写入配置文件来保存sentinel的当前状态。当配置文件无法写入时,Sentinel启动失败。
2. sentinel的配置

一个简单的sentinel配置文件实例如下:

port 26329
sentinel monitor myredis 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel notification-script myredis

sentinel 选项的名字 主Redis实例的名字 选项的值

配置文件的格式为:

第一行配置指示 Sentinel 去监视一个名为 mymaster 的主redis实例, 这个主实例的 IP 地址为本机地址127.0.0.1 , 端口号为 6379 , 而将这个主实例判断为失效至少需要 2 个 Sentinel 进程的同意,只要同意 Sentinel 的数量不达标,自动failover就不会执行。同时,一个Sentinel都需要获得系统中大多数Sentinel进程的支持, 才能发起一次自动failover, 并预留一个新主实例配置的编号。而当超过半数Redis不能正常工作时,自动故障转移是无效的。

各个选项的功能如下:

down-after-milliseconds选项指定了 Sentinel 认为Redis实例已经失效所需的毫秒数。

当实例超过该时间没有返回PING,或者直接返回错误, 那么 Sentinel 将这个实例标记为主观下线(subjectively down,简称 SDOWN )。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移: 只有在足够数量的 Sentinel 都将一个实例标记为主观下线之后,实例才会被标记为客观下线(objectively down, 简称 ODOWN ), 这时自动故障迁移才会执行。具体的行为如下:

(1).每个 Sentinel 每秒一次向它所监控的主实例、从实例以及其他 Sentinel 实例发送一个 PING 命令。当一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 Sentinel 标记为主观下线。如果一个主实例被标记为主观下线, 并且有足够数量的 Sentinel (至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主实例被标记为客观下线。

(2).在一般情况下, 每个 Sentinel 进程会以每 10 秒一次的频率向它已知的所有主实例和从实例发送 INFO 命令。 当一个主实例被 Sentinel实例标记为客观下线时, Sentinel 向下线主实例的所有从实例发送 INFO 命令的频率会从 10 秒一次改为每秒一次。

(3).当没有足够数量的 Sentinel 同意主实例已经下线, 主Redis服务实例的客观下线状态就会被移除。 当主服务器重新向 Sentinel 的PING 命令返回有效回复时, 主服务器的主观下线状态就会被移除。

parallel-syncs选项指定了在执行故障转移时, 最多可以有多少个从Redis实例在同步新的主实例, 在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长。

尽管复制过程的绝大部分步骤都不会阻塞从实例, 但从redis实例在载入主实例发来的 RDB 文件时, 仍然会造成从实例在一段时间内不能处理命令请求: 如果全部从实例一起对新的主实例进行同步, 那么就可能会造成所有从Redis实例在短时间内全部不可用的情况出现。

所以从实例被设置为允许使用过期数据集(参见对 redis.conf 文件中对 slave-serve-stale-data 选项),可以缓解所有从实例都在同一时间向新的主实例发送同步请求的负担。你可以通过将这个值设为 1 来保证每次只有一个从Redis实例处于不能处理命令请求的同步状态。

failover-timeout如果在该时间(ms)内未能完成failover操作,则认为该failover失败。

notification-script: 指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用。
3. Sentinel集群的运行机制

一个 Sentinel进程可以与其他多个 Sentinel进程进行连接, 每个 Sentinel进程之间可以互相检查对方的可用性, 并进行信息交换。

和其他集群不同的是,你无须设置其他Sentinel的地址,Sentinel进程可以通过发布与订阅来自动发现正在监视相同主实例的其他Sentinel。同样,你也不必手动列出主实例属下的所有从实例,因为Sentinel实例可以通过询问主实例来获得所有从实例的信息。

每个 Sentinel 都订阅了被它监视的所有主服务器和从服务器的 __sentinel__:hello 频道, 查找之前未出现过的 sentinel进程。 当一个 Sentinel 发现一个新的 Sentinel 时,它会将新的 Sentinel 添加到一个列表中,这个列表保存了 Sentinel 已知的,监视同一个主服务器的所有其他Sentinel。
4. 启动Redis和sentinel

下面的测试环境为ubuntu 14.04 LTS,Redis 2.8.19。下面首先配置一个小型的M/2S环境。

/etc/redis/redis-m.conf
daemonize yes
pidfile /var/run/redis/redis-server-m.pid
port 6379
loglevel notice
logfile /var/log/redis/redis-server-m.log
databases 16
##disable snapshot
save ""
dir /app/redis-m
appendonly yes
appendfilename "appendonly.aof"
##not to be a slave
#slaveof no one

/etc/redis/redis-s1.conf
daemonize yes
pidfile /var/run/redis/redis-server-s1.pid
port 6380
loglevel warning
logfile /var/log/redis/redis-server-s1.log
databases 16
##disable snapshot
save ""
dir /app/redis-s1
appendonly yes
appendfilename "appendonly.aof"
##to be a slave

/etc/redis/redis-s2.conf
daemonize yes
pidfile /var/run/redis/redis-server-s2.pid
port 6381
loglevel warning
logfile /var/log/redis/redis-server-s2.log
databases 16
##disable snapshot,enable AOF
save ""
dir /app/redis-s2
appendonly yes
appendfilename "appendonly.aof"
##to be a slave
slaveof 127.0.0.1 6379

启动后,查看进程和复制状态是否正常:

ps -ef | grep redis
root 17560 1 0 09:48 ? 00:00:00 redis-server *:6379
root 17572 1 0 09:48 ? 00:00:00 redis-server *:6380
root 17609 1 0 09:49 ? 00:00:00 redis-server *:6381

redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=547,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=547,lag=1
master_repl_offset:547
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:546

前面我们了解了,Sentinel可以通过master Redis实例来获得它的从实例的信息。所以每一个Sentinel只配置主实例的监控即可。Sentinel之间端口有所不同。

port 26379
sentinel monitor myredis 127.0.0.1 6379 2
sentinel down-after-milliseconds myredis 60000
sentinel failover-timeout myredis 180000
sentinel parallel-syncs myredis 1
sentinel notification-script myredis /etc/redis/log-issues.sh

其中,通知脚本简单的记录一下failover事件。

#!/bin/bash

echo "master failovered at `date`" > /root/redis_issues.log

另外两个端口分别为port 26380。然后通过redis-sentinel命令来启动两个sentinel实例。

# nohup redis-sentinel /etc/redis/sentinel1.conf > /root/sentinel1.log 2>&1 &
[1] 18207
# nohup redis-sentinel /etc/redis/sentinel2.conf > /root/sentinel2.log 2>&1 &
[2] 18212

通过日志输出可以看出已经成功监控master和两个slave。并和另一个sentinel进程通信。

[18207] 08 May 13:28:29.336 # Sentinel runid is d72be991001b994568d3de1b746f611884b0343a
[18207] 08 May 13:28:29.336 # +monitor master myredis 127.0.0.1 6379 quorum 2
[18207] 08 May 13:28:29.339 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
[18207] 08 May 13:28:29.339 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
[18207] 08 May 13:28:36.602 * +sentinel sentinel 127.0.0.1:26479 127.0.0.1 26479 @ myredis 127.0.0.1 6379

5. 连接Sentinel和主动failover

在默认情况下,Sentinel 使用TCP端口26379(普通 Redis 服务器使用的是 6379)。Sentinel 接受 Redis 协议格式的命令请求, 所以你可以使用 redis-cli 或者任何其他 Redis 客户端来与 Sentinel 进行通讯。

有两种方式可以和 Sentinel 进行通讯:

第一种方法是通过直接发送命令来查询被监视 Redis 服务器的当前状态, 以及进行主动转移等操作。这些命令包括:

(1). PING :返回 PONG 。

# redis-cli -p 26379
127.0.0.1:26379> ping
PONG

(2). SENTINEL masters:列出所有被监视的主Redis服务实例,以及这些主服务实例的当前状态。SENTINEL slaves :列出给定主服务实例的所有从实例,以及这些从实例的当前状态。

127.0.0.1:26379> sentinel masters
1) 1) "name"
2) "myredis"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) "a88ffd6548e333f3ac895cf1b890ef32a527dd66"
......
37) "parallel-syncs"
38) "1"
39) "notification-script"
40) "/etc/redis/log-issues.sh"
127.0.0.1:26379> sentinel slaves myredis
1) 1) "name"
2) "127.0.0.1:6381"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6381"
......
2) 1) "name"
2) "127.0.0.1:6380"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6380"
.......

(3). SENTINEL get-master-addr-by-name : 返回给定名字的主实例的 IP 地址和端口号。 如果这个主实例正在执行故障转移操作, 或者针对这个主实例的故障转移操作已经完成, 那么这个命令返回新的主服务器的 IP 地址和端口号。

127.0.0.1:26379> sentinel get-master-addr-by-name myredis
1) "127.0.0.1"
2) "6379"

(4). SENTINEL reset : 重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清除该sentinel的所保存的所有状态信息,并进行一次重新的发现过程。

127.0.0.1:26379> sentinel reset myredis

(integer) 1

(5). SENTINEL failover :进行一次主动的failover。即在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移 。发起故障转移的 Sentinel 会向其他 Sentinel 发送一个新的配置,其他 Sentinel 会根据这个配置进行相应的更新。

127.0.0.1:26379> sentinel failover master ---主动failover 切换测试
OK

## master切换到了localhost:6381上。

127.0.0.1:26379> sentinel get-master-addr-by-name myredis
1) "127.0.0.1"
2) "6381"
## redis-cli中
redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up

第二种方法是使用发布与订阅功能, 通过接收 Sentinel 发送的通知: 当执行故障转移操作, 或者某个被监视的实例被判断为主观下线或者客观下线时, Sentinel 就会发送相应的信息。

一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。

通过执行 PSUBSCRIBE * 命令可以接收所有事件信息。例如:

127.0.0.1:26379> PSUBSCRIBE *
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "*"
3) (integer) 1

###此时进行一次主动的failover,各个频道的输出中涉及了新纪元(epoch)通知、投票、选举、新主和新slave的通告、角色转变通知,最终完成了这次主动failover过程。

1) "pmessage"
2) "*"
3) "+new-epoch"
4) "2"
1) "pmessage"
2) "*"
3) "+try-failover"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+vote-for-leader"
4) "d72be991001b994568d3de1b746f611884b0343a 2"
1) "pmessage"
2) "*"
3) "+elected-leader"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-select-slave"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+selected-slave"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-send-slaveof-noone"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-wait-promotion"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "-role-change"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381 new reported role is master"
1) "pmessage"
2) "*"
3) "+promoted-slave"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-reconf-slaves"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+slave-reconf-sent"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+slave-reconf-inprog"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+slave-reconf-done"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-end"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+switch-master"
4) "myredis 127.0.0.1 6381 127.0.0.1 6380"
1) "pmessage"
2) "*"
3) "+slave"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6380"
1) "pmessage"
2) "*"
3) "+slave"
4) "slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380"
1) "pmessage"
2) "*"
3) "-role-change"
4) "slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380 new reported role is master"
1) "pmessage"
2) "*"
3) "+role-change"
4) "slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380 new reported role is slave"

由此可见,一次failover的过程如下:

一次故障转移操作由以下步骤组成:

(1).由sentinel主动发起failover或者发现主服务器已经进入客观下线状态。

(2).sentinel对我们的当前纪元(epoch)进行自增,并尝试在这个纪元中当选为此次failover的总指挥。

(3).如果当选失败, 那么在设定的故障迁移超时时间的两倍之后, 重新尝试当选。 如果当选成功, 那么执行以下步骤。

(4).选出一个从redis实例,并将它升级为主redis实例。

(5).向被选中的从redis实例发送 SLAVEOF NO ONE 命令,让它转变为主redis实例。

(6).通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel , 其他 Sentinel 对它们自己的配置进行更新。

(7).向已下线主服务器的从服务器发送SLAVEOF命令, 让它们去复制新的主服务器。

(8).当所有从redis实例都已经开始复制新的主redis实例时, 领头Sentinel 终止这次故障迁移操作。
6. 被动failover场景测试

当前状态,主failover为6380

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380

关闭6380Redis实例,等待down-after-milliseconds后,sentinel的日志有如下输出,证明切换成功。

[18207] 08 May 14:20:32.784 # +sdown master myredis 127.0.0.1 6380
[18207] 08 May 14:20:32.855 # +odown master myredis 127.0.0.1 6380 #quorum 2/2
[18207] 08 May 14:20:32.855 # +new-epoch 3
......投票、选举......
[18207] 08 May 14:20:34.989 # +switch-master myredis 127.0.0.1 6380 127.0.0.1 6381
[18207] 08 May 14:20:34.989 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381
[18207] 08 May 14:20:34.992 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381

启动6380实例,它会自己作为slave连接行6381这个master节点上。

$ redis-server /etc/redis/redis-s1.conf
$ redis-cli -p 6380
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up

测试成功。最后需要注意的是,sentinel集群自身也需要多数机制,也就是2个sentinel进程时,挂掉一个另一个就不可用了。
7. Sentinel的客户端

如果要做到应用程序(客户端)对Redis的failover透明Transparent),客户端需要监控sentinel的频道信息,并自动连接新的主节点。官方提供了一个专门的topic来讲解这个问题: Guidelines for Redis clients with support for Redis Sentinel ,而一些常用的开发语言也已经有了整合sentinel的redis driver:

Node.JS redis-sentinel-client — Transparent Redis Sentinel client

Python redis 2.10.3

Java Jedis

以Python为例,首先安装redis-py。
pip install redis

一个简单的测试代码如下,首先获得一个Sentinel对象,然后

vim sentinel.py
from redis.sentinel import Sentinel
sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
master = sentinel.master_for('myredis', socket_timeout=0.1)
master.set('foo', 'bar')
slave = sentinel.slave_for('myredis', socket_timeout=0.1)
slave.get('foo')

执行后成功得到bar这个值。

python sentinel.py
bar

上面的master和slave都是标准的建立好连接的StrictRedis实例,slave则是sentinel查询到的第一个可用的slave。如果正在连接的master不可用时,客户端会先抛出redis.exceptions.ConnectionError异常(此时还没开始failover),然后抛出redis.sentinel.MasterNotFoundError异常(failover进行中),在sentinel正常failover之后,实例正常。所以要开发一个sentinel的高可用客户端,可以参考上面那篇官方的指导。

--------------------------
[root@mycat01 ~]# cat /usr/local/redis-3.2.5/sentinel.conf
port 26380
#sentinel需要监控的master信息
sentinel myid a10dab2cafd172a889229f056e13b4597ce071bb

#master password

sentinel monitor master 10.118.220.137 6380 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 60000
sentinel auth-pass master redis123

sentinel config-epoch master 12
dir "/usr/local/redis-3.2.5"
protected-mode yes

bind 10.118.220.137
# Generated by CONFIG REWRITE
sentinel leader-epoch master 0
sentinel known-slave master 10.118.220.138 6380
sentinel known-slave master 10.118.220.139 6380
sentinel known-sentinel master 10.118.220.139 26380 7324b2e8aa00bc51caf7e2ef8ac16537602322ac
sentinel known-sentinel master 10.118.220.139 0 97e531d20c528418c065fc9ed381ddad69067fa0
sentinel known-sentinel master 10.118.220.138 26380 9a6fa49fe77d656e3d4536513b9faa6aced3d88d
sentinel current-epoch 12

GitHub 加速计划 / sentine / Sentinel
22.24 K
7.98 K
下载
alibaba/Sentinel: Sentinel 是阿里巴巴开源的一款面向分布式服务架构的流量控制、熔断降级组件,提供实时监控、限流、降级和系统保护功能,适用于微服务治理场景。
最近提交(Master分支:3 个月前 )
195150bc * fix issue 2485 which occur oom when using async servlet request. * optimize imports * 1. fix the same issue in the webmvc-v6x 2. improve based on review comments 2 个月前
b78b09d3 2 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐