掘金 后端 ( ) • 2024-05-09 10:28

theme: serene-rose highlight: atelier-sulphurpool-light

一、什么是Redis的集群

Redis集群是一种为了实现数据的高可用性、可扩展性和容错性而设计的分布式系统。它通过将数据分散存储在多个Redis节点上,并利用主从复制和自动故障转移等机制,确保在节点故障或网络分区的情况下,系统仍能持续提供服务。

特点

  • Redis集群架构支持多Master节点,且每个Master节点可配置多个Slave节点,实现数据的读写分离。

  • 这种架构设计不仅保证了数据的高可用性,还能应对海量数据的读写操作。

  • 与传统的哨兵模式不同,Redis集群内置了Sentinel的故障转移机制,因此无需再额外配置哨兵功能。

  • 客户端在连接Redis集群时,无需连接所有节点,只需选择连接任意一个可用的集群节点即可。

  • 数据的分布和维护是通过槽位(slot)来实现的,每个物理服务节点负责一部分槽位,集群负责维护节点、插槽与数据之间的关系。这样的设计使得Redis集群在处理大量数据时能保持高效稳定的性能。

二、什么是分片、槽位slot

2.1 什么是分片

  • 在Redis集群的应用中,我们将数据分割并分散存储在多台Redis服务器上,这个过程被称为数据分片。

  • 换句话说,每个Redis实例在集群中都被视为整体数据集的一个独立分片,共同承载着数据的存储和处理任务。这种分片机制有助于实现数据的均衡分布和高效访问,提升了Redis集群的性能和可扩展性。

2.2 什么是槽位slot

  • Redis集群并未采用传统的一致性哈希算法,而是创新性地引入了 哈希槽(hash slot) 的概念。在Redis集群中,整个键空间被划分为16384个哈希槽,而不是直接对节点进行哈希。每个键都通过一个CRC16校验后,再对16384取模来确定它属于哪个哈希槽。随后,集群中的每个Redis节点都会被分配一部分哈希槽来负责管理。

  • 首先,它允许在集群中轻松地添加或删除节点,因为只需移动一部分哈希槽的数据,而不是整个键空间。

  • 其次,由于哈希槽的数量是固定的(16384个),这有助于实现更均匀的数据分布和更简单的集群管理。最后,通过哈希槽的方式,Redis集群能够高效地处理大量的数据和并发访问,同时保证数据的可靠性和稳定性。

image.png

为什么redis集群的最大槽数是16384个?

Redis集群选择16384个槽位而不是更大的65536个,主要是基于网络通信效率和存储效率的考虑。

CRC16算法确实可以产生65536个不同的哈希值,但如果直接使用这么多槽位,会导致每个节点在发送心跳信息时产生过大的消息头。

在Redis集群中,每个节点都会定期发送ping消息来保持集群的状态同步。这些ping消息包含了节点所负责的槽位信息,即myslots数组。当槽位数量为65536时,myslots数组的大小会达到8KB,这会使得每次发送的心跳包变得非常庞大,从而消耗大量的网络带宽。

相比之下,当槽位数量为16384时,myslots数组的大小仅为2KB,这大大降低了心跳包的体积,使得网络通信更加高效。此外,由于Redis集群的主节点数量通常不会超过1000个,使用16384个槽位也足够满足大多数应用场景的需求。

另外,槽位数量的减少还有助于提高数据的压缩比,使得在节点数量较少的情况下,数据的传输更加高效。这对于分布式系统来说是非常重要的,因为它可以降低网络延迟,提高系统的整体性能。

综上所述,Redis集群选择16384个槽位是出于对网络通信效率和存储效率的考虑。这种设计使得Redis集群能够在保持高性能的同时,有效地管理大量的数据。

三、Redis集群的实战步骤

前置操作

准三台centos虚拟机IP分别为: 129、131、131

实际上线情况,三主三从、六台服务器都是在不同的服务器中

image.png

用FinalShell连接

image.png

①在各台虚拟机分别新建文件夹,用来放置Redis配置文件

mkdir -p /root/myredis/cluster

②在改文件夹下各自新建两个配置文件,用来启动主机和从机

vim /root/myredis/cluster/redisCluster6381.conf

bind 0.0.0.0
daemonize yes
protected-mode no
port 6381
logfile "/root/myredis/cluster/cluster6381.log"
pidfile /root/myredis/cluster6381.pid
dir /root/myredis/cluster
dbfilename dump6381.rdb
appendonly yes
appendfilename "appendonly6381.aof"
requirepass 123456
masterauth 123456
 
cluster-enabled yes
cluster-config-file nodes-6381.conf
cluster-node-timeout 5000

image.png

vim /root/myredis/cluster/redisCluster6382.conf

bind 0.0.0.0
daemonize yes
protected-mode no
port 6382
logfile "/root/myredis/cluster/cluster6382.log"
pidfile /root/myredis/cluster6382.pid
dir /root/myredis/cluster
dbfilename dump6382.rdb
appendonly yes
appendfilename "appendonly6382.aof"
requirepass 123456
masterauth 123456
 
