首页 > 数据库 >优化 Redis 集群缓存分配:解决节点间分配不均导致内存溢出问题

优化 Redis 集群缓存分配:解决节点间分配不均导致内存溢出问题

时间:2023-08-15 18:00:09浏览次数:42  
标签:缓存 predixy Redis 0.213 192.168 分配 used memory 节点

一、Redis 集群部署简介

在现代应用程序中,缓存被广泛应用以提高性能和减轻后端数据库的压力。本文将探讨面对 Redis 集群缓存分配不均问题时的解决方法。

我们的 Redis 集群部署包括 3 主 3 从,每个节点分配内存 4G(服务器总内存32G),内存淘汰策略相同:volatile-lru

二、问题描述

在性能测试过程中,通过 pinpoint 监控发现报错:

Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: OOM command not allowed when used memory> 'maxmemory'

三、排查、分析问题过程

1. 查看内存使用情况

清空缓存后,再次执行性能测试一段时间,使用 info memory 查看各节点内存使用情况,发现 2、6 节点内存快速上升,其它节点内存使用率很低。

例如,2 节点内存达到 3.81G,6 节点内存达到 3.8G,而其他 4 个节点内存仅为 80M 左右。

[root@iZ2ze3e0bvnd1hf5xbkxn3Z redis01]# ./redis-cli -h 192.168.0.213 -p 6692 -c -a Tiye@54L2!
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.213:6692> info memory
# Memory
used_memory:4095914816
used_memory_human:3.81G
used_memory_rss:4473937920
used_memory_rss_human:4.17G
used_memory_peak:4105896552
used_memory_peak_human:3.82G
used_memory_peak_perc:99.76%
used_memory_overhead:5159996
used_memory_startup:1483832
used_memory_dataset:4090754820
used_memory_dataset_perc:99.91%
allocator_allocated:4095978056
allocator_active:4728315904
allocator_resident:4765335552
total_system_memory:33019609088
total_system_memory_human:30.75G
used_memory_lua:30720
used_memory_lua_human:30.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:4096000000
maxmemory_human:3.81G
maxmemory_policy:volatile-lru
allocator_frag_ratio:1.15
allocator_frag_bytes:632337848
allocator_rss_ratio:1.01
allocator_rss_bytes:37019648
rss_overhead_ratio:0.94
rss_overhead_bytes:-291397632
mem_fragmentation_ratio:1.09
mem_fragmentation_bytes:378064128
mem_not_counted_for_evict:0
mem_replication_backlog:1048576
mem_clients_slaves:20512
mem_clients_normal:2603516
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0
[root@iZ2ze3e0bvnd1hf5xbkxn3Z redis02]# ./redis-cli -h 192.168.0.213 -p 6691 -c -a Tiye@54L2!
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.213:6691> info memory
# Memory
used_memory:84125536
used_memory_human:80.23M
used_memory_rss:107753472
used_memory_rss_human:102.76M
used_memory_peak:109050608
used_memory_peak_human:104.00M
used_memory_peak_perc:77.14%
used_memory_overhead:9292232
used_memory_startup:1483832
used_memory_dataset:74833304
used_memory_dataset_perc:90.55%
allocator_allocated:84208120
allocator_active:102572032
allocator_resident:108343296
total_system_memory:33019609088
total_system_memory_human:30.75G
used_memory_lua:30720
used_memory_lua_human:30.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:4096000000
maxmemory_human:3.81G
maxmemory_policy:volatile-lru
allocator_frag_ratio:1.22
allocator_frag_bytes:18363912
allocator_rss_ratio:1.06
allocator_rss_bytes:5771264
rss_overhead_ratio:0.99
rss_overhead_bytes:-589824
mem_fragmentation_ratio:1.28
mem_fragmentation_bytes:23669520
mem_not_counted_for_evict:0
mem_replication_backlog:1048576
mem_clients_slaves:20512
mem_clients_normal:2603360
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0

2. 分析主从关系

 使用 cluster nodes 命令获取 Redis 集群中所有节点的信息,并判断各节点主从关系。
[root@iZ2ze3e0bvnd1hf5xbkxn3Z redis06]# ./redis-cli -h 192.168.0.213 -p 6696 -c -a Tiye@54L2!
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.213:6696> cluster nodes
e73a5ec3e26ed23e9b4bf56811527c8820a7bd79 192.168.0.213:6696@16696 myself,slave e2a678a004bc99e76180a16a6a41e2cad1c96052 0 1691992895000 2 connected
25317f0f8f7b2eebdbdc0914c659ab96ed3dab18 192.168.0.213:6693@16693 master - 0 1691992897074 3 connected 10923-16383
27aba75f54cccbb42125edb20f2f9d7c2f777d6c 192.168.0.213:6695@16695 slave 5e08015f75cdb05b1c7ed78dead1d85cdb0e838f 0 1691992895070 1 connected
5e08015f75cdb05b1c7ed78dead1d85cdb0e838f 192.168.0.213:6691@16691 master - 0 1691992894068 1 connected 0-5460
053916b96426f790244d984cad3f69f9151e4ece 192.168.0.213:6694@16694 slave 25317f0f8f7b2eebdbdc0914c659ab96ed3dab18 0 1691992896072 3 connected
e2a678a004bc99e76180a16a6a41e2cad1c96052 192.168.0.213:6692@16692 master - 0 1691992894000 2 connected 5461-10922

