什么redis集群?
- redis集群是一个提供在多个redis节点之间共享数据的程序集。它并不像redis主从复制模式那样仅提供一个master节点来提供写服务,而是会提供多个master节点来提供写服务,每个master节点中存储的数据都不一样,这些数据通过数据分片的方式被自动分割到不同的master节点上
redis集群介绍:
- Redis Cluster 是redis的分布式解决方案,当遇到单机、内存、流量等瓶颈时,可以采用cluster架构方式达到负载均衡的目的
数据分布:
- 分布式数据库首先要解决吧整个数据库集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集,需要关注的是数据分片规则,Rredis Cluster采用哈希分片规则。
集群节点之间的通讯方式:
- 节点之间通过建立TCP连接,使用gossip协议来传播集群的信息。端口为:服务端口+10000
Redis Cluster部署的两种方式:
### 原生安装与官方工具安装
### 原生安装的步骤:
* 1.手动配置节点发现
* 2.meet操作(通知新节点加入)
* 3.指派槽位
* 4.分主从
### 官方工具安装:
* 如果redis版本为3打头需要手动安装redis-trib.rb工具,新版本无需安装
本章实验环境如下:
### 环境介绍:
* 为了使整个集群变得高可用性,我们给每台服务器上开了两个实例 一个为master一个为slave,当master节点故障,则会自动使用slave升级为master节点。
<!-- -->
* 如何知道集群中某个节点故障了呢?
* 他们之间的通讯方式:每个节点都使用tcp协议相互通讯交流,当某个master出现故障时,所有节点都会知道这个出现故障的master,这时集群会自动把故障下面的salve升级为master
### 实验操作:
*
#### 原生安装:
<!-- -->
* 1.三台服务器上部署redis服务:
* redis1:创建数据目录和安装目录:
* mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid}
<!-- -->
* mkdir -p /data/redis_cluster/redis_{6380,6381}
<!-- -->
* 解压安装包到/opt/redis_cluster目录下:
* tar xf redis-5.0.7.tar.gz -C /opt/redis_cluster/
<!-- -->
* cd /opt/redis_cluster/
<!-- -->
* ln -s redis-5.0.7 redis
<!-- -->
* cd redis
<!-- -->
* make \&\& make install
<!-- -->
* 编辑配置文件:
* 配置文件解释: ![](https://file.jishuzhan.net/article/1767544611489714177/c4b35aa193061f7fccaa778561bb97f6.webp)
*
```bash
cat >/opt/redis_cluster/redis_6380/conf/redis_6380.conf<<EOF
bind 192.168.8.5
port 6380
daemonize yes
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_cluster/redis_6380/"
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF
cd /opt/redis_cluster/
cp redis_6380/conf/redis_6380.conf redis_6381/conf/redis_6381.conf
sed -i 's#6380#6381#g' redis_6381/conf/redis_6381.conf
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
```
* 将redis1服务器的安装目录和数据目录,远程复制到redis2、redis3服务器上:
* scp -rp /opt/\* root@192.168.8.6:/opt
* scp -rp /opt/\* root@192.168.8.7:/opt
* redis2 操作:
*
```bash
cd /opt/redis_cluster/redis
make install
find /opt/redis_cluster/redis_638* -type f -name "*.conf"|xargs sed -i "s#5#6#g"
mkdir -p /data/redis_cluster/redis_{6380,6381}
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
```
* redis3 操作:
*
```bash
cd /opt/redis_cluster/redis
make install
find /opt/redis_cluster/redis_638* -type f -name "*.conf"|xargs sed -i "s#5#7#g"
mkdir -p /data/redis_cluster/redis_{6380,6381}
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
```
<!-- -->
* 查看8.6-7服务器上是否有6380和6381端口:
* netstat -anpt \| grep 638
<!-- -->
* ![](https://file.jishuzhan.net/article/1767544611489714177/c4a91b49605f3fc2e71d659f69ffa843.webp)
<!-- -->
* 至此每台服务器上出现此端口,代表三台redis部署启动成功。
<!-- -->
*
#### 开始创建群集:
*
##### 1.手动配置节点发现:
* 登录任意一台服务器的redis节点:
* redis-cli -h 192.168.8.5 -p 6380
<!-- -->
* 登录8.5的6380redis实例后,开始发现其他五个节点:
* 使用节点发现命令,发现其他五个节点(登录数据库后执行):
*
```bash
CLUSTER MEET 192.168.8.5 6381
CLUSTER MEET 192.168.8.6 6380
CLUSTER MEET 192.168.8.7 6380
CLUSTER MEET 192.168.8.6 6381
CLUSTER MEET 192.168.8.7 6381
```
* 查看集群信息:
* CLUSTER NODES
<!-- -->
* ![](https://file.jishuzhan.net/article/1767544611489714177/a326d28d5a24d2cd3378fa448d10c7f0.webp)
*
##### Redis Cluster 通讯流程:
* 1)集群中的每一个节点都会单独开辟一个 Tcp 通道,用于节点之间彼此通信,防火墙放行(端口号+10000).
<!-- -->
* 2)每个节点在固定周期内通过特定规则选择结构节点发送 ping 消息
<!-- -->
* 3)接收到 ping 消息的节点用 pong 消息作为响应。集群中每个节点通过一定规则挑选要通信的节点,每个节点可能知道全部节点,也可能仅知道部分节点,
<!-- -->
* 只要这些节点彼此可以正常通信,最终他们会打成一致的状态,当节点出现故障,新节点加入,主从角色变化等,它能够给不断的ping/pong消息,从而达到同步目的。
<!-- -->
*
##### Redis Cluster手动分配槽位:
* 现在节点之间已经互相发现了,但是此时集群还是不可用的状态,因为并没有给节点分配槽位,而且必须是所有的槽位都分配完毕后整个集群才是可用的状态。
<!-- -->
* 我们虽然是有6个节点,但是真正写入数据的只有三个节点,其他三个节点只是作为主节点的从节点,只需要分配这其中三个主节点的槽位就可以了
<!-- -->
* 分别登录到每个主节点的客户端来执行命令:
* 在数据库外执行:
*
```bash
redis-cli -h 192.168.8.5 -p 6380 cluster addslots {0..5460}
redis-cli -h 192.168.8.6 -p 6380 cluster addslots {5461..10922}
redis-cli -h 192.168.8.7 -p 6380 cluster addslots {10923..16383}
```
* 再次查看集群信息:
* 可以看到后面有了刚才分配的槽位,群集状态也是ok的。 ![](https://file.jishuzhan.net/article/1767544611489714177/43b1883f04dfb92061a4f09cd80d3846.webp)
<!-- -->
*
##### 手动配置集群高可用:
* 虽然这时候集群是可以用得了,但是整个集群只要有一台机器坏掉了,那么整个集群都是不可用的。
<!-- -->
* 这时候就需要将另外三个没有槽位的三个节点分别作为现在三个有槽位的主节点的从节点,这样就可以应对集群主节点故障时可以进行自动切换,以保证整个集群的高可用性。
<!-- -->
* 在任意一台redis服务器上远程操作集群其他节点
* 注意:需要执行命令的是每个服务器的从节点
* 注意主从的ID不要搞混了
<!-- -->
* 主从节点不要在一台服务器上,要交叉分主从
<!-- -->
*
```bash
redis-cli -h 192.168.8.5 -p 6381 CLUSTER REPLICATE 49cbd0227229494070be11e3bc2a4a383f8d535e (第二台主机6380的id)id号查看自己的id号
redis-cli -h 192.168.8.6 -p 6381 CLUSTER REPLICATE c9f13f78e29245ca993ea635ab27a3e260c6a210(第三台主机6380的id)
redis-cli -h 192.168.8.7 -p 6381 CLUSTER REPLICATE 6bb3f91ff8da948fc07d25445992e2161ed741f4 (第一台主机6380的id)
```
* 再次查看群集信息:
* 发现每台主机的6381端口节点,都变成了slave状态(从服务器) ![](https://file.jishuzhan.net/article/1767544611489714177/f1bb9bf462964423686bd75d0cbe8998.webp)
<!-- -->
* 此时手动搭建群集以部署完毕,测试是否可以正常存储数据!!
*
##### Redis Cluster测试集群:
* 此时我们使用常规插入redis数据的方式往集群里写数据看看会发生什么
<!-- -->
* redis-cli -h 192.168.8.5 -p 6380 set k1 v1
* ![](https://file.jishuzhan.net/article/1767544611489714177/e2baee94b20b8a64fca63953cf0fbc69.webp)
<!-- -->
* 并没有插入数据到数据库中,这是因为集群后由于数据被分片了,所以并不是说在那台机器上写入数据就会在那台机器的节点上写入。
<!-- -->
* 集群的数据写入和读取就要涉及到另外一个概念,ASK路由。
<!-- -->
* Redis Cluster ASK路由介绍:
* 在集群模式下,redis接受任何键相关命令是首选会计算键对应的槽(slot),再根据槽找出所对应的节点,如果节点是自身,则处理键命令;
<!-- -->
* 否则恢复MOVED重定向错误,通知客户端请求正确的节点,这个过程称为MOVER重定向。
<!-- -->
* redis-cli客户端提供了-c参数实现自动重定向。
<!-- -->
* 插入数据:redis-cli -c -h 192.168.8.5 -p 6380 set k1 v1
<!-- -->
* 写入后同样需要使用-c选项来读取键值:
<!-- -->
* 读取数据:redis-cli -c -h 192.168.8.5 -p 6380 get k1
<!-- -->
*
##### Redis Cluster模拟故障转移
* 模拟redis2故障:
* redis-cli -h 192.168.8.6 -p 6380 shutdown
<!-- -->
* redis-cli -h 192.168.8.6 -p 6381 shutdown
<!-- -->
* 查看群集节点状态:
* redis-cli -h 192.168.8.5 -p 6380
* cluster nodes
<!-- -->
* 关闭8.6的6380主节点后,8.5的6381从节点自动又主节点切换回了主节点 ![](https://file.jishuzhan.net/article/1767544611489714177/6cf80f6fb55cf4cafb6bac74276f71c3.webp)
<!-- -->
* 再次将8.6服务器上的两个节点启动起来:
* redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
<!-- -->
* redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
<!-- -->
* 查看群集节点状态:
* 8.5的6381切换回了slave。
<!-- -->
*
<!-- -->
*
#### 使用工具自动搭建部署Redis Cluster集群
* 实验环境还是6个节点与原生安装一样:
* 部署redis节点过程略与上方一样
<!-- -->
*
##### 开始部署群集:
* 无需安装redis-trib.rb工具(新版本无需安装),节点部署好后直接创建集群
<!-- -->
*
##### 创建群集:
*
```bash
redis-cli --cluster create --cluster-replicas 1 192.168.8.5:6380 192.168.8.6:6380 192.168.8.7:6380 192.168.8.5:6381 192.168.8.6:6381 192.168.8.7:6381
```
* (前面三个自动被分配为master,后三个自动被分配为slave)
* 直接yes即可
<!-- -->
* 检查完整性:redis-cli --cluster check 192.168.8.5:6380
* 槽位也被自动分配了 ![](https://file.jishuzhan.net/article/1767544611489714177/1ce7efb90f79b6a731394461575fdae5.webp)
<!-- -->
*
##### 当我们节点不够用时,使用redis集群扩容:
* 1)准备新节点
<!-- -->
* 2)加入集群
<!-- -->
* 3)迁移槽和数据
<!-- -->
* 为了省资源,我们在redis1服务器上再创建两个新节点
* mkdir -p /opt/redis_cluster/redis_{6390,6391}/{conf,logs,pid}
<!-- -->
* mkdir -p /data/redis_cluster/redis_{6390,6391}
<!-- -->
* cd /opt/redis_cluster/
<!-- -->
* cp redis_6380/conf/redis_6380.conf redis_6390/conf/redis_6390.conf
<!-- -->
* cp redis_6380/conf/redis_6380.conf redis_6391/conf/redis_6391.conf
<!-- -->
* sed -i 's#6380#6390#g' redis_6390/conf/redis_6390.conf
<!-- -->
* sed -i 's#6380#6391#g' redis_6391/conf/redis_6391.conf
<!-- -->
* 启动节点
* redis-server /opt/redis_cluster/redis_6390/conf/redis_6390.conf
<!-- -->
* redis-server /opt/redis_cluster/redis_6391/conf/redis_6391.conf
<!-- -->
* 发现节点:(将新建的两台节点)
* redis-cli -c -h 192.168.8.5 -p 6380 cluster meet 192.168.8.5 6390
<!-- -->
* redis-cli -c -h 192.168.8.5 -p 6380 cluster meet 192.168.8.5 6391
<!-- -->
* 从之前的三台master节点服务器上向新的6390节点分配slots槽位
* redis-cli --cluster reshard 192.168.8.5:6390
* ![](https://file.jishuzhan.net/article/1767544611489714177/bac133b1f79dee4c8532146559562e4d.webp)
<!-- -->
* 将6391顺从于6390:
* redis-cli -h 192.168.8.5 -p 6391 cluster replicate 6390id
<!-- -->
* 再次检查集群,发现6390有了槽位,6391 没有槽位也是slave
<!-- -->
* 扩展完之后,再将它们收缩:
* 移除下线节点的槽位:
<!-- -->
* redis-cli --cluster reshard 192.168.8.5:6390
* ![](https://file.jishuzhan.net/article/1767544611489714177/c6002499e914bbaa5d0f6f573469e2a2.webp)
<!-- -->
* 这样重复三次,即可将槽位还回去
* 1365 给redis1的6380
<!-- -->
* 1366 给redis2的6380
<!-- -->
* 1365 给redis3的6380
<!-- -->
* 移除下线的节点:
* redis-cli -c -h 192.168.8.5 -p 6380 cluster forget 6f2a812b88aa230e13fadabc1096304ddcbddc17(6390id)
<!-- -->
* redis-cli -c -h 192.168.8.5 -p 6380 cluster forget 547176fc5e7b7a3fb144ea1cb49dd48018d3ff3c(6391id)
<!-- -->
* 至此整章redis集群的原生部署和自动部署环境分别介绍完毕,感谢观看!!