Redis Sentinel模式集群搭建及说明
说明:三台机器 centos:6.7 Redis-3.0.7
一、单机安装Redis
安装说明:
安装目录 | /usr/local/redis3 |
配置文件目录 | /usr/local/redis3/conf |
数据存储目录 | /database/redis |
日志目录 | /var/log/redis |
服务启动用户名 | root |
1、下载:wget http://yunwei.up366.cn/tools/redis/redis-3.0.7.tar.gz
解压:tar -zxvf redis-3.0.7.tar.gz
安装:进入解压后的目录(redis-3.0.7)
make PREFIX=/usr/local/redis3 (如果有malloc的报错,则执行 make PREFIX=/usr/local/redis3 MALLOC=libc )
make test (如果出现如下图报错,执行yum install tcl -y再make test)
make install PREFIX=/usr/local/redis3
创建所需目录(配置文件目录、数据存储目录、日志目录)
mkdir -p /usr/local/redis3/conf /database/redis /var/log/redis
2、创建实例数据存储目录
mkdir -p /database/redis/redis_6379
从解压目录(redis-3.0.7)中复制配置文件redis.conf到/usr/local/redis3/conf目录下
cp redis.conf /usr/local/redis3/conf/redis_6379.conf
编辑配置文件redis_6379.conf,按照下表中的配置项修改配置文件
# | 配置项 | 配置参数 | 配置项含义 |
1 | daemonize | yes | #指定是否后台运行,yes:是,no:否 |
2 | pidfile | /var/run/redis_6379.pid | #指定pid文件路径 |
3 | port | 6379 | #指定实例端口 |
4 | logfile | "/var/log/redis/redis_6379.log" | #指定日志文件路径 |
5 | dbfilename | dump.rdb | #指定dump文件名 |
6 | dir | /database/redis/redis_6379/ | #指定数据存储目录 |
7 | appendonly | yes | #启用AOF持久化方式,yes:启用,no:禁用 |
3、启动服务
启动redis服务:/usr/local/redis3/bin/redis-server /usr/local/redis3/conf/redis_6379.conf
检查服务进程是否正常:ps -ef |grep 6379
检查日志是否有报错:/var/log/redis/redis_6379.log
二、搭建主从:
从服务器执行:slaveof 主库ip 6379
三、配置Sentinel:
1、编辑Sentinel配置文件
vim /usr/local/redis3/conf/sentinel.conf
port 26379
daemonize yes
dir /database
logfile "/var/log/redis/sentinel1.log"
sentinel monitor mymaster 192.168.0.142 6379 2
sentinel down-after-milliseconds mymaster 6000(默认是30s)
sentinel failover-timeout mymaster 30000
sentinel auth-pass mymaster up366.com
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh(实现vip的漂移)
注:三个节点均添加
2、编辑reconfig.sh脚本(故障转移时自动触发,前端只需连接vip即可,vip永远存在于主库)
#!/bin/bash
MASTER_IP=${6}
MY_IP='192.168.0.142' # 每个Server本身的IP
VIP='192.168.0.145' # VIP
NETMASK='24' # Netmask
INTERFACE='eth0' # 接口
if [ ${MASTER_IP} = ${MY_IP} ]; then
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
exit 0
fi
exit 1
3、启动Sentinel(三个节点均开启)
./redis-server /usr/local/redis3/conf/sentinel.conf --sentinel &
集群说明:
1、Redis配置文件参数说明:
daemonize yes
#当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
pidfile "/var/run/redis_6379.pid"
#指定Redis监听端口,默认端口为6379
port 6379
#master配置
#登陆redis密码进入redis后需输入auth password
requirepass "up366.com"
#此参数确定了TCP连接中已完成队列(完成三次握手之后)的长度, 当然此值必须不大于Linux系统定义的/proc/sys/net/core/somaxconn值,默认是511,而Linux的默认参数值是128。
tcp-backlog 511
#当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 0
#如果设置不为0,就使用配置tcp的SO_KEEPALIVE值,使用keepalive有两个好处:检测挂掉的对端。降低中间设备出问题而导致网络看似连接却已经与对端端口的问题。在Linux内核中,设置了keepalive,redis会定时给对端发送ack。检测到对端关闭需要两倍的设置值。
tcp-keepalive 0
#指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose(debug 记录很多信息,用于开发和测试# varbose 有用的信息,不像debug会记录那么多# notice 普通的verbose,常用于生产环境# warning 只有非常重要或者严重的信息会记录到日志)
loglevel notice
#日志记录文件
logfile "/var/log/redis/redis_6379.log"
#设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库(相当于有16个数据库空间,切换到不同的空间切换数据)
databases 16
#指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合(分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。)
save 900 1
save 300 10
save 60 10000
#当RDB持久化出现错误后,是否依然进行继续进行工作,yes:不能进行工作,no:可以继续进行工作,可以通过info中的rdb_last_bgsave_status了解RDB持久化是否有错误
stop-writes-on-bgsave-error yes
#指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes
#是否校验rdb文件。
rdbchecksum yes
#指定本地数据库文件名,默认值为dump.rdb
dbfilename "dump.rdb"
#指定本地数据库存放目录
dir "/database/redis/redis_6379"
#当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:1) 如果slave-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。2) 如果slave-serve-stale-data设置为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”。
slave-serve-stale-data yes
#作为从服务器,默认情况下是只读的
slave-read-only yes
#是否使用socket方式复制数据。目前redis复制提供两种方式,disk和socket。如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件。有2种方式:disk方式是master创建一个新的进程把rdb文件保存到磁盘,再把磁盘上的rdb文件传递给slave。socket是master创建一个新的进程,直接把rdb文件以socket的方式发给slave。disk方式的时候,当一个rdb保存的过程中,多个slave都能共享这个rdb文件。socket的方式就的一个个slave顺序复制。在磁盘速度缓慢,网速快的情况下推荐用socket方式。
repl-diskless-sync no
#diskless复制的延迟时间,防止设置为0。一旦复制开始,节点不会再接收新slave的复制请求直到下一个rdb传输。所以最好等待一段时间,等更多的slave连上来。
repl-diskless-sync-delay 5
#slave根据指定的时间间隔向服务器发送ping请求。
repl-ping-slave-period 10
#是否禁止复制tcp链接的tcp nodelay参数,可传递yes或者no。默认是no,即使用tcp nodelay。如果master设置了yes来禁止tcp nodelay设置,在把数据复制给slave的时候,会减少包的数量和更小的网络带宽。但是这也可能带来数据的延迟。默认我们推荐更小的延迟,但是在数据量传输很大的场景下,建议选择yes。
repl-disable-tcp-nodelay no
#当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master。而配置成0,永远不会被选举。
slave-priority 100
#默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
appendonly yes
#aof文件名
appendfilename "appendonly.aof"
#aof持久化策略的配置 #no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快。 #always表示每次写入都执行fsync,以保证数据同步到磁盘。 #everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。
appendfsync everysec
#在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据。
no-appendfsync-on-rewrite no
#aof自动重写配置。当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。
auto-aof-rewrite-percentage 100
#设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写
auto-aof-rewrite-min-size 64mb
#of文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项(redis宕机或者异常终止不会造成尾部不完整现象。)出现这种现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。
aof-load-truncated yes
#如果达到最大时间限制(毫秒),redis会记个log,然后返回error。当一个脚本超过了最大时限。只有SCRIPT KILL和SHUTDOWN NOSAVE可以用。第一个可以杀没有调write命令的东西。要是已经调用了write,只能用第二个命令杀。
lua-time-limit 5000
#执行时间比slowlog-log-slower-than大的请求记录到slowlog里面,单位是微秒,所以1000000就是1秒。注意,负数时间会禁用慢查询日志,而0则会强制记录所有命令。
slowlog-log-slower-than 10000
#慢查询日志长度。当一个新的命令被写进日志的时候,最老的那个记录会被删掉。这个长度没有限制。只要有足够的内存就行。你可以通过
slowlog-max-len 128
#延迟监控功能是用来监控redis中执行比较缓慢的一些操作,用LATENCY打印redis实例在跑命令时的耗时图表。只记录大于等于下边设置的值的操作。0的话,就是关闭监视。默认延迟监控功能是关闭的,如果你需要打开,也可以通过CONFIG SET命令动态设置。
latency-monitor-threshold 0
#键空间通知使得客户端可以通过订阅频道或模式,来接收那些以某种方式改动了
notify-keyspace-events ""
#数据量小于等于hash-max-ziplist-entries的用ziplist,大于hash-max-ziplist-entries用hash
hash-max-ziplist-entries 512
#value大小小于等于hash-max-ziplist-value的用ziplist,大于hash-max-ziplist-value用hash。
hash-max-ziplist-value 64
#数据量小于等于list-max-ziplist-entries用ziplist,大于list-max-ziplist-entries用list。
list-max-ziplist-entries 512
#value大小小于等于list-max-ziplist-value的用ziplist,大于list-max-ziplist-value用list。
list-max-ziplist-value 64
#数据量小于等于set-max-intset-entries用iniset,大于set-max-intset-entries用set。
set-max-intset-entries 512
#数据量小于等于zset-max-ziplist-entries用ziplist,大于zset-max-ziplist-entries用zset。
zset-max-ziplist-entries 128
#value大小小于等于zset-max-ziplist-value用ziplist,大于zset-max-ziplist-value用zset。
zset-max-ziplist-value 64
#value大小小于等于hll-sparse-max-bytes使用稀疏数据结构(sparse),大于hll-sparse-max-bytes使用稠密的数据结构(dense)。一个比16000大的value是几乎没用的,建议的value大概为3000。如果对CPU要求不高,对空间要求较高的,建议设置到10000左右。
hll-sparse-max-bytes 3000
#Redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用。当你的使用场景中,有非常严格的实时性需要,不能够接受Redis时不时的对请求有2毫秒的延迟的话,把这项配置为no。如果没有这么严格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存。
activerehashing yes
#对于normal client,第一个0表示取消hard limit,第二个0和第三个0表示取消soft limit,normal client默认取消限制,因为如果没有寻问,他们是不会接收数据的。
client-output-buffer-limit normal 0 0 0
#对于slave client和MONITER client,如果client-output-buffer一旦超过256mb,又或者超过64mb持续60秒,那么服务器就会立即断开客户端连接。
client-output-buffer-limit slave 256mb 64mb 60
对于pubsub client,如果client-output-buffer一旦超过32mb,又或者超过8mb持续60秒,那么服务器就会立即断开客户端连接。
client-output-buffer-limit pubsub 32mb 8mb 60
#redis执行任务的频率为1s除以hz。
hz 10
#在aof重写的时候,如果打开了aof-rewrite-incremental-fsync开关,系统会每32MB执行一次fsync。这对于把文件写入磁盘是有帮助的,可以避免过大的延迟峰值。
aof-rewrite-incremental-fsync yes
2、Sentinel工作方式说明:
1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
主观下线和客观下线
主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.
3、复制说明:
Redis 使用的是异步复制, 在执行故障转移期间, 集群可能会丢失写命令。但是在实际上, 丢失命令的情况并不常见, 因为 Redis 几乎是同时执行将命令回复发送给客户端, 以及将命令复制给从节点这两个操作, 所以实际上造成命令丢失的时间窗口是非常小的。
*复制:
注:当完成同步之后,主从服务器就会进入命令传播阶段,主服务器一直将命令发送给从服务器,从服务器一直执行命令即可保证主从一直;在命令传播阶段,从服务器会默认每秒一次的频率向主服务器发送命令:REPLICATION ACK <replication_offset>
三个作用:
1、检测主服务器的连接状态:lag一栏中,一般情况下,lag的值在0或1秒之间跳动,如果超过1秒的话,那么说明主从服务器之间的连接出现了故障。
2、辅助实现min-slaves配置选项:
为保证主从强一致性,有两个参数可进行设置:
min-slaves-to-write 3 表示只有当3个(或以上)的从库连接到主库时,主库才是可写的
min-slaves-max-lag 10 表示允许从库最长失去连接的时间
从服务器连接的数量少于三个,或者三个从服务器的延迟(lag)值都大于或等于10秒时,主服务器将拒绝执行写命令。假设主库与3个从库相连,其中一个从库上一次与主库联系是 9 秒前,这时主库可以正常接受写入,一旦1秒过后这台从库依旧没有活动,则主库则认为目前连接的从库只有2个,从而拒绝写入。
3、检测命令丢失:如果因为网络故障,主库命令没有及时或完整传到从库,主库可根据从库发送REPLICATION ACK命令得到反馈,然后将复制积压缓冲区的数据补发到从库,使主从复制偏移量一致。
*TILT 模式
redis sentinel非常依赖系统时间,例如它会使用系统时间来判断一个PING回复用了多久的时间。
然而,假如系统时间被修改了,或者是系统十分繁忙,或者是进程堵塞了,sentinel可能会出现运行不正常的情况。
当系统的稳定性下降时,TILT模式是sentinel可以进入的一种的保护模式。当进入TILT模式时,sentinel会继续监控工作,但是它不会有任何其他动作,它也不会去回应is-master-down-by-addr这样的命令了,因为它在TILT模式下,检测失效节点的能力已经变得让人不可信任了。