Redis 集群

在介绍 Redis 集群架构之前,我们先简单介绍下 Redis 单实例的架构。从最开始的一主N从,到读写分离,再到 Sentinel 哨兵机制,单实例的 Redis 缓存足以应对大多数的使用场景,也能实现主从故障迁移。但是,在某些场景下,单实例 Redis 缓存会存在的以下几个问题:

(1)写并发: Redis 单实例读写分离可以解决读操作的负载均衡,但对于写操作,仍然是全部落在了 Master 节点上面,在海量数据高并发场景,一个节点写数据容易出现瓶颈,造成 Master 节点的压力上升。

(2)海量数据的存储压力:单实例 Redis 本质上只有一台 Master 作为存储。如果面对海量数据的存储,一台 Redis 的服务器就应付不过来了,而且数据量太大意味着持久化成本高,严重时可能会阻塞服务器,造成服务请求成功率下降,降低服务的稳定性。

针对以上的问题,Redis 集群提供了较为完善的方案,解决了存储能力受到单机限制,写操作无法负载均衡的问题。

什么是 Redis 集群?

Redis 3.0 加入了 Redis 的集群模式,实现了数据的分布式存储,对数据进行分片,将不同的数据存储在不同的 Master 节点上面,从而解决了海量数据的存储问题。

Redis 集群采用去中心化的思想,没有中心节点的说法,对于客户端来说,整个集群可以看成一个整体,可以连接任意一个节点进行操作,就像操作单一 Redis 实例一样,不需要任何代理中间件,当客户端操作的 key 没有分配到该节点(当前连接的节点)上时,Redis 会返回转向指令,指向正确的节点。

Redis 也内置了高可用机制,支持 N 个 Master 节点,每个 Master 节点都可以挂载多个 Slave 节点。当 Master 节点挂掉时,集群会提升它的某个 Slave 节点作为新的 Master 节点。如下图:

如上图所示,Redis 集群可以看成由多个主从复制架构组合起来的,每一个主从架构可以看成一个节点(其中,只有 Master 节点具有处理请求的能力,Slave 节点主要是用于节点的高可用)。

集群的优缺点

优点

(1)解决了写操作无法负载均衡的问题

(2)解决存储能力受到单机限制的问题

(3)实现了较为完善的高可用方案

缺点

(1)使用场景并不那么普遍

(2)需要的服务器资源较多

怎样判新集群是否正常?

如果 Redis 集群中任意一个节点挂了,而且该节点没有从节点(如果有从节点,可以设置为新的主节点),那么这个集群就挂了。

因为集群内置了 16384 个 Slot(哈希槽),并且把所有的物理节点映射到了这 16384 [0-16383] 个 Slot 上,或者说把这些 Slot 均等的分配给了各个节点。

当需要在 Redis 集群存放一个数据(key-value)时,Redis 会先对这个 key 计算 CRC16 值,然后将得到一个结果与 16384 进行求余,这个余数会对应 [0-16383] 其中一个槽,进而决定 key-value 存储到哪个节点中。所以一旦某个节点挂了,该节点对应的所有 Slot 就无法使用,那么就会导致集群无法正常工作。

如果 Redis 集群有三个节点,Slot 分布如下 :

  • 节点A覆盖 0-5460

  • 节点B覆盖 5461-10922

  • 节点C覆盖 10923-16383

注意:每个节点有 5460 个哈希槽(Slot)

如果此时向 Redis 集群中新增了一个节点:

  • 节占A覆盖 1365-5460

  • 节占B覆盖 6827-10922

  • 节点c覆盖 12288-16383

  • 节点D覆盖 0-1364

注意:每个节点有 4095 个哈希槽,所以每个 Redis 集群理论上最多可以有 16384 个节点。

集群配置

Redis 的哨兵模式基本已经可以实现高可用、读写分离,但是在这种模式每台 Redis 服务器都存储相同的数据,很浪费内存资源。所以,在 Redis3.0 上加入了群集模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点存储着不同的内容。

根据官方推荐,集群部署至少要 3 台以上的 Master 节点,最好使用 3 主 3 从六个节点的模式。

Redis 集群是由多个 Redis 服务器组成的分布式网络服务集群,集群之中有多个 Master 主节点,每一个 Master 节点都可读可写,节点之间会相互通信,两两相连,Redis 集群无中心节点。

在 Redis 集群中,可以给每个一个 Master 节点添加 Slave 节点,Master 节点和 Slave 节点直接尊循主从复制的特性,当用户需要处理更多读请求的时候, 添加 Slave 节点可以扩展系统的读性能。

Redis 集群的故障转移

Redis 群集的 Master 节点内置了类似哨兵的节点故障检测和自动故障转移功能,当群集中的某个 Master 节点下线时,群集中的其他在线 Master 节点会注意到这一点,并且对已经下线的 Master 节点进行故障转移。

Redis 集群进行故障转移的方法和哨兵模式进行故障转移的方法基本一样。不同的是,在集群里面故障转移是由集群中其他在线的 Master 节点负责进行的,所以群集不必另外配置哨兵。

集群配置步骤

下面配置的 Redis 示例将创建三个 Redis 节点,每个节点分为一个 Master 和一个 Slave。环境信息如下:

