Redis Cluster 分片机制

server/2024/12/18 1:19:19/

Redis 集群是 Redis 提供的一种分布式实现,用于水平扩展数据存储能力。通过 Redis 集群,可以将数据分片存储在多个 Redis 节点上,同时提供高可用性和故障转移功能。

  • 分片(Sharding)
    • Redis 集群将数据划分为 16384 个插槽(slots),每个插槽代表一部分数据。
    • 每个 Redis 节点负责一部分插槽。数据键通过哈希函数映射到特定的插槽。
  • 主从复制(Replication)
    • 每个分片可以有一个主节点和多个从节点。
    • 主节点负责处理写请求,从节点作为备份,提供读取和故障切换。
  • 高可用性
    • 如果主节点故障,从节点会自动提升为主节点,确保服务可用性。
    • 这只限于每个分片的主从节点范围内,如果主从节点都挂了,那么这个分片上的数据是访问不到的。
  • 一致性模型
    • Redis 集群采用 最终一致性,在网络分区的情况下使用部分可用性,但不会丢失数据。

在 Spring Boot 项目中集成 Redis 集群,可以使用 Spring Data Redis 来进行配置。

在 Spring Boot 中,可以使用 RedisTemplate 来操作 Redis 数据。通过 Lettuce 客户端来实现 Redis 集群中的读写分离,可以利用 Lettuce 对读策略(ReadFrom)的支持,将读操作分配到从节点,写操作保持在主节点。这适用于 Redis 的主从复制架构。

创建一个配置类,用于设置 RedisTemplate。

  • 使用 LettuceConnectionFactory 配置 Redis 连接。
  • 设置 ReadFrom 策略,选择将读请求发送到从节点。
  • 使用 RedisTemplate 执行读写操作,Lettuce 会根据配置的 ReadFrom 策略自动选择节点。

配置 LettuceConnectionFactory,通过自定义 LettuceConnectionFactory 配置 Redis 集群连接和读策略。

可以将 Redis 集群的配置部分放在 application.yml 文件中,使配置更加灵活。

spring:redis:cluster:nodes:- 127.0.0.1:7000- 127.0.0.1:7001- 127.0.0.1:7002timeout: 5000lettuce:read-from: REPLICA_PREFERRED  # 优先从从节点读取pool:max-active: 8max-idle: 8min-idle: 0

在配置类中读取配置文件

@Configuration
public class RedisConfig {@Value("${spring.redis.cluster.nodes}")private List<String> clusterNodes;@Beanpublic LettuceConnectionFactory redisConnectionFactory() {// 使用配置文件中的 Redis 集群节点信息RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(clusterNodes);LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()// 使用配置文件中的读取策略.readFrom(ReadFrom.REPLICA_PREFERRED).build();return new LettuceConnectionFactory(clusterConfig, clientConfig);}// 配置 RedisTemplate,用于与 Redis 交互@Beanpublic RedisTemplate<String, Object> redisTemplate() {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory());// 设置序列化器template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(new StringRedisSerializer());return template;}
}
  • read-from 配置项说明:
    • MASTER: 所有操作都在主节点执行(默认)。
    • MASTER_PREFERRED:优先从主节点读取数据,如果主节点不可用则从从节点读取。
    • REPLICA: 所有读取操作都从从节点执行。
    • REPLICA_PREFERRED: 优先从从节点读取,如果没有可用从节点则读取主节点。
    • ANY: 读取请求可以从任意节点执行(包括主节点和从节点)。

RedisTemplate 会根据配置的 LettuceConnectionFactory,自动进行读写分离。写操作会默认发往主节点,而读操作则根据 ReadFrom 策略发往从节点。

在 Redis 集群中,为了在执行 Lua 脚本时能够确保操作的多个键位于同一哈希槽中,Redis 引入了 哈希标签(Hash Tag) 的概念。

  • 哈希标签 是一种机制,用来告诉 Redis 集群哪些键应该被视为一个整体,映射到同一个哈希槽(Hash Slot)中。
  • 哈希标签是通过将键名的一部分用大括号 {} 包围来实现的。Redis 只会对 {} 内部的内容进行哈希计算,以决定该键的哈希槽位置。
  • 如果你有两个键 key1 和 key2,通常它们会映射到不同的哈希槽中。然而,如果使用哈希标签,例如 user:{123} 和 order:{123},那么 123 部分会被用于哈希计算,使这两个键落在同一个哈希槽中。
  • user:{123} 和 order:{123} 将会落在同一个哈希槽。
  • user:123 和 order:123 将可能落在不同的哈希槽中。
  • 在 Redis 集群环境中,当执行 Lua 脚本时,所有涉及的键必须位于同一个哈希槽中,否则会报错,因为 Redis 集群无法在不同的节点之间自动协调 Lua 脚本。使用哈希标签可以确保多个相关键位于同一哈希槽,这样在执行 Lua 脚本时可以正常运行。

在 Redis 集群架构中,如果发生数据倾斜(即某些节点存储的数据明显多于其他节点),这可能会导致部分节点的负载过高,影响性能和稳定性。为了解决数据倾斜问题,可以采取以下措施:

调整哈希槽的分配
Redis 集群中使用哈希槽(hash slots)来分布数据,每个节点管理一定数量的哈希槽。如果某些节点的哈希槽数量明显多于其他节点,可能会导致数据倾斜。可以通过 redis-cli --cluster rebalance 命令重新分配哈希槽,让数据更均匀地分布在各个节点上。

# <node-address>:<port> 表示集群中任一主节点的地址和端口,用于连接到 Redis 集群。Redis 会通过这个节点获取集群的状态信息。
# 最终重新平衡哈希槽的分配是针对整个集群的。
redis-cli --cluster rebalance --cluster-use-empty-masters <node-address>:<port>

添加新的节点:增加新的节点可以减轻现有节点的负担,并改善数据分布:

