乐趣区

Redis集群容器化安装

  1. Redis 集群概述

Redis 作为当前非常热门的内存型数据结构存储,可用于数据存储,缓存和消息代理等。本文将讲解如何基于 docker 搭建 Redis 集群,Redis 的集群设计包括两个部分:主从复制和哈希 Slot。
1.1. 主从复制
主从复制在数据库中很常见,一般用来做读写分离,Redis 中也是如此。要求只有 1 个 Master(主节点),可以有 N 个 slaver(从节点),而且 Slaver 也可以有自己的 Slaver,由于这种主从的关系决定他们是在配置阶段就要指定他们的上下级关系,而不是 Zookeeper 那种平行关系是自主推优出来的。
读写分离,Master 只负责写和同步数据给 Slaver,Slaver 承担了被读的任务,所以 Slaver 的扩容只能提高读效率不能提高写效率。
Slaver 先将 Master 那边获取到的信息压入磁盘,再 load 进内存,client 端是从内存中读取信息的。当一个新的 Slaver 加入到这个集群时,会主动找 Master 来拜码头,Master 发现新的小弟后将全量数据发送给新的 Slaver,数据量越大性能消耗也就越大,所以尽量避免在运行时做 Slaver 的扩容。
优点:读写分离,通过增加 Slaver 可以提高并发读的能力。
缺点:Master 写能力是瓶颈,维护 Slaver 开销也总将会变成瓶颈。
1.2. 哈希 Slot
哈希 Slot 名字上可能不好理解,其实就是数据库中的“水平划分”。如果你之前有了解过数据库的表分区的话,就会发现下来对于哈希 Slot 的描述,就和数据库表分区里面的“HASH 分区”原理上大致相同。

对象保存到 Redis 之前先经过 CRC16 哈希到一个指定的 Node 上,例如图中 Object4 最终 Hash 到了 Node1 上。
每个 Node 被平均分配了一个 Slot 段,对应着 0 -16384,Slot 不能重复也不能缺失,否则会导致对象重复存储或无法存储。
Node 之间也互相监听,一旦有 Node 退出或者加入,会按照 Slot 为单位做数据的迁移。例如 Node1 如果掉线了,0-5640 这些 Slot 将会平均分摊到 Node2 和 Node3 上, 由于 Node2 和 Node3 本身维护的 Slot 还会在自己身上不会被重新分配,所以迁移过程中不会影响到 5641-16384 Slot 段的使用。
优点:将 Redis 的写操作分摊到了多个节点上,提高写的并发能力,扩容简单。
缺点:每个 Node 承担着互相监听、高并发数据写入、高并发数据读出,工作任务繁重。
1.3. 合二为一
看到这里大家也就发现了,主从和哈希的设计优缺点正好是相互弥补的,将二者结合在一起,就是 Redis 集群的终极形态,先 Hash 分逻辑节点,然后每个逻辑节点内部是主从,如图:

2. 集群安装
默认我们已经有了 docker 环境,现在开始基于 docker 安装 Redis 集群。redis 5.0 版本之前,网上有很多教程都是通过 redis-trib.rb 来创建集群,但是 redis 5.0 版本以后,就只能通过 redis-cli 来实现。本文即通过 redis-cli 创建集群,因为 redis 集群的节点选举方式是需要半数以上的 master 通过,所以建议创建奇数个节点。本例中创建 3 个 Master 节点,并为每个 Master 节点各分配 1 个 Slave 节点。
2.1. 宿主机环境
首先需要找一份原始的 redis.conf 文件,将其重命名为:redis-cluster.tmpl,并配置如下几个参数,此文件的目的是生成每一个 redis 实例的 redis.conf:

vi redis-cluster.tmpl

然后执行下列脚本,给 3 个 Master 和 3 个 Slave 创建各自的挂载卷目

录当前目录结构为

2.2. 创建 Redis 节点
假设我们只考虑单纯的 docker 环境,并无 docker-compose 和 k8s 之类的服务编排,每个 redis 容器之间必须要保证通讯,可以通过创建 docker network。(使用微服务编排的情况,后续再讨论)

现在我们就可以运行 docker redis 的 master 和 slave 实例了

查看已创建的 redis 容器

2.3. 构建集群
通过 redis-cli 命令构建集群,随便找一个 redis 容器,运行 redis-cli –cluster create –cluster-replicas 1 ip:port 命令即可

记住构建集群时,要保证节点 redis 数据为空,否则会出现下列错误。

2.4. 集群验证
集群搭建完成后,我们通过 redis-cli 命令连接集群节点验证一下。redis 集群节点的连接命令是通过 redis-cli -c -h ${ip} -p ${port}


可以看到通过 “cluster info” 命令看到集群的基本信息,所有的 slot (16384) 都分配完毕。然后通过 “cluster nodes” 命令查看到每个 master 节点的 slot 分配的区域。至此,redis 集群基本安装成功。
3. 后期运维
3.1. 基本命令
集群

节点

槽(slot)

3.2. 常见问题
(1)redis-cluster 把所有的物理节点映射到[0 ~ 16383] 个 slot(哈希槽)上,cluster 负责维护 node<->slot<->value。
(2)集群任意一个节点中,如果 master 挂掉,但是还有 slaver,slave 将自动升为 master,系统正常。
(3)集群任意一个节点中,如果 master 挂掉,并且没有 slaver,集群将进入 fail 状态。
(4)如果集群超过半数以上节点的 master 挂掉,不管是否有 slaver,集群都将进入 fail 状态。
(5)节点判断是否失效的选举,是集群中所有的 master 参与的,如果半数以上的 master 节点与当前被检测的 master 节点通讯检测超时(cluster-node-timerout),就认为当前 master 节点挂掉了。
本人创业团队产品 MadPecker,主要做 BUG 管理、测试管理、应用分发
网址:www.madpecker.com,有需要的朋友欢迎试用、体验!
本文为 MadPecker 团队技术人员编写,转载请标明出处

退出移动版