本文咱们来了解Redis的Cluster集群与分片,Cluster集群的三主三从服务器的搭建,最后面还会与SpringBoot整合的内容。
「什么是Cluster集群」
在上一章主要是使用Sentinel解决主从架构的故障自动迁移的问题,但还是会因为Master主节点的写能力和存储能力还是会被限制。使用Cluster集群就是为了解决单机Redis容量有限的问题,将数据按照一定的规则分配到多台机器。Cluster集群是一组相互之间独立的、通过网络互联的计算机,计算机与计算机之间构成了一个组,并以单一系统的模式管理。
分布式和集群的区别:分布式就是把一个系统进行拆分成多个小系统,每个小系统只负责自己的服务。集群就是把一个业务可以多个系统负责。
例如:用户去银行存钱,Anna小姐姐是窗台1的工作人员,工作内容有开户、存钱、挂失等等。Anna业务工作内容太多导致效率低下,所有银行就聘请多几个人来负责不同的事情,让客户根据需要来进行选择,这就是分布式。老王的工作内容是对客户存钱的,但是只有一个窗口,导致排很长的队,这时可以开多几个窗口来同时对客户进行服务,这就是集群。一般来说分布式和集群是配合在一起使用的。
「Redis集群模式的介绍」
Cluster模式是Redis3.0开始推出的,Cluster是用无中心的结构,每个节点里保存的数据和整改集群状态,每个节点都和其他的节点连接。在官网要求是要六个节点才可以保证高可用,即三主三从,扩展性强、更好做到高可用。在Cluster中每个节点之间都会相互通信比如Master1都会与Slave1、Slave2、Slave3进行通信,采用的是gossip协议进行交换节点元数据信息。数据分散的存储到各个节点之中。
「Cluster数据分片和虚拟哈希槽」
需求分析
在Redis中,主节点的写能力和读的能力有限,单台机器没有办法满足实际需求,因此需要把数据分散到各个机器上,类似于数据库的分库分表。
下图所示,Redis可以根据所定义的规则来决定该记录存储到那个区,再后面可以根据规则去区里拿数据。
「常见的数据分区算法」
哈希取模:对选择的partitioning key 计算它的哈希值,在根据得出的哈希值来分配存储区域。
范围分片:通过确定分区键是否在范围内来进行分区,比如存储区一分区键为1-1000,那么1-1000的数据就存储在区一。
一致性Hash分区:Redis的Cluster集群没有采用一致性的哈希方案,它是采用**「数据分片」**中的哈希槽来对数据进行存储与读取的。
「什么是Redis的哈希槽」
Redis集群会预先分好16384个桶,当需要在Redis集群中放置一个key-value时,根据CRC16(key)mod算法得到相对应的值,再决定将这个key放在那个桶中。
哈希槽大体流程
假设主节点的数量为3,将Redis集群的16384个槽位按照**「用户定义的规则」**来去分配这3个节点,每个主节点复制一份槽位。
节点1槽位范围:0-5460
节点2槽位范围:5461-10922
节点3槽位范围:10923-16383
注意:从节点是没有槽位的,只有主节点才有
存储查找
对要存储查找的键进行CRC16哈希运算,得到一个值,并取模16384,判断这个值在那个节点范围内
假如CRC16("test_key")%16384=3000,根据值来判断存储在节点一
CRC16算法是一种校验算法
使用哈希槽的好处就在于可以方便的添加或移除节点,当需要添加节点时,只需要把其他节点的某些哈希槽范围缩小,在把剩余的哈希槽给新的节点。比如存储区三,原本是10923-16383,这时设置为10923-13000,那剩下的13001-16383就给新的节点了。删除节点也是如此,只需要把移除节点的哈希槽挪到哈希槽的其他节点就可以了。
「Cluster集群环境准备」
在这里首先说明一下,旧版本的Redis需要使用ruby语言进行构建,新版5+直接用Redis-cli即可,六个节点,三主三从,主从节点会自动分配,不是人工指定的。主节点故障后,从节点会替换成主节点。
节点有:6381、6382、6383、6384、6385、6386,那个节点是主、从我们不知道因为是自动分配的(网络安全组记得打开)。
搭建集群之前需要删除的:如果之前有开启上一章的哨兵进程记得停掉和/user/local/redis/data/目录下持久化相关文件记得删除,还有log目录下的日志文件记得删除
在conf目录下创建cluster目录,该目录下分别创建redis1.conf-redis6.conf配置,编辑redis1.conf,配置信息如下,redis2.conf和后面的也是如下配置,注意需要修改相关的信息(端口port、日志文件logfile、appendfilename、cluster-config-file、cluster-announce-port、cluster-announce-bus-port)
bind 0.0.0.0
port 6381
daemonize yes
requirepass "123456"
logfile "/usr/local/redis/log/redis1.log"
dbfilename "xdclass1.rdb"
dir "/usr/local/redis/data"
appendonly yes
appendfilename "appendonly1.aof"
masterauth "123456"
#是否开启集群
cluster-enabled yes
# ⽣成的node⽂件,记录集群节点信息,默认为nodes.conf,防⽌冲突,改为nodes-6381.conf
cluster-config-file nodes-6381.conf
#节点连接超时时间
cluster-node-timeout 20000
#集群节点的ip,当前节点的ip
cluster-announce-ip 172.18.172.109
#集群节点映射端⼝
cluster-announce-port 6381
#集群节点总线端⼝,节点之间互相通信,常规端⼝+1万
cluster-announce-bus-port 16381
复制代码
bind 0.0.0.0
port 6386
daemonize yes
requirepass "123456"
logfile "/usr/local/redis/log/redis6.log"
dbfilename "xdclass6.rdb"
dir "/usr/local/redis/data"
appendonly yes
appendfilename "appendonly6.aof"
masterauth "123456"
cluster-enabled yes
cluster-config-file nodes-6386.conf
cluster-node-timeout 20000
cluster-announce-ip 172.18.172.109
cluster-announce-port 6386
cluster-announce-bus-port 16386
复制代码
上面把相关配置都搞定之后,接着我们就可以实战Cluster集群了。
启动六个节点
./redis-server ../conf/cluster/redis1.conf
./redis-server ../conf/cluster/redis2.conf
./redis-server ../conf/cluster/redis3.conf
./redis-server ../conf/cluster/redis4.conf
./redis-server ../conf/cluster/redis5.conf
./redis-server ../conf/cluster/redis6.conf
复制代码
加入集群 --cluster表示构建集群全部节点的信息 --cluster-replicas 1 主从节点的比例,1表示1主1从
./redis-cli -a 123456 --cluster create 172.18.172.109:6381 172.18.172.109:6382 172.18.172.109:6383 172.18.172.109:6384 172.18.172.109:6385 172.18.172.109:6386 --cluster-replicas 1
复制代码
检查状态信息(其中一个节点执行即可)
./redis-cli -a 123456 --cluster check 172.18.172.109:6381
复制代码
命令成功后会自动分配槽位
「Cluster集群命令的读写命令实战」
上面我们已经把Redis的集群已经搭建好了,下面我们开始测试一下Cluster集群的读写
# -c是以集群的模式开启
./redis-cli -c -a 123456 -p 6381
#集群信息
cluster info
#节点信息
cluster nodes
复制代码
测试集群命令set / get,当使用set命令添加一个Key时,发现该key通过计算过后自动分配到那个哈希槽中,get则会计算该值,并在相对应的哈希槽中取到该数据(自动转向),操作都是主节点操作,从节点只是备份。
流程解析:
(1)启动应用
(2)加入集群
(3)从节点请求复制主节点(主从复制一样)先全量再增量
「使用SpringBoot整合Cluster集群」
在SpringBoot项目的application.yml中添加配置(记得把配置sentinel的注释掉)
cluster:
#命名的最多转发次数
max-redirects: 3
nodes:
8.129.113.233:6381,8.129.113.233:6382,8.129.113.233:6383,8.129.113.233:6384,8.129.113.233:6385,8.129.113.233:6386
复制代码
添加依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
复制代码
在不同网络,所以集群需要改为阿里云的公网ip地址才能进行访问,在公司中部署都会用同一个网络
redis1.conf-redis6.conf文件修改
#对外的ip
cluster-announce-ip 8.129.113.233
#对外端⼝
cluster-announce-port
#集群桥接端⼝
cluster-announce-bus-por
复制代码
也可以使用动态命令来修改
config set cluster-announce-ip 8.129.113.233
复制代码
「Cluster集群故障自动转移实战」
如果集群里面发送故障怎么办,那我们就再来实操一遍!
流程:先kill掉主节点,从节点成为新的master节点
我们可以手动把一个主节点kill掉,然后再看log,可以看到一直在尝试连接主节点,等设置的等待时间到了之后,就开始把一个从节点变成主节点。
命令如下:
./redis-cli -c -a 123456 -p 6381
#集群信息
cluster info
#节点信息
cluster nodes
复制代码
高可用架构总结
主从模式:能够读写分离,备份。一个主节点可以有多个从节点
哨兵Sentinel:监控,自动故障转移,当哨兵发现主服务器挂掉之后,就会在从节点中选择一个来当主节点
集群:为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器中,内存/QPS不受限于单机、提高并发量。
「小结:」 从最基本的主从架构到集群,了解Redis的集群模式是怎么样的,配置相关的集群配置,如何进行分区的,最后面咱们使用SpringBoot对集群Cluster进行整合。