docker 部署 Redis Cluster 集群

一、Redis 集群(理论篇)

1、redis 集群形式
1-1、数据分区方案

在这里插入图片描述
客户端分区方案 的代表为 Redis Sharding,Redis Sharding 是 Redis Cluster 出来之前,业
界普遍使用的 Redis 多实例集群 方法。Java 的 Redis 客户端驱动库 Jedis,支持 Redis
Sharding 功能,即 ShardedJedis 以及 结合缓存池 的 ShardedJedisPool。

  • 优点
    不使用 第三方中间件,分区逻辑 可控,配置 简单,节点之间无关联,容易 线性扩展,灵
    活性强。
  • 缺点
    客户端 无法 动态增删 服务节点,客户端需要自行维护 分发逻辑,客户端之间 无连接共享,
    会造成 连接浪费。
1-2、代理分区

在这里插入图片描述
代理分区常用方案有 Twemproxy 和 Codis。

2、高可用方式
2-1、Sentinel( 哨兵机制)支持高可用

前面介绍了主从机制,但是从运维角度来看,主节点出现了问题我们还需要通过人工干预的
方式把从节点设为主节点,还要通知应用程序更新主节点地址,这种方式非常繁琐笨重, 而
且主节点的读写能力都十分有限,有没有较好的办法解决这两个问题,哨兵机制就是针对第
一个问题的有效解决方案,第二个问题则有赖于集群!哨兵的作用就是监控 Redis 系统的运
行状况,其功能主要是包括以下三个:

  • 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的 Master 和 Slave 是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis 出现问题时, 哨兵(sentinel) 可以通过 API
    向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当主数据库出现故障时自动将从数据库转换为主数
    据库。
    在这里插入图片描述

哨兵的原理
Redis 哨兵的三个定时任务,Redis 哨兵判定一个 Redis 节点故障不可达主要就是通过三个定
时监控任务来完成的:

  • 每隔 10 秒每个哨兵节点会向主节点和从节点发送"info replication" 命令来获取最新的
    拓扑结构
  • 每隔 2 秒每个哨兵节点会向 Redis 节点的_sentinel_:hello 频道发送自己对主节点是否故
    障的判断以及自身的节点信息,并且其他的哨兵节点也会订阅这个频道来了解其他哨兵
    节点的信息以及对主节点的判断
  • 每隔 1 秒每个哨兵会向主节点、从节点、其他的哨兵节点发送一个 “ping” 命令来做心
    跳检测
    在这里插入图片描述

如果在定时 Job3 检测不到节点的心跳,会判断为“主观下线”。如果该节点还是主节点那么
还会通知到其他的哨兵对该主节点进行心跳检测,这时主观下线的票数超过了数
时,那么这个主节点确实就可能是故障不可达了,这时就由原来的主观下线变为了“客观下
线”。

  • 故障转移和 Leader 选举
    如果主节点被判定为客观下线之后,就要选取一个哨兵节点来完成后面的故障转移工作,选
    举出一个 leader,这里面采用的选举算法为 Raft。选举出来的哨兵 leader 就要来完成故障转
    移工作,也就是在从节点中选出一个节点来当新的主节点,这部分的具体流程可参考引用.
    《深入理解 Redis 哨兵搭建及原理》
2、Redis-Cluster

https://redis.io/topics/cluster-tutorial/
Redis 的官方多机部署方案,Redis Cluster。一组 Redis Cluster 是由多个 Redis 实例组成,官
方推荐我们使用 6 实例,其中 3 个为主节点,3 个为从结点。一旦有主节点发生故障的时候,
Redis Cluster 可以选举出对应的从结点成为新的主节点,继续对外服务,从而保证服务的高
可用性。那么对于客户端来说,知道知道对应的 key 是要路由到哪一个节点呢?Redis Cluster
把所有的数据划分为 16384 个不同的槽位,可以根据机器的性能把不同的槽位分配给不同
的 Redis 实例,对于 Redis 实例来说,他们只会存储部分的 Redis 数据,当然,槽的数据是
可以迁移的,不同的实例之间,可以通过一定的协议,进行数据迁移。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 一致性 hash
    一致性哈希 可以很好的解决 稳定性问题,可以将所有的 存储节点 排列在 收尾相接 的
    Hash 环上,每个 key 在计算 Hash 后会 顺时针 找到 临接 的 存储节点 存放。而当有节
    点 加入 或 退出 时,仅影响该节点在 Hash 环上 顺时针相邻 的 后续节点。
    在这里插入图片描述
  • Hash 倾斜
    如果节点很少,容易出现倾斜,负载不均衡问题。一致性哈希算法,引入了虚拟节点,在整
    个环上,均衡增加若干个节点。比如 a1,a2,b1,b2,c1,c2,a1 和 a2 都是属于 A 节点
    的。解决 hash 倾斜问题

