Redis高级-详解-3主3从集群搭建

一、准备

1.拉取redis镜像
docker pull redis
2.Docker容器网络

1.创建虚拟网卡

docker network create myredis

2.查看Dokcer网卡信息

docker network ls

3.查看docker网络详细信息

docker network inspect myredis
3.创建配置文件

使用shell脚本命令批量创建配置文件,这里选择在自己的/usr/local/software/redis目录下。

for port in `seq 6481 6486`; do
mkdir -p /usr/local/software/cluster/node-${port}/conf
touch /usr/local/software/cluster/node-${port}/conf/redis.conf
cat  << EOF > /usr/local/software/cluster/node-${port}/conf/redis.conf
port ${port}
requirepass 123456
masterauth 123456
bind 0.0.0.0
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes 
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
EOF
done
​

port:端口。

requirepass:密码。

masterauth: 从机成为主机后的密码,若设置了requirepass不配置此项,将无法主从复制。

protected-mode:保护模式,默认值 yes。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问。

daemonize:是否以守护线程的方式启动(后台启动),默认 no。

appendonly:是否开启 AOF 持久化模式,默认 no。

cluster-enabled:是否开启集群模式,默认 no。

cluster-config-file:集群节点信息文件。

cluster-node-timeout:集群节点连接超时时间。

cluster-announce-port:集群节点映射端口。

cluster-announce-bus-port:集群节点总线端口。

注:集群总线端口=客户端端口+10000,此端口用于集群故障检测、配置更新等等,若不开启两个端口,则集群节点将无法通信。

运行后,可以使用tree命令查看结构(需要先安装tree命令,yum install tree)

二、启动容器

1.启动

再次使用命令批量启动