根据节点信息中的master字段判断该节点是主节点还是从节点。如果节点的master字段为空,则表示它是主节点;如果master字段不为空,则表示它是从节点,并且该字段的值是对应的主节点ID。
e2a678a004bc99e76180a16a6a41e2cad1c96052 节点是主节点,e73a5ec3e26ed23e9b4bf56811527c8820a7bd79 节点是从节点,并且它的主节点是 e2a678a004bc99e76180a16a6a41e2cad1c96052

综上判断:redis集群6个节点,其中2节点的从节点是6节点。

3. 分析哈希槽数量分配

在 Redis 集群中的任意一个节点上执行 cluster slots 命令,分析哈希槽数量分配是否均匀

192.168.0.213:6692> cluster slots
1) 1) (integer) 0
2) (integer) 5460
3) 1) "192.168.0.213"
2) (integer) 6691
3) "5e08015f75cdb05b1c7ed78dead1d85cdb0e838f"
4) 1) "192.168.0.213"
2) (integer) 6695
3) "27aba75f54cccbb42125edb20f2f9d7c2f777d6c"
2) 1) (integer) 5461
2) (integer) 10922
3) 1) "192.168.0.213"
2) (integer) 6692
3) "e2a678a004bc99e76180a16a6a41e2cad1c96052"
4) 1) "192.168.0.213"
2) (integer) 6696
3) "e73a5ec3e26ed23e9b4bf56811527c8820a7bd79"
3) 1) (integer) 10923
2) (integer) 16383
3) 1) "192.168.0.213"
2) (integer) 6693
3) "25317f0f8f7b2eebdbdc0914c659ab96ed3dab18"
4) 1) "192.168.0.213"
2) (integer) 6694
3) "053916b96426f790244d984cad3f69f9151e4ece"

根据提供的哈希槽信息,我们可以计算出以下三个哈希槽的数量:

  • 第一个哈希槽范围:0到5460,共计5461个槽位。
  • 第二个哈希槽范围:5461到10922,共计5462个槽位。
  • 第三个哈希槽范围:10923到16383,共计5461个槽位。

综上判断:这三个哈希槽的数量分别是5461、5462和5461。即,哈希槽数量分配均匀。

四、尝试解决方案

方法一:使用 Predixy 代理

跟产品开发人员沟通,没有做predixy适配,但可以尝试配置。最后发现产品启动服务报错,放弃该方案。尝试过程记录如下:

1. 下载安装包

wget https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz

2. 解压&修改配置文件

tar zxvf predixy-1.0.5-bin-amd64-linux.tar.gz
cd predixy-1.0.5

① 编辑conf/predixy.conf文件

 Include cluster.conf  #Include cluster.conf解开注释
# Include sentinel.conf
# Include try.conf    #注释掉Include try.conf
## Worker threads
WorkerThreads 3 #从1改为3,表示开启的进程数

② 编辑conf/cluster.conf文件

lusterServerPool {
    MasterReadPriority 0 #设置为0代表开启读写分离
    Password Tiye@54L2! #redis集群密码
    StaticSlaveReadPriority 50
    DynamicSlaveReadPriority 50
    RefreshInterval 1
    ServerTimeout 1
    ServerFailureLimit 10
    ServerRetryTimeout 1
    KeepAlive 120
    Servers {
        + 192.168.0.213:6691 #redis集群节点
        + 192.168.0.213:6692
        + 192.168.0.213:6693
        + 192.168.0.213:6694
        + 192.168.0.213:6695
        + 192.168.0.213:6696
    }
}

   配置文件解析文档:https://github.com/joyieldInc/predixy/blob/master/doc/config_CN.md

3. 创建脚本文件

① 创建启动和停止脚本,放到predixy-1.0.5目录下

mkdir -p /opt/predixy-1.0.5/logs/
cd /opt/predixy-1.0.5/bin

② 创建启动脚本up.sh

#!/bin/bash
path=`pwd`
nohup $path/bin/predixy conf/predixy.conf > $path/logs/predixy.log 2>&1 &

③ 查看日志

tail -f logs/predixy.log

④ 创建停止脚本down.sh

#!/bin/bash
path=`pwd`
pid=`ps -ef | grep $path/bin/predixy | grep -v grep | awk '{print $2}'`
kill -9 $pid

4. 测试predixy代理

./redis-cli -p 7617
127.0.0.1:7617> mset b1 b2
OK
127.0.0.1:7617> get b1
"b2"

