方案介绍

当前,整个微服务集群由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 命令进行异步删除,或者使用 HDELSREM 等命令逐步删除 key 中的元素。
  4. 使用 SCAN 命令:如果你需要遍历一个大 key,那么你可以使用 SCANHSCANSSCANZSCAN 等命令,这些命令可以在不阻塞 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

检查日志,发现有节点报WARN日志,大意是已经发现了新加入的节点10.10.117.147:7070

2023-11-23T04:41:45.png

此时,我打算提前对一批非核心微服务进行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
2023-11-23T04:45:17.png

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

切换后可以看出,业务量并没有减少,cpu使用率也并没有降低,但是延迟小了,效率高了。
2023-11-24T08:12:31.png

最后修改:2024 年 05 月 11 日
如果觉得我的文章对你有用,请随意赞赏