cluster-enabled yes
cluster-config-file nodes-6382.conf
cluster-node-timeout 5000

image.png

vim /root/myredis/cluster/redisCluster6383.conf

bind 0.0.0.0
daemonize yes
protected-mode no
port 6383
logfile "/root/myredis/cluster/cluster6383.log"
pidfile /root/myredis/cluster6383.pid
dir /root/myredis/cluster
dbfilename dump6383.rdb
appendonly yes
appendfilename "appendonly6383.aof"
requirepass 123456
masterauth 123456

cluster-enabled yes
cluster-config-file nodes-6383.conf
cluster-node-timeout 5000

image.png

vim /root/myredis/cluster/redisCluster6384.conf

bind 0.0.0.0
daemonize yes
protected-mode no
port 6384
logfile "/root/myredis/cluster/cluster6384.log"
pidfile /root/myredis/cluster6384.pid
dir /root/myredis/cluster
dbfilename dump6384.rdb
appendonly yes
appendfilename "appendonly6384.aof"
requirepass 123456
masterauth 123456
 
cluster-enabled yes
cluster-config-file nodes-6384.conf
cluster-node-timeout 5000

image.png

vim /root/myredis/cluster/redisCluster6385.conf


bind 0.0.0.0
daemonize yes
protected-mode no
port 6385
logfile "/root/myredis/cluster/cluster6385.log"
pidfile /root/myredis/cluster6385.pid
dir /root/myredis/cluster
dbfilename dump6385.rdb
appendonly yes
appendfilename "appendonly6385.aof"
requirepass 123456
masterauth 123456
 
cluster-enabled yes
cluster-config-file nodes-6385.conf
cluster-node-timeout 5000

image.png

vim /root/myredis/cluster/redisCluster6386.conf

bind 0.0.0.0
daemonize yes
protected-mode no
port 6386
logfile "/root/myredis/cluster/cluster6386.log"
pidfile /root/myredis/cluster6386.pid
dir /root/myredis/cluster
dbfilename dump6386.rdb
appendonly yes
appendfilename "appendonly6386.aof"
requirepass 123456
masterauth 123456
 
cluster-enabled yes
cluster-config-file nodes-6386.conf
cluster-node-timeout 5000

image.png

③启动六台Redis主机实例

cd /usr/local/redis/bin/

./redis-server /root/myredis/cluster/redisCluster6381.conf

./redis-server /root/myredis/cluster/redisCluster6382.conf

ps -ef|grep redis

image.png

cd /usr/local/redis/bin/

./redis-server /root/myredis/cluster/redisCluster6383.conf

./redis-server /root/myredis/cluster/redisCluster6384.conf

ps -ef|grep redis

image.png

cd /usr/local/redis/bin/

./redis-server /root/myredis/cluster/redisCluster6385.conf

./redis-server /root/myredis/cluster/redisCluster6386.conf

ps -ef|grep redis

image.png

④通过redis-cli命令为6台机器构建集群关系

./redis-cli -a 123456 --cluster create --cluster-replicas 1 192.168.118.129:6381 192.168.118.129:6382 192.168.118.131:6383 192.168.118.131:6384 192.168.118.132:6385 192.168.118.132:6386

image.png

image.png

⑤以6381端口作为访问入口,检查并验证集群的运行状况

./redis-cli -a 123456 -p 6381

info replication

cluster nodes

image.png

使用技巧

为了避免路由失效,请在命令中加入“-c”参数,并额外添加一个key。

./redis-cli -a 123456 -p 6381 -c

image.png

要确定某个键对应的槽位值,请使用 CLUSTER KEYSLOT 命令并跟上相应的键名称进行查询。

cluster keyslot k1

image.png

如果6381突然关机,6384会成为主机,并且当6381恢复之后,并不会再次成为主机而是成以节点的形式回归

Redis集群不保证强一致性,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令,因为在6381关机到6384成为主机这一段时间内,这范围内的槽位是不可以写入数据的,此时如果有数据写入则会发生数据丢失

CLUSTER FAILOVER 这个命令可以让6381与6384的主从关系互换

redis-cli -a 123456 --cluster add node 192.168.111.174:6387 192.168.111.129:6381 这个命令是吧6387作为master加入原集群

重新分派槽号 命令:redis-cli -a 密码 --cluster reshard IP地址:端口号

从集群中将4号从节点6388删除 命令:redis-cli -a 密码 --cluster del-node ip:从机端口 从机6388节点ID

redis-cli -a 123456 --cluster del-node 192.168.111.174:6388 218e7b8b4f81be54ff173e4776b4f4faaf7c13da

四、总结

本文深入探讨了Redis集群的基本概念、核心特性以及关键的分片和槽位机制。Redis集群通过数据分片、主从复制和故障转移等技术,确保了数据的高可用性、可扩展性和容错性。其中,哈希槽的创新设计使得数据分布更加均匀,集群管理更为简便。通过实战步骤的展示,读者可以更加直观地理解如何搭建和管理一个高效的Redis集群,从而满足海量数据的处理需求。总的来说,Redis集群是一种强大且灵活的分布式系统解决方案,为现代应用提供了卓越的性能和稳定性保障。