目录
[什么是数据分片(data sharding)](#什么是数据分片(data sharding))
Redis集群的诞生
在前面文章,我们介绍过Redis的主从复制的诞生是为了实现读写分离,提高数据的安全性;
哨兵机制的诞生是为了主节点宕机,可以自动选择一个从节点替换掉主节点,避免了人工干预。
虽然主从复制+哨兵模式采用了多节点,但是它们存在的目的主要是解决容灾问题,并不是性能问题。
随着Redis在各类高并发,高性能系统中的广泛应用,单节点Redis的局限性逐渐显现出来,而Redis集群正式为了解决这些局限性而设计的。
单节点Redis的局限性
1.存储容量限制
- Redis 是基于内存的存储系统,因此其存储容量受限于单台机器的内存大小。对于一些需要存储海量数据的应用,单节点 Redis 的内存容量很快就会成为瓶颈。
2.性能瓶颈
- 随着系统规模的扩大,单节点 Redis 的 CPU 和网络带宽可能无法满足不断增加的读写请求。尤其在高并发场景下,单节点 Redis 容易出现性能瓶颈,影响整个系统的响应速度。
3.单点故障
- 虽然 Redis 提供了主从复制机制,但在单节点模式下,如果主节点出现故障,系统的可用性就会受到影响。即使通过 Redis Sentinel 可以实现自动故障转移,但在大规模应用场景中,仍然需要更高的可靠性和容错能力。
4.扩展性能差
- 在单节点模式下,Redis 的扩展性有限。当需要扩展存储容量或提升性能时,通常只能通过增加单台机器的硬件资源来实现,而无法通过简单地增加节点来水平扩展。
分布式系统发展的需要
随着互联网应用的迅猛发展,越来越多的系统需要处理海量数据和高并发请求。这些系统的特点包括:
1.海量数据处理
- 现代应用(如社交网络、电商平台、物联网等)通常需要处理和存储庞大的数据量,这些数据往往需要在内存中进行快速读写操作。
2.高性能要求
- 许多系统需要提供 7x24 小时不间断的服务,容忍节点故障成为了高可用性的基本要求。
3.弹性扩展能力
- 随着业务的发展,系统的负载可能会急剧增加。因此,系统需要能够快速、无缝地扩展以应对流量高峰。
正是在这样的大数据高并发的需求之下,Redis 集群方案应运而生。redis集群是对redis的水平扩容,即启动m个redis节点,将整个数据分布存储在这个m个节点中,每个节点存储总数据的1/m。
Redis集群(cluster)
如图所示案例
如图所示:3主3从组成的集群,每台master承担三分之一的请求和数据。集群中节点之间使用gossip协议进行通信,实现了去中心化。
Redis集群设计
提到集群,必然离不开数据分片。
什么是数据分片(data sharding)
数据分片(Data Sharding)是一种将数据集分割成更小的部分(称为"片"或"分片")并分布到多个存储单元(如数据库或服务器)上的技术。每个分片只存储数据集的一部分,从而使得系统能够水平扩展,处理更大规模的数据量和更高的并发请求。
Redis Cluster使用数据分片实现key的存储分布
Redis Cluster将集群划分为16384个槽位,数据库中所有的key进行hash计算后,都会落到16384个槽位中的其中一个槽位。那么key是如何定位到哪个槽位的呢,可以通过公式进行计算:CRC16(key)%16384,得到的值就是槽位;16384个槽位全部分配给cluster中的节点,每个节点维护自己的槽位,同时每个节点也会存储其他节点维护的槽位信息。
数据访问如何定位到具体的节点
如上图所示
- 1.如果客户端发送过来的key刚好在节点1所维护的范围之内,直接返回结果
- 2.如果客户端发送过来的key不在节点1所维护的范围之内,节点1会返回moved命令,告诉客户端所请求的key在节点2所维护的槽内,客户端收到命令之后,向正确的节点重新发送获取命令,拿到返回结果。
Redis集群工作原理
1.数据分片
当客户端发送写入请求时,Redis 集群使用 CRC16 算法对键进行哈希运算,得到一个哈希值,然后对 16384 取模,确定该键对应的槽。集群中的某个节点负责这个槽的所有键。
2.请求路由
客户端可以直接连接到集群中的任意节点。当请求的数据不在当前节点上时,该节点会返回一个 MOVED
响应,指引客户端向正确的节点发送请求。
3.故障检测与自动故障转移
Redis 集群中的每个节点都会通过 Gossip 协议交换彼此的状态。如果一个主节点被大多数主节点判定为不可用(称为主观下线,SDOWN
),集群会尝试将其从节点提升为主节点,并接管它负责的槽(称为客观下线,ODOWN
)。
4.数据一致性
Redis 集群采用异步复制机制,从节点异步地复制主节点的数据。如果主节点故障,部分数据可能丢失,尽管如此,Redis 集群仍然保证大多数情况下的高可用性和数据完整性。
Redis集群搭建
要搭建 Redis 集群,通常需要至少 6 个 Redis 实例(3 个主节点,3 个从节点)。以下是搭建 Redis 集群的基本步骤:
1.准备Redis实例
- 安装 Redis,并配置多个实例,每个实例配置不同的端口和
cluster-enabled yes
选项。
2.配置节点
- 每个 Redis 实例的配置文件(如
redis.conf
)中需要设置cluster-enabled yes
,并指定cluster-config-file
和cluster-node-timeout
。
3.启动Redis实例
- 启动所有 Redis 实例,使它们处于独立运行状态。
4.创建集群
- 使用 Redis 自带的
redis-cli
工具执行redis-cli --cluster create
命令,将多个 Redis 实例组成一个集群。 - 在执行此命令时,需要指定主从节点,并划分 16384 个槽给各个主节点。
5.检查集群状态
- 使用
redis-cli --cluster check
命令检查集群状态,确保所有节点正确配置并互相连接。
Redis集群的优缺点
优点
-
可扩展性:通过数据分片,Redis 集群能够水平扩展,将数据分布在多个节点上,从而扩展存储容量和吞吐量。
-
高可用性:通过主从复制和自动故障转移,Redis 集群能够在主节点故障时自动恢复,并继续提供服务。
-
无中心架构:Redis 集群采用无中心架构,避免了单点故障,使得整个集群更加稳定和健壮。
缺点
-
复杂性增加:与单节点 Redis 相比,Redis 集群的部署和管理更加复杂,特别是在处理节点故障和数据恢复时。
-
数据一致性问题:由于采用异步复制,Redis 集群在主节点故障时可能会丢失部分数据。
-
槽迁移:在动态扩展或缩减集群时,槽的迁移可能会导致暂时性的服务中断。
Redis集群的常见问题及优化
1.避免网络分区
- 网络分区可能导致集群的部分节点不可用。可以通过设置合理的超时时间和定期的节点检查来减少网络分区的影响。
2.优化读写性能
- 为了提高读写性能,可以通过增加从节点数量和使用客户端的智能路由机制来优化读写操作的分布
3.数据重分片
- 在扩展或缩减集群时,需要对槽进行重新分配。为了减少对服务的影响,可以使用 Redis 提供的工具
redis-trib
或者redis-cli
进行平滑的数据迁移。
4.监控与告警
- 使用监控工具(如 Redis Sentinel、Prometheus 等)实时监控 Redis 集群的状态,并配置告警策略,及时处理集群中的异常情况。
Redis 集群通过数据分片、主从复制和无中心架构,提供了一种高可用、可扩展的分布式键值存储解决方案。尽管它的部署和管理较为复杂,但对于大规模、高可用性需求的应用场景,Redis 集群是一个强大的工具。通过合理的配置、优化和监控,Redis 集群能够为分布式应用提供强大的数据支持和高性能的存储服务。