  • 使用 redis-cli --cluster add-node 命令将新节点加入到集群中。
  • 加入新节点后,使用 redis-cli --cluster rebalance 来重新平衡数据和哈希槽的分布,使得新节点参与数据存储。

迁移数据:可以手动或自动将数据从高负载节点迁移到其他节点:

  • 使用 redis-cli --cluster reshard 命令将部分哈希槽从高负载节点迁移到其他节点。
  • 迁移数据时,需要指定源节点、目标节点以及要迁移的哈希槽数量。
redis-cli --cluster reshard <node-address>:<port>
  • 输入目标哈希槽数量和目标节点,Redis 会自动完成迁移。

选择合适的分片键:如果数据倾斜是由于分片键选择不合理造成的,可以考虑重新选择分片键:

  • 使用均匀分布的数据字段作为分片键,例如随机数或 UUID,而不是用户 ID 等容易造成数据集中化的字段。
  • 使用哈希策略来确保分片键的散列值在集群中均匀分布。

监控和优化:通过监控工具持续关注 Redis 集群的运行状态,及早发现并解决数据倾斜问题:

  • 使用 redis-cli --cluster info 或其他 Redis 监控工具来查看每个节点的哈希槽和内存使用情况。
  • 借助 INFO 命令获取每个节点的状态信息,了解内存和负载分布。
  • 定期评估数据分布,必要时进行数据迁移或重新分配哈希槽。

在创建 Redis 集群时,哈希槽的分配通常是自动进行的,但也可以手动分配哈希槽给每个主节点。

首先,使用以下命令创建一个 Redis 集群,并为每个主节点分配哈希槽。

redis-cli --cluster create \
192.168.1.1:6379 \
192.168.1.2:6379 \
192.168.1.3:6379 \
192.168.1.4:6379 \
--cluster-replicas 1 \
--cluster-slots 16384

此命令将创建一个包含 4 个主节点的 Redis 集群,并为每个主节点指定 16384 个哈希槽。

手动分配哈希槽

# 为主节点 1 分配哈希槽 0 - 4095
redis-cli --cluster addslots 192.168.1.1:6379 0 4095# 为主节点 2 分配哈希槽 4096 - 8191
redis-cli --cluster addslots 192.168.1.2:6379 4096 8191# 为主节点 3 分配哈希槽 8192 - 12287
redis-cli --cluster addslots 192.168.1.3:6379 8192 12287# 为主节点 4 分配哈希槽 12288 - 16383
redis-cli --cluster addslots 192.168.1.4:6379 12288 16383

http://www.ppmy.cn/server/151043.html

相关文章

leetcode---mysql

619. 只出现一次的最大数字 - 力扣&#xff08;LeetCode&#xff09; MyNumbers 表&#xff1a; ------------------- | Column Name | Type | ------------------- | num | int | ------------------- 该表可能包含重复项&#xff08;换句话说&#xff0c;在SQL中&…

外卖开发(八)—— SpringTask(定时任务) 和 WebSocket网络协议

外卖开发&#xff08;八&#xff09;—— SpringTask 和 WebSocket 一、利用SpringTask完成定时任务1、cron表达式2、springtask实现 二、使用webSocket实现接单、催单提醒1、代码分析2、催单提醒 一、利用SpringTask完成定时任务 Spring Task是Spring框架提供的任务调度工具&…

Scala——泛型

背景&#xff1a;你是一个程序员&#xff0c;老板让你写一个函数&#xff0c;用来获取列表中的中间元素 定义函数的格式&#xff1a; def 函数名字&#xff08;参数1&#xff1a;类型1&#xff09;&#xff1a;返回值的类型{} package test40 //泛型 //List&#xff08;1,2,3…

ADB在浏览器中:ya-webadb项目安装与配置完全指南

ADB在浏览器中&#xff1a;ya-webadb项目安装与配置完全指南 ya-webadb ADB in your browser [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/ya/ya-webadb 项目基础介绍与编程语言 ya-webadb 是一个由 Yume-chan 开发的开源项目&#xff0c;它实现了ADB&#x…

取证工具 iOS Forensic Toolkit: macOS\Windows\Linux 不同版本的比较

ElcomSoft 公司致力于提供符合许可法规的数据取证解决方案&#xff0c;满足所有相关的法律要求。 Elcomsoft iOS Forensic Toolkit 软件提供面向 iPhone/iPad/iPod 设备的取证功能。该软件有三种版本&#xff0c;分别用于 macOS、Windows 和 Linux 版本系统。 macOS、Windows…

OpenCV图片矫正

在计算机视觉领域&#xff0c;图片矫正是一项非常重要的技术&#xff0c;特别是在处理因拍摄角度问题导致的图像失真时。 实验原理 图片矫正主要依赖于透视变换&#xff08;Perspective Transformation&#xff09;。透视变换是一种几何变换&#xff0c;可以将图像中的一个四…

每日十题八股-2024年12月16日

1.垃圾回收算法哪些阶段会stop the world? 2.minorGC、majorGC、fullGC的区别&#xff0c;什么场景触发full GC 3.垃圾回收器 CMS 和 G1的区别&#xff1f; 4.什么情况下使用CMS&#xff0c;什么情况使用G1? 5.G1回收器的特色是什么&#xff1f; 6.GC只会对堆进行GC吗&#x…

RabbitMQ中的Work Queues模式

在现代分布式系统中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信和解耦系统的关键组件之一。RabbitMQ 是一个广泛使用的开源消息代理软件&#xff0c;支持多种消息传递模式。其中&#xff0c;Work Queues&#xff08;工作队列&#xff09;模式是一…