对于redis来讲,什么是最重要的?linux
毋庸置疑,是内存。redis
redis内存使用状况:info memory算法
示例:缓存
能够看到,当前节点内存碎片率为226893824/209522728≈1.08,使用的内存分配器是jemalloc。服务器
used_memory_rss 一般状况下是大于 used_memory 的,由于内存碎片的存在。网络
可是当操做系统把redis内存swap到硬盘时,memory_fragmentation_ratio 会小于1。redis使用硬盘做为内存,由于硬盘的速度,redis性能会受到极大的影响。并发
redis 空进程自身消耗很是的少,能够忽略不计,优化内存能够不考虑此处的因素。dom
对象内存,也即真实存储的数据所占用的内存。ide
redis k-v结构存储,对象占用能够简单的理解为 k-size + v-size。高并发
redis的键统一都为字符串类型,值包含多种类型:string、list、hash、set、zset五种基本类型及基于string的Bitmaps和HyperLogLog类型等。
在实际的应用中,必定要作好kv的构建形式及内存使用预期,能够参考 关于Redis的使用,你必需要弄懂这些常见的疑难杂症! 中关于不一样值类型不一样形式下的内部存储实现介绍。
缓冲内存包括三部分:客户端缓存、复制积压缓存及AOF缓冲区。
1)客户端缓存:接入redis服务器的TCP链接输入输出缓冲内存占用,TCP输入缓冲占用是不受控制的,最大容许空间为1G。输出缓冲占用能够经过client-output-buffer-limit参数配置。
redis 客户端主要分为从客户端、订阅客户端和普通客户端。
从客户端链接占用:也就是咱们所说的slave,主节点会为每个从节点创建一条链接用于命令复制,缓冲配置为:client-output-buffer-limit slave 256mb 64mb 60。
主从之间的间络延迟及挂载的从节点数量是影响内存占用的主要因素。所以在涉及须要异地部署主从时要特别注意,另外,也要避免主节点上挂载过多的从节点(<=2);
订阅客户端内存占用:发布订阅功能链接客户端使用单独的缓冲区,默认配置:client-output-buffer-limit pubsub 32mb 8mb 60。
当消费慢于生产时会形成缓冲区积压,所以须要特别注意消费者角色配比及生产、消费速度的监控。
普通客户端内存占用:除了上述以外的其它客户端,如咱们一般的应用链接,默认配置:client-output-buffer-limit normal 1000。
能够看到,普通客户端没有配置缓冲区限制,一般通常的客户端内存消耗也能够忽略不计。
可是当redis服务器响应较慢时,容易形成大量的慢链接,主要表现为链接数的突增,若是不能及时处理,此时会严重影响redis服务节点的服务及恢复。
关于此,在实际应用中须要注意几点:
-> maxclients最大链接数配置必不可少。
-> 合理预估单次操做数据量(写或读)及网络时延ttl。
-> 禁止线上大吞吐量命令操做,如keys等。
高并发应用情景下,redis内存使用须要有实时的监控预警机制,
2)复制积压缓冲区
v2.8以后提供的一个可重用的固定大小缓冲区,用以实现向从节点的部分复制功能,避免全量复制。配置单数:repl-backlog-size,默认1M。单个主节点配置一个复制积压缓冲区。
3)AOF缓冲区
AOF重写期间增量的写入命令保存,此部分缓存占用大小取决于AOF重写时间及增量。
关于Redis的使用,你必需要弄懂这些常见的疑难杂症!简单介绍过redis的内存分配方式。
子进程即redis执行持久化(RDB/AOF)时fork的子任务进程。
父子进程会共享相同的物理内存页,父进程处理写请求时会对须要修改的页复制一份副本进行修改,子进程读取的内存则为fork时的父进程内存快照,所以,子进程的内存消耗由期间的写操做增量决定。
THP机制会下降fork子进程的速度;写时复制内存页由4KB增大至2M。高并发情境下,写时复制内存占用消耗影响会很大,所以须要选择性关闭。
通常须要配置linux系统 vm.overcommit_memory=1,以容许系统能够分配全部的物理内存。防止fork任务因内存而失败。
redis的内存管理主要分为两方面:内存上限控制及内存回收管理。
目的:缓存应用内存回收机制触发 + 防止物理内存用尽(redis 默认无限使用服务器内存) + 服务节点内存隔离(单服务器上部署多个redis服务节点)
在进行内存分配及限制时要充分考虑内存碎片占用影响。
动态调整,扩展redis服务节点可用内存:config set maxmemory {}。
回收时机:键过时、内存占用达到上限
1)过时键删除:
redis 键过时时间保存在内部的过时字典中,redis采用惰性删除机制+定时任务删除机制。
惰性删除:即读时删除,读取带有超时属性的键时,若是键已过时,则删除而后返回空值。这种方式存在问题是,触发时机,加入过时键长时间未被读取,那么它将会一直存在内存中,形成内存泄漏。
定时任务删除:redis内部维护了一个定时任务(默认每秒10次,可配置),经过自适应法进行删除。
删除逻辑以下:
须要说明的一点是,快慢模式执行的删除逻辑相同,这是超时时间不一样。
2)内存溢出控制
当内存达到maxmemory,会触发内存回收策略,具体策略依据maxmemory-policy来执行。
noevication:默认不回收,达到内存上限,则再也不接受写操做,并返回错误。
volatile-lru:根据LRU算法删除设置了过时时间的键,若是没有则不执行回收。
allkeys-lru:根据LRU算法删除键,针对全部键。
allkeys-random:随机删除键。
volatitle-random:速记删除设置了过时时间的键。
volatilte-ttl:根据键ttl,删除最近过时的键,一样若是没有设置过时的键,则不执行删除。
动态配置:config set maxmemory-policy {}
在设置了maxmemory状况下,每次的redis操做都会检查执行内存回收,所以对于线上环境,要确保所这只的maxmemory>used_memory。
另外,能够经过动态配置maxmemory来主动触发内存回收。