redis哨兵
Redis-Sentinel
1、Redis-Sentinel
Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能。而redis-sentinel就是一个独立运行的进程,用于监控多个master-slave集群,自动发现master宕机,进行自动切换slave > master。
Sentinel(哨兵、岗哨)主要功能如下:
- 不时的监控redis是否良好运行,如果节点不可达就会对节点进行下线标识;
- 如果被标识的是主节点,sentinel就会和其他的sentinel节点“协商”,如果其他节点也认为主节点不可达,就会选举一个sentinel节点来完成自动故障转义;
- 在master-slave进行切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换;
简而言之,Redis哨兵就是保护redis主从集群正常运转,当主库挂掉之后,自动地在从库中挑选新的主库,进行同步。
2、主从复制背景问题
Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:
一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。
扩展主节点的读能力,分担主节点读压力。
但是问题是:一旦主节点宕机,从节点上位,那么需要人为修改所有应用方的主节点地址(改为新的master地址),还需要命令所有从节点复制新的主节点。
这个问题,redis-sentinel可以解决。
3、主从复制架构
4、Redis-Sentinel架构
Sentinel是redis的一个进程,但是不存储数据,只是监控redis。
Sentinel会通过命令连接向被监视的主从服务器发送“HELLO”信息,该消息包含Sentinel的IP、端口号、ID等内容,以此来向其他Sentinel宣告自己的存在。与此同时,Sentinel会通过订阅连接接收其他Sentinel的“HELLO”信息,以此来发现监视同一个主从服务器的其他Sentinel。
sentinel1通过发送HELLO信息来让sentinel2和sentinel3发现自己,其他两个sentinel也会进行类似的操作,如下图:
1)多个sentinel发现并确认master有问题;
2)选举出一个sentinel作为领导;
3)选出一个slave作为master;
4)通知其余slave成为新的master的slave;
5)通知客户端主从变化;
6)等待老的master复活成为新master的slave;
Sentinel也可以同时监控多个主从架构,如下图:
5、redis-sentinel(哨兵)的配置
第一步:准备三个redis数据库实例(三个配置文件,通过端口区分)
1
2
3
|
[root@localhost redis - 4.0 . 10 ] # redis-server redis-6380.conf [root@localhost redis - 4.0 . 10 ] # redis-server redis-6381.conf [root@localhost redis - 4.0 . 10 ] # redis-server redis-6382.conf |
主从规划:主库6380,从库6381、6382
第二步:准备三个哨兵的配置文件redis-sentinel-26380.conf(也是通过端口区分)
[root@localhost redis-4.0.10]# vi redis-sentinel-26380.conf 编辑配置文件,内容如下 port 26380 dir /var/redis/data/ logfile "26380.log" # 当前Sentinel节点监控 127.0.0.1:6380 这个主节点 # 2代表判断主节点失败至少需要2个Sentinel节点同意 # s15master是主节点的别名 sentinel monitor s15master 127.0.0.1 6380 2 # 每个Sentinel节点都要定期用PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30s且没有回复,则判定不可达 sentinel down-after-milliseconds s15master 30000 sentinel parallel-syncs s15master 1 # 故障转移超时时间为180秒 sentinel failover-timeout s15master 180000 daemonize yes
三个配置文件内容仅仅是port(端口)参数不同,其他都一样,因此按照如下方式快速生成其他两个:
1
2
|
sed "s/26380/26381/g" redis - sentinel - 26380.conf > redis - sentinel - 26381.conf sed "s/26380/26382/g" redis - sentinel - 26380.conf > redis - sentinel - 26382.conf |
第三步:启动三个哨兵
1
2
3
|
[root@localhost redis - 4.0 . 10 ] # redis-sentinel redis-sentinel-26380.conf [root@localhost redis - 4.0 . 10 ] # redis-sentinel redis-sentinel-26381.conf [root@localhost redis - 4.0 . 10 ] # redis-sentinel redis-sentinel-26382.conf |
启动后查看哨兵配置文件是否发生改变,以redis-sentinel-26380.conf为例,变化如下图:
第四步:检查哨兵的通信状态
1
|
[root@localhost redis - 4.0 . 10 ] # redis-cli -p 26380 info sentinel |
6、redis哨兵高可用故障实验
情况一:杀掉redis主节点的进程6380端口,观察从节点是否会进行新的master选举,进行切换
情况二:重新开启旧的“master”节点进程6380端口,查看此时它的身份
总结:哨兵也是通过更改redis的配置文件,来切换主从身份。.
redis-cluster
为什么要用redis-cluster?
- 并发问题:redis官方声称可以达到 10万/每秒(每秒执行10万条命令),假如业务需要每秒100万的命令执行呢?
- 数据量太大:一台服务器内存正常是16~256G,假如你的业务需要500G内存,你怎么办?配置一个超级牛逼的计算机,超大内存,超强cpu并不是一个好办法,正确的应该是考虑分布式,加机器,把数据分到不同的位置,分摊集中式的压力,一堆机器做一件事。
redis实例集群主要思想是将redis数据的key进行散列,通过hash函数特定的key会映射到指定的redis节点上。
1、数据分布理论
分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。
常见的分区规则有哈希分区和顺序分区。Redis-cluster采用哈希分区规则,因此接下来会讨论哈希分区规则:
- 节点取余分区;
- 一致性哈希分区;
- 虚拟槽分区(redis-cluster采用的方式);
2、虚拟槽分区
Redis Cluster采用虚拟槽分区,虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。
Redis Cluster槽的范围是0 ~ 16383。
槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,每个节点负责一定数量的槽。
3、搭建redis集群(redis cluster)
redis支持多实例的功能,我们在单机演示集群搭建,需要6个实例,三个是主节点,三个是从节点,数量为6个节点才能保证高可用的集群。
第一步:准备6个redis数据库实例,配置文件为redis-{7000...7005}.conf
[root@localhost redis-4.0.10]# mkdir myrediscluster 创建一个目录存放配置文件 [root@localhost myrediscluster]# vi redis-7000.conf 编辑配置文件,写入如下内容 port 7000 daemonize yes dir "/opt/redis/data" logfile "7000.log" dbfilename "dump-7000.rdb" cluster-enabled yes # 开启集群模式 cluster-config-file nodes-7000.conf # 集群内部的配置文件 # redis cluster需要16384个slot都正常的时候才能对外提供服务,换句话说,只要任何一个slot异常那么整个cluster不对外提供服务,因此生产环境一般为no cluster-require-full-coverage no
快速生成其他5个配置文件:
1
2
3
4
5
|
[root@localhost myrediscluster] # sed "s/7000/7001/g" redis-7000.conf > redis-7001.conf [root@localhost myrediscluster] # sed "s/7000/7002/g" redis-7000.conf > redis-7002.conf [root@localhost myrediscluster] # sed "s/7000/7003/g" redis-7000.conf > redis-7003.conf [root@localhost myrediscluster] # sed "s/7000/7004/g" redis-7000.conf > redis-7004.conf [root@localhost myrediscluster] # sed "s/7000/7005/g" redis-7000.conf > redis-7005.conf |
第二步:启动这6个redis数据库实例
1
2
3
4
5
6
|
[root@localhost myrediscluster] # redis-server redis-7000.conf [root@localhost myrediscluster] # redis-server redis-7001.conf [root@localhost myrediscluster] # redis-server redis-7002.conf [root@localhost myrediscluster] # redis-server redis-7003.conf [root@localhost myrediscluster] # redis-server redis-7004.conf [root@localhost myrediscluster] # redis-server redis-7005.conf |
第三步:配置ruby语言环境,脚本一键启动redis-cluster
1)下载ruby语言的源码包,解压缩
1
2
|
wget https: / / cache.ruby - lang.org / pub / ruby / 2.3 / ruby - 2.3 . 1.tar .gz tar - zxvf ruby - 2.3 . 1.tar .gz |
2)配置,编译且安装
1
2
|
. / configure - - prefix = / opt / ruby / 释放makefile make && make install 编译且安装 |
查看ruby安装目录下的bin目录,有如下文件:
3)下载ruby操作redis的模块包
1
|
[root@localhost opt] # wget http://rubygems.org/downloads/redis-3.3.0.gem |
4)配置ruby环境变量
[root@localhost ~]# echo $PATH [root@localhost ~]# vim /etc/profile 编辑配置文件profile,写入下面一行代码 PATH=$PATH:/opt/ruby/bin/ [root@localhost ~]# source /etc/profile 读取文件,使配置生效
5)通过ruby的包管理工具gem去安装redis包,安装后会生成一个redis-trib.rb这个命令
1
|
gem install - l redis - 3.3 . 0.gem |
第三步:一键开启redis-cluster, 其实就是分配主从关系 以及 槽位分配 slot槽位分配
1
|
/ opt / redis - 4.0 . 10 / src / redis - trib.rb create - - replicas 1 127.0 . 0.1 : 7000 127.0 . 0.1 : 7001 127.0 . 0.1 : 7002 127.0 . 0.1 : 7003 127.0 . 0.1 : 7004 127.0 . 0.1 : 7005 |
执行后如下图:
第四步:检查各节点主从状态
1
2
3
4
5
6
|
[root@localhost opt] # redis-cli -p 7000 info replication [root@localhost opt] # redis-cli -p 7001 info replication [root@localhost opt] # redis-cli -p 7002 info replication [root@localhost opt] # redis-cli -p 7003 info replication [root@localhost opt] # redis-cli -p 7004 info replication [root@localhost opt] # redis-cli -p 7005 info replication |
第五步:向redis集群写入数据,查看数据流向
1
2
|
[root@localhost opt] # redis-cli -p 7000 -c 参数-c代表集群模式 127.0 . 0.1 : 7000 > set name tom 写入数据 |
结果如下图:
总结:写入数据时会将key自动的重定向,放到某一个节点的slot槽位中。