for port in $(seq 6481 6486); \
do \
   docker run -it -d -p ${port}:${port} -p 1${port}:1${port} \
  --privileged=true -v /usr/local/software/cluster/node-${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  --privileged=true -v /usr/local/software/cluster/node-${port}/data:/data \
  --restart always --name redis-${port} --net myredis \
  --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf
done

启动后使用docker ps 查看是否启动。

2.命令解释

-it:以交互模式启动

-d:后台运行,容器启动完成后打印容器

–privileged:是否让docker 应用容器 获取宿主机root权限(特殊权限-)

-p :端口映射

-v:数据卷挂载

–sysctl参数来设置系统参数,通过这些参数来调整系统性能

–restart always:在容器退出时总是重启容器

–name :给容器取名

–net myredis :使用我们创建的虚拟网卡

3.搭建Redis Cluster集群

随便进入一个节点创建集群。

1.进入redis-6381容器

docker exec -it redis-6481 /bin/bash

2.创建集群,注意开启防火墙的12个端口,包括集群总线端口!

redis-cli -a 123456 --cluster create 192.168.88.129:6481 192.168.88.129:6482 192.168.88.129:6483 192.168.88.129:6484 192.168.88.129:6485 192.168.88.129:6486 --cluster-replicas 1

查看节点信息,连接redis后输入cluster info

redis-cli -h 192.168.88.129 -p 6481
auth 123456
​
cluster info

也可输入cluster nodes查看节点信息

cluster nodes

可看到myself为我们所在的节点。

三、测试

1.测试

出现错误,这是因为我们没有以集群的方式连接( -c )。

重新连接

redis-cli -c -a 123456 -h 192.168.88.129 -p 6481 

12706是哈希槽的位置,redis一共有16384个槽位,根据槽位来区分数据所在位置,集群算法下面会介绍。

2.可能用到的命令

批量停止

for port in `seq 6481 6486`; 
do 
docker start redis-${port}
done

批量删除

for port in $(seq 6481 6486); 
do 
docker rm redis-${port}
done

防火墙

查看已开放的端口(默认不开放任何端口)
firewall-cmd --list-ports
开启6379端口
firewall-cmd --zone=public(作用域) --add-port=6379/tcp(端口和访问类型) --permanent(永久生效)
停止防火墙
systemctl stop firewalld.service
禁止防火墙开机启动
systemctl disable firewalld.service
删除某端口
firewall-cmd --zone= public --remove-port=80/tcp --permanent
重启防火墙
firewall-cmd --reload

四、主从容错迁移

当前情况如下

查看集群状态

模拟宕机6481,然后6485上位

重启6481,6481还是从机。

#主从关系对调(6481对应6485)
cluster failover

集群不保证数据一致性,一定会有数据丢失情况

Redis集群不保证强一致性,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令。

五、主从扩容

1.新建6487,6488
for port in `seq 6487 6488`; do
mkdir -p /usr/local/software/cluster/node-${port}/conf
touch /usr/local/software/cluster/node-${port}/conf/redis.conf
cat  << EOF > /usr/local/software/cluster/node-${port}/conf/redis.conf
port ${port}
requirepass 123456
masterauth 123456
bind 0.0.0.0
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes 
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
EOF
done
2.启动
for port in $(seq 6487 6488); \
do \
   docker run -it -d -p ${port}:${port} -p 1${port}:1${port} \
  --privileged=true -v /usr/local/software/cluster/node-${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  --privileged=true -v /usr/local/software/cluster/node-${port}/data:/data \
  --restart always --name redis-${port} --net myredis \
  --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf
done

记得开启端口的防火墙

3.加入原集群

先进入6481

docker exec -it redis-6481 bash

6487作为master,加入6481

redis-cli -a 123456 --cluster add-node 192.168.88.129:6487 192.168.88.129:6481
4.检查集群情况
redis-cli -a 123456 --cluster check 192.168.88.129:6481
5.重新分配槽号
redis-cli -a 123456 --cluster reshard 192.168.88.129:6481
​
#16386/4 = 4096
#将6387的ID粘贴,说明将4096槽位分派给它
6.再次检查
redis-cli -a 123456 --cluster check 192.168.88.129:6481
7.为主节点6487分配从节点6488
redis-cli -a 123456 --cluster add-node 192.168.88.129:6488 192.168.88.129:6487 --cluster-slave --cluster-master-id a752a054077d0e8b45235f500762f7be0f8f4bbb

8.检查集群

redis-cli -a 123456 --cluster check 192.168.88.129:6481

六、主从缩容

1.删除节点6488
redis-cli -a 123456 --cluster del-node 192.168.88.129:6488 168ce1d839e5e87a82c521389d0a93dc7bc9c045
2.清空6487槽号,重新分配

可以先全给6481

redis-cli -a 123456 --cluster reshard 192.168.88.129:6481
​
#依次输入
#4096
#6481的节点ID 7e1f8fba1aba14618677f27a3d99a62695574e7d
#6487的节点ID a752a054077d0e8b45235f500762f7be0f8f4bbb
#done
#yes
3.检查
redis-cli -a 123456 --cluster check 192.168.88.129:6481
4.删除6487
redis-cli -a 123456 --cluster del-node 192.168.88.129:6487 a752a054077d0e8b45235f500762f7be0f8f4bbb
5.检查
redis-cli -a 123456 --cluster check 192.168.88.129:6481
 
#连接
redis-cli -a 123456 -p 6481 -c
#查看集群拓扑图
cluster nodes

七、集群常用命令

1.通识占位符

不在同一个slot槽位下的键值无法使用mset、mget等多键操作,可以通过{}来定义同一个组的概念,使key中{}内相同内容的键值对放到一个slot槽位去。

#批量获取值
mget k1 k2 k3
(error) CROSSSLOT Keys in request don't hash to the same slot
#使用{}来定义同一个组,批量设置值
mset k1{x} 1 k2{x} 2 k3{x} 3
OK
#批量获取值
mget k1{x} k2{x} k3{x}
1) "1"
2) "2"
3) "3"
2..CLUSTER COUNTKEYSINSLOT

1 :该槽位被占用, 0:该槽位没占用

set A aaa
-> Redirected to slot [6373] located at 139.224.102.249:6381
OK
CLUSTER COUNTKEYSINSLOT 6373
(integer) 1
CLUSTER COUNTKEYSINSLOT 6372
(integer) 0
3.CLUSTER KEYSLOT 键名称

