Redis主从+哨兵环境搭建

字数 2598阅读 93

架构

OS:Centos6.8

Redis01:172.17.100.130(sentinel-1,sentinel-2)

Redis02:172.17.100.131(sentinel-3)

前置条件

yum install -y gcc openssl libtool

部署Redis(主库)

wget http://download.redis.io/releases/redis-4.0.11.tar.gz

tar -xf redis-4.0.11.tar.gz

cd redis-4.0.11

make

mkdir -p /opt/redis/sbin

mkdir -p /opt/redis/bin –p

mkdir -p /data/redis/redis6379/

cp redis.conf /data/redis/redis6379/6379.conf

cd src

cp redis-se* /opt/redis/sbin/

cp redis-check-aof /opt/redis/bin/

cp redis-cli /opt/redis/bin/

echo "export PATH=\$PATH:/opt/redis/sbin/:/opt/redis/bin/" >> /etc/profile

source /etc/profile


#这样操作之后redis只是有一些基本的功能,如果想做测试的话,将无法完成,如果想拥有全部的功能,可以执行下面的操作

#cd redis-4.0.11

#cp -r src /opt/redis/

#建议将redis-4.0.11文件夹改名保存


#编辑配置参数

mv /data/redis/redis6379/6379.conf /data/redis/redis6379/redis_conf.bak

vim /data/redis/redis6379/6379.conf


#是否在后台运行

daemonize yes

#pid文件路径

pidfile "/var/run/redis.pid"

#端口

port 6379

#密码

requirepass "password"

#主(从)节点密码

masterauth "password"

#

tcp-backlog 511

#客户端连接超时时间

timeout 0

#

tcp-keepalive 0

#log等级,生产环境建议notice

loglevel notice

#logfile路径

logfile "/data/redis/6379.log"

#数据库个数

databases 16

#redis进行数据库镜像的频率

#900秒内有1个key发生变化时(进行备份)

save 900 1

#300秒内有10个key发生变化时(进行备份)

save 300 10

#10000秒内有60个key发生变化时(进行备份)

save 60 10000

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename "6379.rdb"

#redis路径

dir "/data/redis/redis6379"

slave-serve-stale-data yes

#从库只读

slave-read-only yes

repl-disable-tcp-nodelay no

slave-priority 100

#最大同时连接数

maxclients 10000

#redis能够使用的最大内存,当内存满了后,如果还收到set命令,redis将剔除设置过expire信息的key

maxmemory 1G

#最大内存淘汰策略

#volatile-lru:从已设置过期时间的内存数据集中挑选最近最少使用的数据 淘汰

#volatile-ttl: 从已设置过期时间的内存数据集中挑选即将过期的数据 淘汰

#volatile-random:从已设置过期时间的内存数据集中任意挑选数据 淘汰

#allkeys-lru:从内存数据集中挑选最近最少使用的数据 淘汰

#allkeys-random:从数据集中任意挑选数据 淘汰

#no-enviction(驱逐):禁止驱逐数据(默认)

maxmemory-policy volatile-lru

#开启appendonly后,redis会把接收到的每一次写操作都追加到appendonly.aof文件中

appendonly yes

#appendonly.aof的名字

appendfilename "6379.aof"

#同步频率,对写操作进行累积,每秒同步一次

appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

lua-time-limit 5000

slowlog-log-slower-than 10000

slowlog-max-len 128

latency-monitor-threshold 0

notify-keyspace-events ""

hash-max-ziplist-entries 512

hash-max-ziplist-value 64

list-max-ziplist-entries 512

list-max-ziplist-value 64

set-max-intset-entries 512

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

hll-sparse-max-bytes 3000

activerehashing yes

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

hz 10

aof-rewrite-incremental-fsync yes

#从库不需要密码就能访问

#protected-mode no

#redis-server只接收来自该IP的请求

bind 0.0.0.0

#bind 127.0.0.1

# Generated by CONFIG REWRITE


#当redis运行后(特别是主从),conf文件也会被修改,因此对初始文件进行备份

cp 6379.conf 6379.conf.bak