二、docker 部署 Cluster 集群

1、创建 6 个 redis 节点

下载镜像

docker pull redis:5.0.7;

3 主 3 从方式,从为了同步备份,主进行 slot 数据分片

#创建6个实例【端口为:7001----7006】
for port in $(seq 7001 7006); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port  ${port}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.56.10
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
appendonly yes
EOF
docker run -p ${port}:${port} -p 1${port}:1${port} --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d redis:5.0.7 redis-server /etc/redis/redis.conf; \
done

#停止【可选】
docker stop $(docker ps -a |grep redis-700 | awk '{ print $1}')
#删除【可选】
docker rm $(docker ps -a |grep redis-700 | awk '{ print $1}')
2、使用 redis 建立集群
#进入到一个redis容器
docker exec -it redis-7001 bash
redis-cli --cluster create 192.168.56.10:7001 192.168.56.10:7002 192.168.56.10:7003 192.168.56.10:7004 192.168.56.10:7005 192.168.56.10:7006 --cluster-replicas 1
3、测试redis集群

随便进入某个 redis 容器

docker exec -it redis-7002 /bin/bash

获取集群信息

redis-cli -c -h 192.168.56.10 -p 7006 cluster info;

获取集群节点

redis-cli -c -h 192.168.56.10 -p 7006  cluster nodes;

使用 redis-cli 的 cluster 方式进行连接

redis-cli -c -h 192.168.56.10 -p 7006

Get/Set 命令测试,将会重定向
节点宕机,slave 会自动提升为 master,master 开启后变为 slave

在这里插入图片描述

Redis集群报错:(error) CROSSSLOT Keys in request don’t hash to the same slot 的解决办法

例如:mset 设置多键值时报错

172.100.0.1:6393> MSET name1 '1' name2 '2' name3 '3' name4 '4'
(error) CROSSSLOT Keys in request don't hash to the same slot

解决办法:用相同的hashTag设置

#设置多个
mset {t}test1 wang {t}test2 zhao {t}test3 liu
#获取多个
mget {t}test1 {t}test2 {t}test3

其他参考:

  • Redis 哈希槽基本概念
哈希槽(hash slot)是来自Redis Cluster的概念, 但在各种集群方案都有使用。

哈希槽是一个key的集合,Redis集群共有16384个哈希槽,每个key通过CRC16散列然后对16384进行取模来决定该key应当被放到哪个槽中,集群中的每个节点负责一部分哈希槽。

以有三个节点的集群为例:

节点A包含0到5500号哈希槽
节点B包含5501到11000号哈希槽
节点C包含11001到16384号哈希槽
这样的设计有利于对集群进行横向伸缩,若要添加或移除节点只需要将该节点上的槽转移到其它节点即可。
在某些集群方案中,涉及多个key的操作会被限制在一个slot中,如Redis Cluster中的mget/mset操作。
  • HashTag
HashTag机制可以影响key被分配到的slot,从而可以使用那些被限制在slot中操作。

HashTag即是用{}包裹key的一个子串,如{user:}1, {user:}2。

在设置了HashTag的情况下,集群会根据HashTag决定key分配到的slot, 
两个key拥有相同的HashTag:{user:}, 它们会被分配到同一个slot,允许我们使用MGET命令。

通常情况下,HashTag不支持嵌套,即将第一个{和第一个}中间的内容作为HashTag。

若花括号中不包含任何内容则会对整个key进行散列,如{}user:。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的小蜗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值