键存放在哪一个槽位上

CLUSTER KEYSLOT A
(integer) 6373
CLUSTER KEYSLOT key1
(integer) 9189
4.CLUSTER SLOTS

查看各个节点的slot区间

127.0.0.1:6481> cluster slots
1) 1) (integer) 0  #范围0~6826
   2) (integer) 6826
   3) 1) "172.18.0.3"
      2) (integer) 6481 
      3) "7e1f8fba1aba14618677f27a3d99a62695574e7d" #主节点
   4) 1) "172.18.0.1"
      2) (integer) 6485
      3) "dfe2b1d120954f2963a26c8db8ecd069e53c24e4" #从节点
2) 1) (integer) 6827
   2) (integer) 10922
   3) 1) "172.18.0.1"
      2) (integer) 6482
      3) "34291a1de4237a74a0ef9dc614cda47df867443c"
   4) 1) "172.18.0.1"
      2) (integer) 6486
      3) "857b4a082d746c4a7297b77c92c19063e863b976"
3) 1) (integer) 10923
   2) (integer) 12287
   3) 1) "172.18.0.3"
      2) (integer) 6481
      3) "7e1f8fba1aba14618677f27a3d99a62695574e7d"
   4) 1) "172.18.0.1"
      2) (integer) 6485
      3) "dfe2b1d120954f2963a26c8db8ecd069e53c24e4"
4) 1) (integer) 12288
   2) (integer) 16383
   3) 1) "172.18.0.1"
      2) (integer) 6483
      3) "83e1bc5451f780667263d50a774742463a1e43f0"
   4) 1) "172.18.0.1"
      2) (integer) 6484
      3) "db20b98538b35b6ef2d1c797a036252422e43bcb"
5.CLUSTER NODES

查看集群拓扑图

127.0.0.1:6481> cluster nodes
34291a1de4237a74a0ef9dc614cda47df867443c 172.18.0.1:6482@16482 master - 0 1722324119624 2 connected 6827-10922
dfe2b1d120954f2963a26c8db8ecd069e53c24e4 172.18.0.1:6485@16485 slave 7e1f8fba1aba14618677f27a3d99a62695574e7d 0 1722324118618 10 connected
7e1f8fba1aba14618677f27a3d99a62695574e7d 172.18.0.3:6481@16481 myself,master - 0 1722324118000 10 connected 0-6826 10923-12287
857b4a082d746c4a7297b77c92c19063e863b976 172.18.0.1:6486@16486 slave 34291a1de4237a74a0ef9dc614cda47df867443c 0 1722324118114 2 connected
db20b98538b35b6ef2d1c797a036252422e43bcb 172.18.0.1:6484@16484 slave 83e1bc5451f780667263d50a774742463a1e43f0 0 1722324118618 3 connected
83e1bc5451f780667263d50a774742463a1e43f0 172.18.0.1:6483@16483 master - 0 1722324118000 3 connected 12288-16383
​6.CLUSTER INFO

查看集群环境信息

127.0.0.1:6481> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:10
cluster_my_epoch:10
cluster_stats_messages_ping_sent:41609
cluster_stats_messages_pong_sent:41062
cluster_stats_messages_sent:82671
cluster_stats_messages_ping_received:41062
cluster_stats_messages_pong_received:41599
cluster_stats_messages_received:82661

八、一些问题

1.有什么用?

提供在多个Redis节点间共享数据的程序集。

1.Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能

2.客户端与Redis的节点连接,不再需要连接集群中所有的节点,只需要任意连接集群中的一个可用节点即可。

3.槽位slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系。

2.集群算法-分片-槽位

Redis集群引入了哈希槽的概念。Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个节点负责一部分hash槽。

分片是什么 ?

使用Redis集群时我们会将存储的数据分散到多台redis机器上,这称为分片。

有什么用?

最大优势,方便扩缩容和数据分派查找。通过刚才的扩容缩容我们也能体会到这一点。

从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

3.注意

Redis集群不保证强一致性,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令。

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值