redis的所有的数据都存在内存中,所以如何合理高效的利用redis内存就变得非常的重要了。首先我们应该知道redis的内存主要消耗在什么地方,怎么管理内存,怎么做才能够让redis的内存优化。这样才能用更少的内存,存储更多的数据,降低成本。
============================================================
我们可以使用info命令查看redis中的内存的消耗情况,查看redis内存消耗的相关指标,从而可以更好的分析内存。
- mem_fragmentation_ratio > 1 说明多出来的部分名没有用于数据存储,而是被内存碎片所消耗,相差越大,说明内存碎片率越严重。
- mem_fragmentation_ratio < 1 一般出现在Redis内存交换(Swap)到硬盘导致(used_memory > 可用最大内存时,Redis会把旧的和不适用的数据写入到硬盘,这块空间就叫Swap空间),出现这种情况需要格外关注,硬盘速度远远慢于内存,Redis性能就会变得很差,甚至僵死。
内存消耗的划分
对象内存
对象内存是redis内存中占用最大的一块,存储着所有的用户的数据。redis所有的数据都采用的是key-value型数据类型,每次创建键值对的时候,都要创建两个对象,key对象和value对象。key对象都是字符串,value对象的存储方式,包括五种数据类型:string,list,hash,set,zset。每种存储方式在使用的时候长度、数据类型不同,则占用的内存就不同。
缓冲内存
主要包括:客户端缓冲、复制积压缓冲区、AOF缓冲区
客户端缓冲:普通的客户端的连接(大量连接),从客户端(主要是复制的时候,异地跨机房,或者主节点下有多个从节点),订阅客户端(发布订阅功能,生产大于消费就会造成积压)
复制积压缓冲:2.8版本之后提供的可重用的固定大小缓冲区用于实现部分复制功能,默认1MB,主要是在主从同步时用到。
AOF缓冲区:持久化用的,会先写入到缓冲区,然后根据响应的策略向磁盘进行同步,消耗的内存取决于写入的命令量和重写时间,通常很小。
内存碎片
目前可选的分配器有jemalloc、glibc、tcmalloc默认jemalloc
出现高内存碎片问题的情况:大量的更新操作,比如append、setrange;大量的过期键删除,释放的空间无法得到有效利用
解决办法:数据对齐,安全重启(高可用/主从切换)。
自身内存
主要指AOF/RDB重写时redis创建的子进程内存的消耗,linux具有写时复制技术,父子进程会共享相同的物理内存页,当父进程写请求时会对需要修改的页复制出一份副本来完成写操作。
设置上限
redis默认是无限使用内存。所以在使用的时候尽量的去配置maxmemory,给redis设置内存使用上限,防止因redis的无限使用造成系统内存耗尽。需注意的是maxmemory配置的是Redis实际使用的内存量,即used_memory,由于有内存碎片的存在,所以实际的内存使用比used_memory要大。
Redis可以动态的执行内存的调整:
config set maxmemory 6GB
配置内存回收策略
删除过期的对象
1. 过期键的删除
惰性删除:什么时候执行呢?就是在客户端读取带有超时属性的键时,如果已经超过键值设置的过期时间,则删除并返回空。这样做的目的是主要是为了节省CPU成本考虑,不需要单独维护TTL链表来处理过期键的删除。但是,如果单独使用这种存在一个问题,如果当前的键值永远不再被访问呢?就不删除了吗?那肯定不行,这就会造成内存泄漏的问题。那Redis是怎么解决的呢?Redis提供了一个定时任务的删除机制来做补充。
2. 定时任务删除
Redis内存维护了一个定时任务,默认是每秒运行10次。具体的逻辑图如下:
溢出控制策略
当Redis使用的内存达到上限maxmemory后,就会根据maxmemory-policy设置的相关策略进行对应的操作。
Hashtable
Redis所有的数据存储都是Key-Value的数据类型。整体的结构是Redis自己实现的hashtable,Redis有两个hashtable存在,但是只有其中一个是用来存数据的,另一个hashtable的存在是为了在扩容的时候用的。通过采用渐进式的方式,把旧的hashtable中的数据逐渐的复制到另外一个hashtable中去。为什么采用渐进式呢?因为Redis是单线程的,扩容一直数据的迁移是很耗费时间的,所以迁移的过程是不能对Redis的其他使用造成影响。所以采用渐进式。
redisObect对象
Redis中所有的值对象内部定义都是redisObject结构体。
简单动态字符串(simple dynamic string,SDS)
在Redis中,字符串对象时经常用到的。Redis中字符串的结构也是Redis自己定义的结构。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装自己,为自己的面试之路不再坎坷!今天就给大家分享一个Github上全面的Java面试题大全,就是这份面试大全助我拿下大厂Offer,月薪提至30K!
我也是第一时间分享出来给大家,希望可以帮助大家都能去往自己心仪的大厂!为金三银四做准备!
一共有20个知识点专题,分别是:
Dubbo面试专题
JVM面试专题
Java并发面试专题
Kafka面试专题
MongDB面试专题
MyBatis面试专题
MySQL面试专题
Netty面试专题
RabbitMQ面试专题
Redis面试专题
Spring Cloud面试专题
SpringBoot面试专题
zookeeper面试专题
常见面试算法题汇总专题
计算机网络基础专题
设计模式专题
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
img-iillQvfK-1713564502989)]
计算机网络基础专题
[外链图片转存中…(img-7IaFwlbv-1713564502991)]
设计模式专题
[外链图片转存中…(img-XIcZTx0s-1713564502992)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!