有关redis相关的性能优化及内存说明
本篇文章不涉及redis的安装配置,百度或谷歌即可,很简单。
首先,我来说说redis的应用场景,大部分公司都是将redis作为缓存服务器,或者作为ELK日志收集里面的缓存角色(其他这里就不做介绍,比如作为数据库、订阅/发布等)。在这些应用中,我们最值得关注的是redis内存管理机制。下面我就从如下几个问题,开始探讨。
Redis是否需要开启限制内存大小?
在实际生产当中,设置redis内存大小是必须的。否则redis会无限制使用内存,直到将内存资源消耗殆尽。一般配置内存不超过机器内存3/4。如果超过此值,就需要考虑分片或拆分数据。
Redis查看内存及参数说明
Redis INFO命令说明,通过redis info命令可以知道当前redis资源使用情况。我们这里不涉及其他,只谈内存。为了快速定位并解决性能问题,这里选择几个关键性的数据指标,它包含了大多数人在使用Redis上会经常碰到的性能问题。
used_memory:274704400
used_memory_human:261.98M
used_memory_rss:284229632
used_memory_rss_human:271.06M
used_memory_peak:274704400
used_memory_peak_human:261.98M
used_memory_peak_perc:100.00%
used_memory_overhead:80161972
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory_policy:noeviction
其他字段代表的含义,都以字节为单位:
- used_memory:由redis内存分配器分配的内存总量。
- used_memory_human:以标准的格式返回Redis分配的内存总量。
- used_memory_rss:从操作系统的角度返回Redis已分配的内存总量(俗称常驻集大小)。这个值和top、ps等命令的输出一致。
- used_memory_peak:Redis内存消耗峰值(以字节为单位)。
- used_memory_peak_human:以人类可读的格式返回Redis的内存消耗峰值。
- mem_fragmentation_ratio:内存碎片率。used_memory_rss和used_memory之间的比率。
- used_memory_lua: Lua脚本引擎所使用的内存大小。
- mem_allocator: 在编译时指定的Redis使用的内存分配器,可以是libc、jemalloc、tcmalloc。
当redis的内存使用超过最大可用内存时,那么操作系统开始进行内存与swap空间交换,把内存中旧的或不再使用的内容写入硬盘上(硬盘上的这块空间叫Swap分区),以便腾出新的物理内存给新页或活动页(page)使用。但是,这样会造成redis性能下降。如果出现这种情况,需要及时增加内存。
Redis数据持久化
Redis的持久化数据是通过RDB快照和AOF追加实现,他们实现redis宕机时减少最少数据丢失(不能100%实现数据不丢失)。当开启并触发快照功能时,Redis会fork一个子进程把当前内存中的数据完全复制一份写入到硬盘上。因此若是当前使用内存超过可用内存的45%时触发快照功能,那么此时进行的内存交换会变的非常危险(可能会丢失数据)。也就是说,redis在save的时候会出现双倍内存的使用,如果此时不能保证redis有多余可用内存 ,那么倘若在这个时候实例上有大量频繁的更新操作,问题会变得更加严重。
多留一倍内存是最安全的。重写AOF文件和RDB文件的进程(即使不做持久化,复制到Slave的时候也要写RDB)会fork出一条新进程来,采用了操作系统的Copy-On-Write策略(如果父进程的内存没被修改,子进程与父进程共享Page。如果父进程的Page被修改, 会复制一份改动前的内容给新进程),留意Console打出来的报告,如"RDB: 1215 MB of memory used by copy-on-write"。在系统极度繁忙时,如果父进程的所有Page在子进程写RDB过程中都被修改过了,就需要两倍内存。不过,在实际生产中,可以通过如下方式来实现减少内存开销。
- 尽可能使用hash数据结构。
- 设置key的过期时间。
- 回收key。
回收key的策略有几种,分别如下所示:
- volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据。
- volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰。
- volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰。
- allkeys-lru:使用LRU算法从所有数据集合中淘汰数据。
- allkeys-random:从数据集合中任意选择数据淘汰
- no-enviction:禁止淘汰数据。
接下来,我们就说说,redis持久化机制:RDB和AOF
RDB: snapshot
二进制格式,按照指定的策略,周期性的将数据保存至磁盘,数据文件默认为dump.db;
客户端也可显示SAVE或BGSAVE命令启动快照保存机制;
SAVE: 同步,在主线程中保存快照,此时会阻塞所有客户端请求,并且SAVE是完整备份,所以此时需要大量资源(分配的虚拟空间,只有进程数据变动时才会给子进程分配物理内存);
BGSAVE: 异步,客户端请求不会阻塞,默认使用它进行快照;
AOF: Append Only File
记录每一次写操作至指定的文件尾部实现持久化,当redis重启时,可通过重新执行文件中的命令在内存重建数据库;
BGREWRITEAOF: AOF文件重写,不会读取正在使用AOF文件,而通过将内存中的数据以命令的方式保存到临时文件中,完成之后替换原来的AOF文件;
AOF追加过程:
- (1) redis 主进程通过fork创建子进程;
- (2) 子进程根据redis内存中的数据创建数据库重建命令序列于临时文件;
- (3) 父进程集成client请求,并会把请求中的写操作追加至原AOF文件。额外地,这些新的写请求还会被放置于一个缓冲队列中;
- (4) 子进程重新完成,会通知父进程,父进程把缓冲中的命令写到文件中;
- (5) 父进程用临时文件替换原AOF文件;
注意:持久化本身不能取代备份,还需要制定备份策略,对redis数据库定期进行备份;
Redis缓存命中率
redis info命令提供强大的监控功能,能够查看当前缓存的数据状态。主要涉及到的字段如下:
keyspace_hits:14414110 #命中key的次数
keyspace_misses:3228654 #未命中key次数
used_memory:433264648 #redis内存分配器分配内存大小
expired_keys:1333536 #运行以来过期key数量
evicted_keys:1547380 #运行以来删除key数量
缓存的命中率公式:keyspace_hits / ( keyspace_hits + keyspace_misses ) 。一个缓存失效机制,和过期时间设计良好的系统,命中率可以做到95%以上。
Redis 延迟故障排查
需要使用showlog去查看是否有命令导致延迟。
禁用巨大透明内存页。( echo never > /sys/kernel/mm/transparent_hugepage/enabled)
启用并使用Redis的延迟监视器功能,以便获得对Redis实例中的延迟事件和原因的可读描述。
由swap引发的延迟。
由AOF和磁盘I/O导致的延迟。
以上参考官方文档:https://redis.io/topics/latency,每个问题的排查过程、方式都在文档中有说明。
有关redis相关的性能优化及内存说明的更多相关文章
- redis性能优化、内存分析及优化
redis性能优化.内存分析及优化 1.优化网络延时 2.警惕执行时间长的操作 3.优化数据结构.使用正确的算法 4.考虑操作系统和硬件是否影响性能 5.考虑持久化带来的开销 5.1 RDB 全量持久 ...
- Android 性能优化之内存泄漏检测以及内存优化(中)
https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...
- 微擎开启性能优化里面的性能优化memcache内存优化及数据库读写分离
http://www.mitusky.com/forum.php?mod=viewthread&tid=3135 [微擎 安装使用] 微擎开启性能优化里面的性能优化memcache内存优化及数 ...
- 老李分享:Android性能优化之内存泄漏1
老李分享:Android性能优化之内存泄漏 前言 对于内存泄漏,我想大家在开发中肯定都遇到过,只不过内存泄漏对我们来说并不是可见的,因为它是在堆中活动,而要想检测程序中是否有内存泄漏的产生,通常我 ...
- jvm性能优化及内存分区
jvm性能优化及内存分区 2012-09-17 15:51:37 分类: Java Some of the default values for Sun JVMs are listed below. ...
- [Android 性能优化系列]内存之基础篇--Android怎样管理内存
大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地 ...
- [Android 性能优化系列]内存之提升篇--应用应该怎样管理内存
大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地 ...
- KVM总结-KVM性能优化之内存优化
我们说完CPU方面的优化(http://blog.csdn.net/dylloveyou/article/details/71169463),接着继续第二块内容,也就是内存方面的优化.内存方面有以下四 ...
- tomcat 性能优化(内存优化 线程优化)
转自:http://blog.sina.com.cn/s/blog_4b5bc01101014s81.html tomcat 性能优化 linux修改TOMCAT_HOME/bin/catalina. ...
随机推荐
- 在Mac上快速Kill掉Tomcat
最近IDEA总是会莫名其妙的挂掉,而挂掉之后通过IDEA开启的Tomcat却没有同步给关掉,等我再在IDEA里要启动的时候,就不行了.... 这时,就需要手动去kill掉tomcat,每次先 ps - ...
- loj6253/luogu4062-Yazid的新生舞会
先考虑部分分(只有01/只有0~7)做法:枚举每个数,把和他相同的设为1,不同的设为-1,然后这个数作为众数贡献的个数就是区间和>0的个数 推着做,树状数组记前缀和<=x的区间的数量就可以 ...
- 前端学习 -- Css -- display和Visibility
display 将一个内联元素变成块元素,通过display样式可以修改元素的类型.可选值: 1 inline:可以将一个元素作为内联元素显示. 2 block: 可以将一个元素设置块元素显示. 3 ...
- 算法-动态规划DP小记
算法-动态规划DP小记 动态规划算法是一种比较灵活的算法,针对具体的问题要具体分析,其宗旨就是要找出要解决问题的状态,然后逆向转化为求解子问题,最终回到已知的初始态,然后再顺序累计各个子问题的解从而得 ...
- 解题:BZOJ 2989 数列
题面 学习二进制分组 题目本身可以看成二维平面上的问题,转成切比雪夫距离后就是矩形和了 二进制分组是将每个修改添加到末尾,然后从后往前二进制下进位合并,这样最多同时有$\log n$组,每个修改只会被 ...
- [Coci2015]Kamp
Description 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的点)要集中到一个点举行聚会. 聚会结束后需要一辆车从举行聚会的这点出发 ...
- linux文件名匹配——通配符使用
背景:在linux使用过程中,经常需要查找文件,对命令中的通配符pattern和正则表达式的区分不是很清楚.有必要好好研究一下. 1 扫盲 1.1 通配符和正则表达式 当在使用命令行时,有很多时间都用 ...
- 开源.NET界面库
一.十大开源的.NET用户界面框架 选择一款合适的GUI框架是.NET开发中比较重要但又很棘手的问题,因为用户界面相当于一款应用的"门面",直接面向用户.好的UI更能吸引用户,有时 ...
- final的用法---java基础知识
Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量. final类不能被继承,没有子类,final类中的方法默认是final的. final方法 ...
- Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock)
Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在学习Java的之前,你可能已经听说过读 ...