127.0.0.1:6379         Master
127.0.0.1:6378         Master
127.0.0.1:6377         Master
127.0.0.1:26379        Slave
127.0.0.1:26378        Slave
127.0.0.1:26377        Slave

Redis 集群配置分为三个步骤,分别如下:

第一步:将6个 Redis 配置为 3 个 主从复制模式,不知道怎样配置主从复制,请参考“Redis 主从复制”。

第二步:将所有 Redis 中的 dump.rdb 文件删除,或者清理 Redis 中的数据。

第三步:将三个 Master 配置成集群模式,注意,Slave 不需要配置为集群模式。

第四步:使用 redis-cli --cluster create 命令创建 Redis 集群。

下面开始配置 Redis 集群,详细配置如下:

Master(127.0.0.1:6379)配置

下面是一个 Master 节点的集群配置,集群配置总共有三相配置,分别是 cluster-enabled、cluster-config-file 和 cluster-node-timeout,配置如下:

################################ REDIS CLUSTER  ###############################

# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
# started as cluster nodes can. In order to start a Redis instance as a
# cluster node enable the cluster support uncommenting the following:
#
# cluster-enabled yes
cluster-enabled yes

# Every cluster node has a cluster configuration file. This file is not
# intended to be edited by hand. It is created and updated by Redis nodes.
# Every Redis Cluster node requires a different cluster configuration file.
# Make sure that instances running in the same system do not have
# overlapping cluster configuration file names.
#
# cluster-config-file nodes-6379.conf
cluster-config-file nodes-6379.conf

# Cluster node timeout is the amount of milliseconds a node must be unreachable
# for it to be considered in failure state.
# Most other internal time limits are multiple of the node timeout.
#
# cluster-node-timeout 15000
cluster-node-timeout 15000

Master(127.0.0.1:6378)配置

cluster-enabled yes
cluster-config-file nodes-6378.conf
cluster-node-timeout 15000

Master(127.0.0.1:6377)配置

cluster-enabled yes
cluster-config-file nodes-6377.conf
cluster-node-timeout 15000

启动集群

启动集群之前,我们先将三个 Redis 主从模式启动起来(注意,这里可以通过编写批处理脚本,一次就启动好了)。然后,在 DOS 中执行如下命令去创建集群,如下:

C:\Users\Administrator> redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6378 127.0.0.1:6377
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: dad34b2df666bb44b3d1f3807eb0030a529c2ec7 127.0.0.1:6379
  slots:[0-5460] (5461 slots) master
M: e47001b66c6d20afd76833c0e136c97c60afad32 127.0.0.1:6378
  slots:[5461-10922] (5462 slots) master
M: 39c486df6dbb5f7ffb550c07a1e5710842d993d2 127.0.0.1:6377
  slots:[10923-16383] (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.....
>>> Performing Cluster Check (using node 127.0.0.1:6379)
M: dad34b2df666bb44b3d1f3807eb0030a529c2ec7 127.0.0.1:6379
  slots:[0-5460] (5461 slots) master
M: e47001b66c6d20afd76833c0e136c97c60afad32 127.0.0.1:6378
  slots:[5461-10922] (5462 slots) master
M: 39c486df6dbb5f7ffb550c07a1e5710842d993d2 127.0.0.1:6377
  slots:[10923-16383] (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

从上面日志可知,创建了三个节点,节点信息如下:

  • Master0 的 Slots 范围为 0 - 5460

  • Master1 的 Slots 范围为 5461 - 10922

  • Master2 的 Slots 范围为 10923 - 16383

我们可以通过 redis-cli 工具连接到 Redis,查看 Redis 集群信息,如下:

C:\Users\Administrator> redis-cli
# 查看集群节点信息
127.0.0.1:6379> cluster nodes
e47001b66c6d20afd76833c0e136c97c60afad32 127.0.0.1:6378@16378 master - 0 1681192504330 2 connected 5461-10922
39c486df6dbb5f7ffb550c07a1e5710842d993d2 127.0.0.1:6377@16377 master - 0 1681192503000 3 connected 10923-16383
dad34b2df666bb44b3d1f3807eb0030a529c2ec7 127.0.0.1:6379@16379 myself,master - 0 1681192503000 1 connected 0-5460

# 集群信息,状态为 ok,即运行正常
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:3
cluster_size:3
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1264
cluster_stats_messages_pong_sent:1198
cluster_stats_messages_sent:2462
cluster_stats_messages_ping_received:1196
cluster_stats_messages_pong_received:1264
cluster_stats_messages_meet_received:2
cluster_stats_messages_received:2462
127.0.0.1:6379>

集群验证

使用 Redis 客户端工具 redis-cli 连接到 Redis 集群,然后相集群写入数据,以及从集群获取数据,如下:

C:\Users\Administrator> redis-cli -c
127.0.0.1:6379> set name www.hxstrive.com
-> Redirected to slot [5798] located at 127.0.0.1:6378
OK
127.0.0.1:6378> get name
"www.hxstrive.com"

其中,-c 选项用来启用 Redis 集群模式(遵循 -ASK 和 -MOVED 重定向)。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号