目前可选的方案:
1)sentinel集群 + redis主从
2)redis cluster
两种方案的区别:
1)sentinel集群 + redis主从 主要是可靠性方面考虑。原理比较简单, 通过sentinel集群对redis master进行监控,并在出现问题时进行通知和自动故障迁移。客户端会通过sentinel订阅master地址,当发生切换时,会自动通知客户端
2)redis cluster 主要从可扩展性和可靠性考虑。redis cluster进行分片存储,对key进行CRC16并对slots取余,存储在对应的slot中。客户端缓存slot与nodes的对应关系。
我个人认为两者的架构目标是不同的,第一种方式支持的是众多的小项目,单个redis支持多个db.我曾在网上看到有的公司运行了200多个redis实例,这对维护非常麻烦,个人认为还是改成多个db比较方便。第二种方式支持的是支持超高并发的项目,这时候单个redis的访问已经成为瓶颈,需要进行redis分片来分流压力。redis cluster是不支持多个db的,只支持db0,按照官网的说法,多个不相干项目合并在一个redis实例中不是集群设计的目标,因此没有必要引入这种区分db的复杂性。redis cluster由于实现了分片,因此对scan,keys等命令的支持也比较弱,需要进行一定的改造。
结合目前公司对redis的使用情况,倾向选择第一种解决方案。
一、下载
目前官网最新版是4.0,官网说3.2是一个久经考验的版本,相对来说4.0还不够成熟。那就下个3.2的吧。 下载地址:http://download.redis.io/releases/redis-3.2.11.tar.gz
二、安装
cd /usr/local
tar -zxvf redis-3.2.11.tar.gz
三、配置
cd redis-3.2.11
vi sentinel.conf
port 26379 #后台启动 daemonize yes #记录日志文件 logfile "/var/log/logstash/sentinel.log" #设置远程访问地址 bind 127.0.0.1 192.168.3.10 #监控192.168.3.131 6379的redis主实例,sentinel会自动发现并监控它的从实例。多个监控相同master的sentinel会自动组成集群。 2表示至少两个sentinel实例认为失效才会启动故障迁移 sentinel monitor mymaster 192.168.3.131 6379 2 #设置连接redis master的密码 sentinel auth-pass mymaster 123456 #如果30s没连上,则认为redis实例失效 sentinel down-after-milliseconds mymaster 30000 #如果180s没完成failover,则认为本次failover失败,重新进行failover sentinel failover-timeout mymaster 180000 #在执行故障转移时, 最多可以有多少个从Redis实例在同步新的主实例 sentinel parallel-syncs mymaster 1 #sentinel检测到redis实例异常时,调用报警脚本。该配置项可选,但是很常用。 sentinel notification-script mymaster /usr/local/redis-3.2.11/bin/notify.sh
通知脚本写一句日志,通过filebeat+ELK邮件通知管理员。
mkdir bin
mkdir -p /var/log/logstash
vi /usr/local/redis-3.2.11/bin/notify.sh
echo "master failovered at `date`" > /var/log/logstash/redis_failover.log
chmod 755 ./bin/notify.sh
cd src
make && make install
cp redis-sentinel ../bin
cp redis-cli ../bin
四、启动
cd ../bin
redis-sentinel /usr/local/redis-3.2.11/sentinel.conf
两个警告:
1)Increased maximum number of open files to 10032 (it was originally set to 1024).
解决方法:
echo "ulimit -n 10032" >> /etc/profile
source /etc/profile
(可以通过ulimit -a 查看设置结果)
2)The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
解决方法:
echo "net.core.somaxconn = 512" > /etc/sysctl.conf
sysctl -p
设置开机自启动:
echo "redis-sentinel /usr/local/redis-3.2.11/sentinel.conf" >> /etc/rc.local
五、停止
./redis-cli -p 26379
shutdown
六、操作命令
./redis-cli -p 26379
info sentinel
sentinel masters
sentinel slaves mymaster
sentinel get-master-addr-by-name mymaster
sentinel reset
sentinel failover
七、集群
因为投票机制至少需要3台sentinel, 所以在另外两台机器重复以上操作。
八、注意问题:
1. 如果redis服务设置了密码,那么master的redis.conf也要设置 masterauth "123456", 否则当主从切换之后,从节点连不上主节点
2. 集群运行几天之后,突然发现测试环境
master0:name=mymaster,status=sdown,address=192.168.3.131:6379,slaves=0,sentinels=1
sdown是说明主观下线了,sentinels=1是说明找不到其他的sentinel了,所以没有达到最少2票的选举要求,sdown不会变成odown. slaves=0说明没有发现redis slave. 貌似是发现机制出问题了。
检查配置:
protected-mode yes bind 192.168.3.18 127.0.0.1
好像也没有问题。查了很久,抱着试试看态度改成:
protected-mode no bind 0.0.0.0
重启sentinel节点就好了。
master0:name=mymaster,status=ok,address=192.168.3.131:6379,slaves=1,sentinels=3