本文将对集群的节点、槽指派、命令执行、重新分片、转向、故障转移、消息等各个方面进行深入拆解。
目的在于掌握什么是 Cluster ?Cluster 分片原理,客户端定位数据原理、故障切换,选主,什么场景使用 Cluster,如何部署集群 …...
为什么需要 Cluster
65 哥:码哥,自从用上了你说的哨兵集群实现故障自动转移后,我终于可以开心的跟女朋友么么哒也不怕 Redis 宕机深夜宕机了。
可是最近遇到一个糟心的问题,Redis 需要保存 800 万个键值对,占用 20 GB 的内存。
我就使用了一台 32G 的内存主机部署,但是 Redis 响应有时候非常慢,使用 INFO 命令查看 latest_fork_usec 指标(最近一次 fork 耗时),发现特别高。
主要是 Redis RDB 持久化机制导致的,Redis 会 Fork 子进程完成 RDB 持久化操作,fork 执行的耗时与 Redis 数据量成正相关。
而 Fork 执行的时候会阻塞主线程,由于数据量过大导致阻塞主线程过长,所以出现了 Redis 响应慢的表象。
65 哥:随着业务规模的拓展,数据量越来越大。主从架构升级单个实例硬件难以拓展,且保存大数据量会导致响应慢问题,有什么办法可以解决么?
保存大量数据,除了使用大内存主机的方式,我们还可以使用切片集群。俗话说「众人拾材火焰高」,一台机器无法保存所有数据,那就多台分担。
使用 Redis Cluster 集群,主要解决了大数据量存储导致的各种慢问题,同时也便于横向拓展。
两种方案对应着 Redis 数据增多的两种拓展方案:垂直扩展(scale up)、水平扩展(scale out)。
- 垂直拓展:升级单个 Redis 的硬件配置,比如增加内存容量、磁盘容量、使用更强大的 CPU。
- 水平拓展:横向增加 Redis 实例个数,每个节点负责一部分数据。
比如需要一个内存 24 GB 磁盘 150 GB 的服务器资源,有以下两种方案:
在面向百万、千万级别的用户规模时,横向扩展的 Redis 切片集群会是一个非常好的选择。
65 哥:那这两种方案都有什么优缺点呢?
- 垂直拓展部署简单,但是当数据量大并且使用 RDB 实现持久化,会造成阻塞导致响应慢。另外受限于硬件和成本,拓展内存的成本太大,比如拓展到 1T 内存。
- 水平拓展便于拓展,同时不需要担心单个实例的硬件和成本的限制。但是,切片集群会涉及多个实例的分布式管理问题,需要解决如何将数据合理分布到不同实例,同时还要让客户端能正确访问到实例上的数据。
什么是 Cluster 集群
Redis 集群是一种分布式数据库方案,集群通过分片(sharding)来进行数据管理(「分治思想」的一种实践),并提供复制和故障转移功能。
将数据划分为 16384 的 slots,每个节点负责一部分槽位。槽位的信息存储于每个节点中。
它是去中心化的,如图所示,该集群有三个 Redis 节点组成,每个节点负责整个集群的一部分数据,每个节点负责的数据多少可能不一样。
三个节点相互连接组成一个对等的集群,它们之间通过 Gossip
协议相互交互集群信息,最后每个节点都保存着其他节点的 slots 分配情况。
开篇寄语
技术不是万能的,程序员也不是最厉害的,一定要搞清楚,不要觉得「老子天下第一」。一旦有了这个意识,可能会耽误我们的成长。
技术是为了解决问题的,如果说一个技术不能解决问题,那这个技术就一文不值。
不要去炫技,没有意义。
集群安装
一个 Redis 集群通常由多个节点(node)组成,在刚开始的时候,每个节点都是相互独立的,它们都处于一个只包含自己的集群当中,要组建一个真正可工作的集群,我们必须将各个独立的节点连接起来,构成一个包含多个节点的集群。
连接各个节点的工作可以通过 CLUSTER MEET
命令完成:CLUSTER MEET <ip> <port>
。
向一个节点 node 发送 CLUSTER MEET
命令,可以让 node 节点与 ip 和 port 所指定的节点进行握手(handshake),当握手成功时,node 节点就会将 ip 和 port 所指定的节点添加到 node 节点当前所在的集群中。
就好像 node 节点说:“喂,ip = xx,port = xx 的老哥,要不要加入「码哥字节」技术群,加入集群就找到了一条大神成长之路,关注「码哥字节」公众号回复「加群」,是兄弟就跟我一起来!”