Loading... # 方案介绍 当前,整个微服务集群由30+容器组成,主要依赖redis集群用于实时数据缓存。但是,在项目早期,程序员在redis集群中使用了大Key,虽然年中的时候进行了修复,但是依旧存在。由此,造成每天晚高峰期间,redis集群各节点cpu利用率偏差较大,而其中一台甚至达到瓶颈,严重时出现拒绝服务现象。 为此,研发有意对大Key继续进行优化,但是眼前通过增加高主频主机替换承载压力大的redis节点服务成为快速的方案。该方案主要以原redis3主3从集群为基础,增加1台高主频主机,运行redis服务,并将该服务作为slave角色加入集群,修改各服务在zk中的redis信息配置,并逐步实施重启以生效。 # 方案论证 ## 我现在有1个3主3从的redis集群,因为有大key问题,在研发没有调试好前,恐怕我只有通过升级大key所在redis节点的cpu主频来提高性能 对于大 key 问题,升级 CPU 主频可能会有所帮助,因为这将提高 Redis 的计算能力。然而,这并不是解决大 key 问题的根本方法。大 key 问题通常是由于设计不当或数据结构使用不当引起的,因此最好的解决方案通常是优化你的数据结构和查询方式。 以下是一些可能的优化策略: 1. **优化数据结构**:如果你的大 key 是一个列表或集合,并且你通常只需要访问其一部分数据,那么你可能会考虑将它们分割成多个小 key。这样,每次查询只需要处理一小部分数据,可以大大提高效率。 2. **使用哈希**:如果你的大 key 是一个字符串,那么你可能会考虑使用哈希来存储它。哈希可以将大量数据分布在多个小 key 中,从而减少单个查询的数据量。 3. **使用懒删除或渐进式 rehash**:如果你需要删除一个大 key,那么你可以使用 `UNLINK` 命令进行异步删除,或者使用 `HDEL` 或 `SREM` 等命令逐步删除 key 中的元素。 4. **使用 SCAN 命令**:如果你需要遍历一个大 key,那么你可以使用 `SCAN`、`HSCAN`、`SSCAN` 或 `ZSCAN` 等命令,这些命令可以在不阻塞 Redis 服务器的情况下逐步遍历所有元素。 5. **优化查询**:尽量避免全表扫描,尽量使用索引进行查询。 记住,升级硬件只是临时的解决方案,优化你的数据结构和查询方式才是根本的解决方案。 ## 是的,我必须得在周五来临之前进行此次升级。为此,我的方案是在cloud provider上,购买了1台cpu强劲的云主机,并且部署好了redis服务,下面我将它作为大key问题节点的slave角色加入,然后修改zk中各个微服务配置的集群node信息,然后再进行cluster failover。你看如何? 你的方案看起来是可行的。在一个 Redis 集群中添加新的 slave 节点,并将它提升为 master,是一种常用的扩容和升级策略。以下是一些你可能需要注意的点: 1. **数据同步**:当你将新的节点添加为 slave 时,它将从当前的 master 节点复制所有的数据。这可能需要一些时间,具体取决于你的数据量。在这个过程中,你需要确保你的网络带宽足够,以及你的 master 节点有足够的性能来处理这个复制操作。 2. **配置更新**:当你将新的节点提升为 master 之后,你需要更新你的微服务的配置,以便它们知道新的 master 节点的地址。这可能需要重启你的微服务,或者如果你的微服务支持动态配置,你可以在不重启的情况下更新配置。 3. **故障转移**:`CLUSTER FAILOVER` 命令可以让一个 slave 节点成为 master,但是这个过程可能会导致一段时间的服务中断。你需要确保你的应用可以处理这种情况,或者你需要在服务使用量较低的时候进行这个操作。 4. **监控**:在整个过程中,你需要密切监控你的 Redis 集群和你的微服务的性能,确保没有任何问题。如果出现问题,你需要能够快速回滚你的更改。 请确保你已经在一个测试环境中验证了你的方案,然后再在生产环境中执行。 ## 有个问题,在我将新节点加入集群后,此时redis集群将由7个节点,新加入的属于slave角色,而zk中关于微服务redis nodes的配置没有更新,这样对于使用jedis调用redis服务的微服务来说,是否正常? 当你在 Redis 集群中添加新的 slave 节点时,如果你没有更新 Jedis 客户端的配置,那么客户端将不会知道新节点的存在。这意味着客户端将不会向新的 slave 节点发送任何请求,除非你手动更新配置并重新启动客户端。 然而,从 Redis 集群的角度来看,这并不会影响集群的正常运行。新的 slave 节点将正常地从它的 master 节点复制数据,并且在 master 节点出现问题时,它可以被提升为新的 master 节点。 在你执行 `CLUSTER FAILOVER` 命令并将新的 slave 节点提升为 master 之后,你需要更新 Jedis 客户端的配置,以便它们知道新的 master 节点的地址。如果你不这样做,那么客户端可能会尝试向旧的 master 节点发送请求,这可能会导致错误。 总的来说,添加新的 slave 节点并不会影响使用 Jedis 调用 Redis 服务的微服务的正常运行,但是你需要在适当的时候更新客户端的配置,以便它们知道新的 master 节点的地址。 ## 好的,谢谢。我想再对我的具体细节进行提问。当前,redis集群是版本4,对于这个版本的redis,新增1个新的节点的过程和命令大概是什么? 对于 Redis 4.0 版本,你可以使用以下步骤和命令来添加一个新的节点到你的集群: 1. **在新节点上安装 Redis**:首先,你需要在新的节点上安装和配置 Redis。你可以从 Redis 的官方网站下载源代码并编译,或者你可以使用你的包管理器(如 apt 或 yum)来安装。 2. **启动新节点的 Redis 服务**:你需要使用 `redis-server` 命令启动新节点的 Redis 服务。你可能需要指定一个配置文件,这个配置文件应该包含集群的设置,例如 `cluster-enabled yes`。 3. **添加新节点到集群**:你可以使用 `redis-cli` 工具的 `CLUSTER MEET` 命令来将新的节点添加到集群。你需要在一个已经存在的集群节点上运行这个命令,并指定新节点的 IP 地址和端口。例如,如果新节点的 IP 地址是 192.0.2.0,端口是 6379,你可以使用以下命令: ``` redis-cli -h <existing-node-ip> -p <existing-node-port> CLUSTER MEET 192.0.2.0 6379 ``` 4. **配置新节点的角色**:默认情况下,新的节点将作为一个 master 节点加入到集群。如果你想将新的节点作为一个 slave 节点,你需要使用 `CLUSTER REPLICATE` 命令,并指定一个现有的 master 节点的节点 ID。例如: ``` redis-cli -h 192.0.2.0 -p 6379 CLUSTER REPLICATE <master-node-id> ``` 请注意,这些步骤可能需要根据你的具体环境进行一些调整。在执行这些操作之前,你应该先在一个测试环境中验证它们。 ## 好的。redis的rebalance和reshard分别代表什么意思? 在 Redis 集群中,"rebalance" 和 "reshard" 是两个常见的操作,它们都涉及到如何在集群节点之间分配和重新分配数据。 **Rebalance**:重新平衡(rebalance)是指将 Redis 集群中的数据均匀地分布在所有的节点上。这通常在你添加或删除节点后进行,以确保每个节点都有大致相等的数据量。重新平衡是通过将数据(也就是 key-value 对)从一个节点移动到另一个节点来完成的。 **Reshard**:重新分片(reshard)是指改变 Redis 集群的分片数量。在 Redis 中,数据是按照分片(shard)来存储的,每个分片包含一部分的数据。每个分片都有一个或多个节点负责处理。当你进行重新分片时,你是在改变这些分片的数量和/或它们在节点之间的分配。这通常涉及到移动大量的数据,并可能需要一段时间来完成。 这两个操作都是为了优化 Redis 集群的性能和存储效率。然而,它们都需要谨慎进行,因为在过程中可能会影响到集群的性能。在执行这些操作之前,你应该先在一个测试环境中验证它们,并确保你有一个恢复数据的备份或计划。 # 方案实施 ## Day1 2023年11月23日 04:00 登录redis3节点,执行添加slave任务 ``` cat <<'EOF'>/root/.bashrc export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/opt/xxx/ruby/bin EOF # 将slave加入集群 cd /opt/xxx/redis/utils/create-cluster ../../src/redis-trib.rb add-node --slave --master-id 3f9435a39a9262691007926c7a7dd75792f9ba4b 10.10.117.147:7007 10.19.190.44:7004 3f94 是集群节点10.19.190.44:7004在redis集群中的id 10.10.117.247:7007是新节点redis实例的地址和端口 10.19.190.44:7004是未操作前redis集群中负载较高的redis实例的地址和端口 ``` ``` # 检查集群节点 cluster nodes ``` ![2023-11-23T04:53:41.png][1] 检查日志,发现有节点报WARN日志,大意是已经发现了新加入的节点10.10.117.147:7070 ![2023-11-23T04:41:45.png][2] 此时,我打算提前对一批非核心微服务进行zk中redis信息更改并重启。当使用zk-shell的get命令查看对应微服务在zk中的配置信息时,发现配置的redis节点信息居然是一个ULB的内部负载均衡,且是报文转发的。如此一来,就无需修改了,只需要在此报文转发型ULB的后端服务中,增加新增的redis节点。 ``` [root@10-10-117-147 network-scripts]# cat ifcfg-lo:1 DEVICE=lo:1 IPADDR=10.10.172.209 NETMASK=255.255.255.255 ifup lo:1 ifconfig lo:1 ``` ![2023-11-23T04:44:49.png][3] ![2023-11-23T04:45:17.png][4] ## Day2 2023年11月24日 04:00 凌晨起得早,大概也就3点多。首先,点了点页面,看了看现在线上的情况,也让自己清醒清醒,毕竟待会有“大手术”做。 按照经验操作,整个过程还算顺利。在所有微服务重启后,新加入的redis slave节点已经与微服务实现共同运行。 最后,使用命令 ``` # 使用redis命令行工具连接新加入的slave节点,然后,使用如下命令实现切换。 redis-cli -h xxxx -p 7007 -a xxx cluster failover ``` ![2023-11-24T08:58:47.png][5] 切换后可以看出,业务量并没有减少,cpu使用率也并没有降低,但是延迟小了,效率高了。 ![2023-11-24T08:12:31.png][6] [1]: https://www.sddts.cn/usr/uploads/2023/11/3070018411.png [2]: https://www.sddts.cn/usr/uploads/2023/11/1263843109.png [3]: https://www.sddts.cn/usr/uploads/2023/11/3272414822.png [4]: https://www.sddts.cn/usr/uploads/2023/11/504741081.png [5]: https://www.sddts.cn/usr/uploads/2023/11/308173335.png [6]: https://www.sddts.cn/usr/uploads/2023/11/3003091596.png 最后修改:2024 年 05 月 11 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