相信大家通过阅读博文:非关系型数据库(NoSQL)——Redis安装及部署详解
可以初步的认识Redis数据库的优势及其安装方法,今天我们来认识一下Redis数据库怎么横向扩展,以满足更大的访问需求。
Redis 3.0版本以上开始支持cluster,采用的是hash slot(hash 槽),可以将多个Redis实例整个在一起,形成一个群集,也就是将数据分散到群集的多个机器上。
Redis群集原理
Redis Cluster是一个无中心的结构,每个节点都保存数据和整个群集的状态。每个节点都会保存其他节点的信息,知道其他节点锁负责的槽,并且会与其他节点定时发送心跳信息,能够及时感知群集中异常的节点。如图:
当客户端向群集中任一节点发送与数据库键有关的命令是,接受命令的节点会计算出命令要处理的数据库键属于哪个槽,并检查这个槽是否指派给了自己。如果键所在的槽正好指派给了当前节点,那么节点直接执行这个命令;如果键所在的槽并没有指派给当前节点,那么节点会向客户端返回一个MOVED错误,指引客户端转向正确的节点,并再次发送之前想要执行的命令。
群集角色有Master和Slave。Master之间分配slots,一共有16384个slot。Slave向它指定的Master同步数据,实现备份。当其中一个Master无法提供服务时,该Master的Slave将提升为Master。以保证群集键slot的完整性。当其中的某一个Master和它的Slave都失效,就会导致slot不完整,群集失效,这是就需要人工参与修复。
群集搭建好后,群集中的每个节点都会定期地想其他节点发送PING消息,如果接收PING消息的节点没有在规定的时间内返回PONG消息,那么发送PING消息的节点就会将其标记为疑似下线(PFAIL)。各个节点会通过互相发送消息的方式来交换群集中各个节点的状态信息。如果在一个群集里,半数以上的主节点都将某个节点 X 报告为疑似下线,那么这个主节点 X 将被标记为已下线(FAIL),同时会向群集广播一条关于主节点 X 的FAIL消息,所有收到这条FAIL消息的节点都会立即将主节点 X 标记为已下线。
当需要减少或增加群集中的机器时,我们需要将已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且将相关槽所属的键值对从源节点移动到目标节点。
Redis群集的重新分片操作是由Redis的群集管理软件redis-trib负责执行的,不支持自动的分片,而且需要自己计算从哪些节点上迁移多少Slot。在重新分片的过程中,群集不需要下线,并且源节点和目标节点都可以继续处理命令请求。
架构细节
1.所有的redis节点彼此互联,内部使用二进制协议优化传输速度和带宽;
2.节点的失效在群集中超过半数的主节点检测失效才失效;
3.客户端与redis节点直连,不需要中间代理层,客户端不需要连接群集所有节点,连接群集中任何一个可用节点即可;
4.redis-cluster把所有的物理节点映射到【0-16383】slot上,cluster 负责维护node<->slot<->key;
Redis-cluster选举:
选举过程是群集中所有master参与,如果半数以上master节点与当前master节点通信超时,认为当前master节点挂掉。如图:
以下两种情况出现则为群集不可用:
- 如果群集任意master挂掉,且当前master没有slave,则群集进入fail状态,也可以理解为群集的slot映射【0-16383】不完整时进入的fail状态;
- 如果群集中出现半数的master挂掉,无论是否有slave,群集都进入fail状态;
当群集不可用时,所有对群集的操作都不可用,收到((error)CLUSTERDOWN The cluster is down)错误。
默认情况下,每个群集的节点都使用两个TCP端口,一个是6379,一个是16379:
- 6379端口服务于客户端的连接;
- 16379端口用于群集总线;
即使用二进制协议的节点到节点通信通道。节点使用群集总线进行故障检测,配置更新、故障转移授权等。如果开启了防火墙,需要开放这个端口(本次博文采用强制关闭防火墙)。
Redis群集部署
理解了Redis群集原理之后,搭建redis群集就变得非常简单了。本次实验采用6台服务器搭建Redis群集,其中3台为master,3台为salve。6台服务器的IP地址为192.168.1.1/24——192.168.1.6/24,服务器均为centos 7系统。这里就不上传实验拓补图了。
Redis群集部署的具体操作步骤主要分为:
1.安装Redis并修改配置文件
关于如何搭建Redis服务器及其软件包获取方式均可参考博文:非关系型数据库(NoSQL)——Redis安装及部署详解
按照博文安装即可,6台服务器都需安装Redis,安装完成之后每台服务器都需要修改为本机真实的IP地址,取消回环地址(127.0.0.1),具体修改内容如下:
[root@localhost ~]# vim /etc/redis/6379.conf
bind 192.168.1.1 //改为本机的真是IP地址
daemonize yes
logfile /var/log/redis_6379.log
cluster-enabled yes //启用群集
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
cluster-require-full-coverage no
//关于群集这几条默认是存在,只不过注释了,取消注释即可!
[root@localhost ~]# /etc/init.d/redis_6379 restart
//重启redis服务
Stopping ...
Redis stopped
Starting Redis server...
[root@localhost ~]# netstat -anpt | grep 6379
tcp 0 0 192.168.1.1:6379 0.0.0.0:* LISTEN 6497/redis-server 1
tcp 0 0 192.168.1.1:16379 0.0.0.0:* LISTEN 6497/redis-server 1
tcp 0 0 127.0.0.1:6379 127.0.0.1:43304 TIME_WAIT -
//6379端口和16379端口都在监听
第一个redis服务器已经搭建完毕,剩下5个一样的做法,只是配置文件中都是自身的IP地址,别弄混了!
2.使用脚本创建群集
创建群集要用到ruby的一个脚本,在创建群集之前,需要先安装ruby的运行环境和ruby的Redis客户端,该操作在其中一台服务器进行即可。gem命令是提前下载的redis-3.2.0 gem软件包提供的,直接上传服务器即可使用!
gem软件包网盘链接:https://pan.baidu.com/s/1Fx7YI-ZwZoHOPm13HYeFKw
提取码:cj0x
[root@localhost ~]# yum -y install ruby rubygems
//安装ruby的运行环境
[root@localhost ~]# gem install redis --version 3.2.0
Successfully installed redis-3.2.0
Parsing documentation for redis-3.2.0
Installing ri documentation for redis-3.2.0
1 gem installed
//安装ruby的Redis客户端工具——gem命令
使用脚本创建群集:
[root@localhost ~]# cd /usr/src/redis-3.2.9/src
[root@localhost src]# ./redis-trib.rb create --replicas 1 192.168.1.1:6379 192.168.1.2:6379 192.168.1.3:6379 192.168.1.4:6379 192.168.1.5:6379 192.168.1.6:6379
………… //省略部分内容
Can I set the above configuration? (type 'yes' to accept): yes
………… //省略部分内容
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
//创建群集完成
[root@localhost src]# ./redis-trib.rb check 192.168.1.1:6379
//查看群集状态(可以清楚的看到哪台主机是master、哪台主机时salve)
>>> Performing Cluster Check (using node 192.168.1.1:6379)
M: afb2a0876b9c4c1c19e2bc492e398765bed0a311 192.168.1.1:6379
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 00ed4b0da4f0444c7e2a54a44c2060dd2c51a19a 192.168.1.4:6379
slots: (0 slots) slave
replicates afb2a0876b9c4c1c19e2bc492e398765bed0a311
S: 081d87a0d26895605e4c237c5429d3ae6e01f7b2 192.168.1.5:6379
slots: (0 slots) slave
replicates 050d71e6ad9bbf0a2a90b743d5a9bb9fb77052bb
S: 00bf8cb3a48a696d9bfc4b124234335633dc14d0 192.168.1.6:6379
slots: (0 slots) slave
replicates bec4c3401ced5a43439568f5530d79dd2a911512
M: 050d71e6ad9bbf0a2a90b743d5a9bb9fb77052bb 192.168.1.2:6379
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: bec4c3401ced5a43439568f5530d79dd2a911512 192.168.1.3:6379
slots:10923-16383 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
3.测试群集
登录群集,设置键值测试,需要用到“-c”参数来激活群集,具体操作如下:
[root@localhost ~]# redis-cli -h 192.168.1.1 -p 6379 -c
192.168.1.1:6379> set k1 1
-> Redirected to slot [12706] located at 192.168.1.3:6379
OK
192.168.1.3:6379> get k1
"1"
数据自动同步其redis服务器上,查看效果:
[root@localhost ~]# redis-cli -h 192.168.1.5 -p 6379 -c
192.168.1.5:6379> get k1
-> Redirected to slot [12706] located at 192.168.1.3:6379
"1"
//提示是从192.168.1.3服务器上同步过来的
实验完成!!!
———————— 本文至此结束,感谢阅读 ————————