Redis内存占用过高,该如何解决?(redis内存占用过高,该如何解决)
mhr18 2024-10-24 11:13 42 浏览 0 评论
一、需求背景
1.1背景
项目历史悠久,迭代多年,经过众多同事接手。对于缓存的使用存在许多不合理之处,导致了许多keys冗余:
- 编码层面:序列化方式不统一、数据结构使用不合理造成存储空间冗余、用户数据膨胀导致数据堆积产生的大key、没有设置过期时间的key等等。
- 业务层面:历史需求、运营活动等,存在一批已经停止使用但一直存储在实例中的key。
1.2优化的原因
1.2.1昂贵的费用
目前项目采用了128G的集群,八台实例,平均内存占用70-80G,大概2亿个key。Redis的费用非常昂贵,贴一张阿里云相近规格收费的图。
1.2.2大key存在的隐患
大key会带来的问题如下:
1、集群模式在slot分片均匀情况下,会出现数据和查询倾斜情况,部分有大key的Redis节点占用内存多,QPS高。
2、大key相关的删除或者自动过期时,会出现qps突降或者突升的情况,极端情况下,会造成主从复制异常,Redis服务阻塞无法响应请求。
基于以上原因,需要对项目的缓存进行优化。
二、优化思路
2.1分析key的使用情况
谈到缩容,最直接的方法肯定是分析出占用内存最大的key,对其进行优化。从此处开始,文章中提到的大key不单指单个大key,类似几百万数据的hash集合;也包含了一类key的占用了较大的空间,例如实例存在1000万个 user:info:{userid} 的string类型的key,我们也将它称为大key。
2.1.1key的采集与分析
列举分析常用的样本采集方案
方案 | 优缺点 | 是否选用 |
bigkeys命令 | 优点:使用简单 缺点:耗时较长,只能统计五种基础数据,无法对一类key名称进行匹配,只能找出单个大key | 否 |
在单台实例执行bgSave,dump下来对应的RDB文件,使用对应的分析工具进行分析。我们使用的是rdb_bigkeys | 优点:对业务不造成影响,本地数据,随时可以进行分析 缺点:时效性较弱 | 是 |
扫描脚本,使用scan命令配合扫描整台实例的keys | 优点:支持任意数据类型,时效性高 缺点:虽然scan命令不阻塞主线程,但是大范围扫描keys还是会加重实例的IO,可以闲时再执行。 | 否 |
分析keys的使用,对于时效性要求肯定是不高的,所以选用了方案2,分析RDB文件,并定位key的影响范围。截取部分分析结果图:
2.1.2优化方案
分析出了大key后,就可以按keys的占用空间来排序,从前往后按优先级归纳需要优化的keys。项目中keys存在的问题在最开始已经总结过。
对于不合理的keys,我们分为两类:
- 需要优化改进的keys
- 可以直接删除的keys
一、需要优化改进的keys
这就需要针对业务场景做针对性处理了,只能给出一些典型例子的建议:
- 选择合理的过期时间,结合业务能短尽量短。
- 选择合适的数据结构:例如我们现在设计一个key用于存储一些信息。假定key和value的大小用了16个字节,但是由于RedisObject32b(元数据 8b+SDS指针8b+16b key value数据)、dictEntry 32b(三个指针24b,jellmoc分配出32b)。导致一个string的key需要存64b,冗余了很多数据。 优化方式:将每个Key取hash code,然后按照业务对指定的业务分成n片,用hash code对n取模。此时我们使用hset info:{hash code%n} {key} {value}存储,通过修改hash-max-ziplist-entries(用压缩列表保存时哈希集合中的最大元素个数)和hash-max-ziplist-value(用压缩列表保存时哈希集合中单个元素的最大长度)来控制hash使用ziplist存储,节省空间。 这样可以节省dictEntry开销,剩下32b的空间。 具体详情可以阅读 Redis核心技术实战 的第11章,讲得非常清晰。
- 使用一定的序列化方式压缩存储空间,例如protobuf。
二、可以直接删除的keys
对于可以直接删除的keys,建议使用scan命令+unlink命令删除,避免主线程阻塞。我们采用的删除方式是:scan轮流扫描各个实例,匹配需要删除的Keys。
风险点:
大家都知道对于客户端命令的执行,Redis是单线程处理的,所以存在一些阻塞主线程的操作风险:
- 对于一个占用内存非常大的key,不可直接使用del命令。 解决方案:Redis4.0以上支持unlik命令异步删除。如果Redis版本小于4.0,建议对集合类采用hscan、zscan等命令分段删除。直接删除耗时可以参考:
- Redis具有定时清理过期keys的策略,若有大批key在同一时间过期,会导致每次采样过期的keys都超过采样数量的25%,循环进行删除操作,影响主线程性能。可参考:定期删除策略 解决方案:避免对大量key使用expiret加指定过期时间,需要将过期时间+随机数打散过期时机;由于我们的集群使用5.0版本,定位到定时清除过期Keys的代码serverCron()->databasesCron()->activeExprireCycle()→dbSyncDelete() ,内部删除方式采用unlink异步删除,不影响主线程。
- 评估删除了keys对业务的影响 解决方案:需要结合业务进行风险点评估;做好数据监控,例如异常告警、MySQL的QPS等。
三、优化了许多keys,内存占用还是很高,怎么回事?
Redis日常的使用是会存在内存碎片的,可在客户端执行info memory命令。如果mem_fragmentation_ratio值大于1.5,那么说明内存碎片超过50%,需要进行碎片整理了
解决方案:
- 重启Redis实例,暴力解决,不推荐
- 使用 config set activedefrag yes 命令,调整以下参数进行自动清理
三、优化成果
删除掉一批弃用的keys后,Redis内存占用已经减少了10G。代码上的优化由于业务需求,有些key零散地设置了2-3个月的过期时间,两三个月过后刚好又迎来了淡季,无法准确预估优化了多少空间,但是总归还是有一定的成果。过程的思路和方案仅供参考。
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)