系统参数配置

sed -i -r '/vm.overcommit_memory*/d' /etc/sysctl.conf

sed -i -r '/vm.swappiness*/d' /etc/sysctl.conf

echo "vm.overcommit_memory =1">>/etc/sysctl.conf

echo "vm.swappiness = 1" >>/etc/sysctl.conf

/sbin/sysctl -q -p /etc/sysctl.conf

sed -i -r '/redis soft nofile.*/d' /etc/security/limits.conf

sed -i -r '/redis hard nofile.*/d' /etc/security/limits.conf

echo "redis soft nofile 288000" >>/etc/security/limits.conf

echo "redis hard nofile 288000" >>/etc/security/limits.conf

sed -i -r '/redis soft nproc.*/d' /etc/security/limits.conf

sed -i -r '/redis hard nproc.*/d' /etc/security/limits.conf

echo "redis soft nproc unlimited">>/etc/security/limits.conf

echo "redis hard nproc unlimited">>/etc/security/limits.conf

#(单机验证)启动

redis-server /data/redis/redis6379/6379.conf

#关闭

redis-cli shutdown

Redis从库部署

安装方式和主库一致,主要修改conf

wget http://download.redis.io/releases/redis-4.0.11.tar.gz

tar -xf redis-4.0.11.tar.gz

cd redis-4.0.11

make

mkdir -p /opt/redis/sbin

mkdir -p /opt/redis/bin –p

mkdir -p /data/redis/redis6380/

cp redis.conf /data/redis/redis6380/6380.conf

cd src

cp redis-se* /opt/redis/sbin/

cp redis-check-aof /opt/redis/bin/

cp redis-cli /opt/redis/bin/

echo "export PATH=\$PATH:/opt/redis/sbin/:/opt/redis/bin/" >> /etc/profile

source /etc/profile

修改系统参数

sed -i -r '/vm.overcommit_memory*/d' /etc/sysctl.conf

sed -i -r '/vm.swappiness*/d' /etc/sysctl.conf

echo "vm.overcommit_memory =1">>/etc/sysctl.conf

echo "vm.swappiness = 1" >>/etc/sysctl.conf

/sbin/sysctl -q -p /etc/sysctl.conf

sed -i -r '/redis soft nofile.*/d' /etc/security/limits.conf

sed -i -r '/redis hard nofile.*/d' /etc/security/limits.conf

echo "redis soft nofile 288000" >>/etc/security/limits.conf

echo "redis hard nofile 288000" >>/etc/security/limits.conf

sed -i -r '/redis soft nproc.*/d' /etc/security/limits.conf

sed -i -r '/redis hard nproc.*/d' /etc/security/limits.conf

echo "redis soft nproc unlimited">>/etc/security/limits.conf

echo "redis hard nproc unlimited">>/etc/security/limits.conf

#把主库的6379.conf传输到从库节点上,并修改名字为6380.conf

scp  172.17.100.130:/data/redis/redis6379/6379.conf /data/redis/redis6380/6380.conf

cd /data/redis/redis6380/

sed -i 's/6379/6380/g' 6380.conf

#搭建主从,除了修改端口以外,主要是增加下面这句slaveof

echo “slaveof 172.17.100.130 6379” >> 6380.conf


#主从的验证

登录从库

info replication

master_link_status为up即显示主从同步状态正常


PS:

如果测试环境不想配置密码,那么在主从的配置文件里要开启这个protected-mode no

在此次实验中,我们在配置里面写入了密码,所以要注释掉配置protected-mode no这句


                                  至此主从redis配置完成


防火墙设置

主库

iptables -I INPUT -p tcp --dport 6379 -j ACCEPT

iptables -I INPUT -p tcp --dport 16379 -j ACCEPT

iptables -I INPUT -p tcp --dport 26379 -j ACCEPT

service iptables save

从库

iptables -I INPUT -p tcp --dport 6380 -j ACCEPT

iptables -I INPUT -p tcp --dport 26380 -j ACCEPT

service iptables save


测试主从是否能配置成功

#首先开启主库

redis-server /data/redis/redis6379/6379.conf