5. 启动应用验证predixy代理

将应用配置文件中的集群地址修改为predixy地址,应用服务启动报错:

...Autowired annotation is not supported on static fields...

方法二:缩减为 4 个节点

尝试缩减为 4 个节点,但创建集群时提示至少需要 3 个主节点,因此该方案也不可行。

*** ERROR: Invalid configuration for cluster creation.
*** Redis Cluster requires at least 3 master nodes.
*** This is not possible with 4 nodes and 1 replicas per node.
*** At least 6 nodes are required 

方法三:修改集群节点内存

最终解决方案是修改集群节点内存:1、3、4、5 节点分配内存 3G,2、6 节点分配内存 8G。

五、结论

面对 Redis 集群缓存分配不均的问题,我们可以通过逐步的优化方法来解决。首先,了解节点信息、主从关系和缓存占用情况,然后分析哈希槽分布情况,尝试不同的优化方案,最后通过调整内存分配来解决问题。

标签:缓存,predixy,Redis,0.213,192.168,分配,used,memory,节点
From: https://www.cnblogs.com/n00dle/p/17631331.html

相关文章

  • Redis(2):四种模式(单机、哨兵、集群、主从复制)部署
    学习自:Redis的四种模式-何童鞋-博客园深入理解Redis的部署模式四种模式的探索(redis部署四种模式)-数据库运维技术服务redis部署和运行原理redis的三种部署方式_小咪咪的技术博客_51CTO博客上一节:Redis(1):四种模式(单机、哨兵、集群、主从复制)原理0、所写m:master,主服务器s:s......
  • Linux的Redis安装部署
    简介redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。redis的特点就是:快,可以基于内存存储数据并提供超低延迟、超快的检索速度一般用于在系统中提供快速缓存的能力。安装配置EPEL仓库EPEL的全称叫ExtraPackagesforEnt......
  • redis cluster查询过期key
    redis以前也就部署好没管过,这次用的云上的rediscluster,程序没有设置过期时间,所以要求手动去删除key。按以前的习惯redis-cli登录keys*查询不行,原来cluster下key是存在不同的slot下的,要去每个slot下找#查看cluster信息,特别是cluster_slots_ok的数量clusterinfocluster的slot是从......
  • Redis专题-队列
    Redis专题-队列首先,想一想Redis适合做消息队列吗?1、消息队列的消息存取需求是什么?redis中的解决方案是什么?无非就是下面这几点:0、数据可以顺序读取1、支持阻塞等待拉取消息2、支持发布/订阅模式3、重新消费4、消息不丢失5、消息可堆积那我们来看看redis怎么满足这些需......
  • SpringBoot3集成Redis
    目录一、简介二、工程搭建1、工程结构2、依赖管理3、Redis配置三、Redis用法1、环境搭建2、数据类型3、加锁机制四、Mybatis缓存1、基础配置2、自定义实现五、参考源码标签:Redis.Mybatis.Lock;一、简介缓存在项目开发中,基本上是必选组件之一,Redis作为一个key-value存储系统,具......
  • 虹科干货 | 化身向量数据库的Redis Enterprise——快速、准确、高效的非结构化数据
    用户期望在他们遇到的每一个应用程序和网站都有搜索功能。然而,超过80%的商业数据是非结构化的,以文本、图像、音频、视频或其他格式存储。RedisEnterprise如何实现矢量相似性搜索呢?答案是,将AI驱动的搜索功能集成到RedisEnterprise中,以实现矢量相似性搜索。 RedisEnterprise如何......
  • centos 7安装redis
    您好,这是在CentOS7上安装Redis的详细指南1:安装依赖项:Redis是用C语言开发的,因此在安装之前,您必须确保服务器已经安装了gcc。您可以通过以下命令检查机器是否安装:gcc-v。如果没有安装,您可以通过以下命令安装:yuminstall-ygcc。下载Redis安装包并解压缩:wgethttps://downlo......
  • redis查询 第1个数据库,而不是默认的第0个数据库
    redis查询第1个数据库,而不是默认的第0个数据库 spring.redis.database=1默认:spring.redis.database=0car-test:0>getcar:info:detail:id001NULL##切换数据库car-test:0>select1OKcar-test:1>getcar:info:detail:id001{"id":444186}car-test:1>redis有......
  • redis数据结构字典
    redis数据结构字典数据结构Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对。哈希表typedefstructdictht{//哈希表数组dictEntry**table;//哈希表大小unsignedlongsize;//哈希表大小掩码,用于......
  • yun缓存软件包
    #!/bin/bashpackagename=$1whichyumdownloader||yuminstall-yyum-utils&>/dev/nullls/bak/pkg||mkdir-p/bakpkgyumdownloader--resolve--destdir=/bakpkg/$packagenameyum缓存软件包 CDIR="$(cd"$(dirname"$0")";......