作为内存数据库,内存空间的大小对于Redis来说至关重要。更多内存意味着存储更多数据。但是不知道大家有没有遇到过这样的情况。虽然空间很大,但是内存占用并不理想。为什么会这样?本期,我们就来看看这个“诡异”的事件。坐下来准备出发!-思维导图-查看内存使用情况首先,如果我们想知道Redis内存的使用情况,我们需要获取相关信息。在Redis中查看内存相关信息非常简单。你只需要在命令行输入“infomemory”就可以看到各种相关数据。这里我列出一些比较重要的参数:used_memory:已经使用的内存大小。used_memory_rss:redis物理内存的大小。mem_fragmentation_ratio:内存碎片率。这里有一个需要注意的内存碎片率的名词,它可以用来表示当前的内存使用情况。具体计算方法:对于内存碎片率,一般保持在1~1.5之间是最合理的。什么是内存碎片了解了内存碎片率之后,什么是内存碎片呢?定义是这样的:因为一块连续的空闲空间小于要申请的空间,所以这块空间不可用,对整块内存来说就是内存碎片。例如:假设有一个100MB的连续空闲内存空间,你每次都会从中申请30MB的内存。那么当你申请3次的时候,这块内存就只剩下10MB了,第4次申请就会失败。如果没有其他空间可以释放,并且每次申请的空间都大于10MB,那么剩下的空间就是整块内存的内存碎片。Redis内存碎片最常见的原因是写入、修改和删除数据。这些操作执行后会产生一定程度的内存碎片。Redis中分配的用于写入数据的内存是按照固定的大小进行划分的。Redis为了减少分配次数,会根据申请内存的最接近固定值分配相应大小的空间。什么意思,如果Redis按照8字节、16字节、32字节、48字节等分配内存,当你要存储一个18字节的数据时,此时Redis会分配32字节(因为32是最接近18的固定值)。如果此时重写的数据所需要的内存空间在14字节以内,那么Redis就不需要再分配了。就像如果你有不同的盒子,为了装东西,你需要找到一个体积最接近的盒子。但是放进去之后,发现还有空间放一些小东西,就不用再找盒子了。但是,这种分配空间的方式会带来一定程度的内存碎片。我们可以把固定大小的分割空间看成是不同体积的盒子,每个盒子里的空间都会有不同程度的剩余。剩下的空间就是内存碎片。当修改数据键值对时,它可能会变大或变小,相应地会占用额外的空间或释放未使用的空间。如图所示,目前A、B、C分别占用3、2、4个字节。当把A从3个字节改成2个字节时,此时会空出1个字节的空间。out,那么就会有1个字节的碎片。如果我将数据A从3个字节更改为4个字节会怎样?这时,为了保持数据A的空间连续性,操作系统会将B复制到另一个空间。此时再次发生1字节分片。删除数据理解修改数据,删除数据容易理解。还是上面的例子,如果此时删除了数据B,那么就会释放2个字节的空间。这会导致整个内存空间产生2字节的碎片。内存碎片怎么解决大家可能会有疑问,内存碎片会有什么危害呢?我们还是用上面的方框来表示。想一想,如果要把这些箱子全部装上一辆卡车运走,而且每个箱子都有空位(内存碎片),那么跑一次的效率和性价比会很低。同样,在Redis中,由于大量分片的存在,实际利用率会变低。那么,我们有办法解决内存碎片吗?第一种方式很简单,重新发明轮子就可以了。也就是说直接重启Redis,内存断电整个世界就干净了。但是这种暴力又不麻烦的方式却隐藏着很多的隐患。如果在生产环境中这样做,要提前烧香,是不会出问题的。如果你没做过坚持,那就别烧了,烧了也没用。如果有持久化,恢复时间取决于你的持久化文件的大小,这个阶段无法提供服务。坏的?SpatialDisplacement那么有没有一种不那么刺激的方式呢。是的,高版本的Redis提供了清理内存碎片的方法。一句话,就是空间置换。更换方法怎么样?我们的目的是消除内存碎片,那为什么不把用过的内存数据重新组织起来呢?让不连续的空间连续,剩余的空间继续分配。画个图就明白了:不过说起来还是挺容易的,理论和实践还是有性能损失的。在多次数据副本的过程中,单线程的Redis只能等待,无法响应客户端的请求。这个时候只能发呆,太影响发挥了。很酷,我该怎么办?!别担心,有缓解策略,您可以继续阅读。Redis中有专门的参数设置来自动清理内存碎片:activedefragyes。此命令启动清洁功能,这还不够。Redis还需要其他条件才能进行清理。以下参数满足任意一个条件即可进行清理:active-defrag-ignore-bytes100mb:当碎片达到100MB时,将启用清理。active-defrag-threshold-lower10:当碎片超过10%时启用碎片整理。active-defrag-threshold-upper100:内存碎片超过100%,尽可能清理。在处理的过程中,为了避免影响正常的请求,同时保证性能。同时Redis也提供了监控CPU使用率的参数。只有满足以下条件才能保证正常清理:active-defrag-cycle-min5:清理内存碎片占用CPU时间的比例不低于该值,保证清理性能正常发展。active-defrag-cycle-max75:清理内存碎片占用的CPU时间比例不高于该值。一旦超过,就停止清理,以免清理时大量内存副本阻塞Redis,导致其他请求延迟。总结查看内存使用情况在命令行执行infomemory可以查看Redis内存相关信息。根据内存碎片率,碎片整理可以在一定时间内清理干净。内存碎片产生的原因Redis在写入数据时,为了减少分配次数,会按照固定大小分配内存空间。修改数据时释放或占用额外的内存空间,删除数据时释放空间。这会产生不同程度的内存碎片。内存碎片如何解决Redis重启处理,如果不持久化,可能会引发意外。在持久化的情况下,恢复速度需要取决于文件的大小。通过空间置换,即将使用过的内存数据重新排列在一起。【编辑推荐】比特币暴跌至3000美元的3个原因,以及为何继续看涨?用你喜欢的编程语言配置基础设施即代码2020年50多款Kubernetes工具值得收藏解决“删库跑路”的10个技巧带你进入Emacs世界