#然后开启从库

redis-server /data/redis/redis6380/6380.conf

#登陆主库,进行一波操作

redis-cli -p 6379

keys *

set cnvex 'mysql-dba'

get cnvex

结果显示:"mysql-dba"

到从库上查看

redis-cli -p 6380

get cnvex

结果显示:"mysql-dba"

证明主库的数据已经传到从库上,主从配置成功



哨兵的配置

主库

mkdir -p /data/redis/{sentinel-1,sentinel-2}

cd /data/redis

vim sentinel.conf


daemonize yes

#bind 0.0.0.0

port 16379

dir "/data/redis/sentinel-1"

loglevel notice

logfile "/data/redis/sentinel-1.log"

#sentinel monitor mymaster 172.17.100.130 6379 2

sentinel monitor mymaster 172.17.100.130 6379 1

#配置mymaster的密码

sentinel auth-pass mymaster beacon

#5秒中mymaster没反应,则认为mymaster宕机

sentinel down-after-milliseconds mymaster 5000

#mymaster超过10秒仍然为宕机状态,则执行failover

sentinel failover-timeout mymaster 10000

#这个参数必须写,不写会影响failover

protected-mode no

#执行故障转移时,最多有多少个从服务器同时对新的主服务器进行同步

#sentinel config-epoch mymaster 1


由于哨兵启动后,conf文件也会被修改,所以建议对原始文件进行备份

此次实验,sentinel.conf就是我的原始文件

将其拷贝成sentinel-1.conf、sentinel-2.conf、sentinel-3.conf并修改文件中响应的字段进行匹配(主要是改端口,log名等等)

1和2放在主库130上,3放到从库131上,分别启动即完成了本次哨兵的搭建


启动哨兵

在主从库上分别启动哨兵

redis-sentinel /data/redis/sentinel-1.conf

redis-sentinel /data/redis/sentinel-2.conf

redis-sentinel /data/redis/sentinel-3.conf


关于conf和log

redis的conf

此次设定的是6379为主库,6380为从库;

正常启动情况下,6379.conf和6380.conf里面的内容不会有不同

但是在发生failover的情况下,原本出现在6380.conf里面的 “slaveof 172.17.100.130 6379”  会消失

而6379.conf最底下会出现 “slaveof 172.17.100.131 6380”

简言之,从库的conf下会自动出现slaveof语句


sentinel的conf

发2张图对比一下从库sentinel.conf前后的变化

图1为原始conf

图2为启动之后的conf

配置中列出了该sentinel的myid,当前的epoch值,以及除自己之外的其他几个哨兵(以及他们的myid)

关于epoch,哨兵启动后都会同步同一个epoch值,当发生切换(成功/失败)时,epoch值+1,如果一直切换失败,这个epoch值会不停的增长(如下图)


sentinel自动切换实验

主库

ps -ef|grep redis,kill掉redis-server对应的进程号


查看哨兵的log可以发现哨兵集群首先在kill掉主进程大约5秒钟之后将状态改为odown

生成新的epoch 17

开始选举投票,并执行一系列的failover准备

在51秒553完成切换,将主库由130 switch-master到131上

在56秒579的时候,将130变更为131的从库

从库这边的log如下

在主库上,重新拉起redis-server

log显示sentinel在第一时间判定130的redis-server为-sdown,之后将其连接为131的从库

此时的6379.conf末尾已经写入了slaveof信息

131并不会将主库还给130,而是自己继续做主库

将131的redis-server杀掉

上面的情况又会再次复现,130重新成为主库


实验中遇到的问题


问题1

主要是哨兵配置中的那个

protected-mode no

不一定必须配置成no,但是这个参数一定要配置

我试过注释掉这个参数,会发生无法切换的问题


问题2

之前在网上爬文,看到某些文章在下图里面配置数不为1,大概意思是需要多个哨兵统一,才会发生切换,但实际中我有3个哨兵,配置成1就能很好的完成切换任务,反而是配置成2之后,会遇到切换的问题

目前此处没有深究2者的差异,后续再来填坑

zhi