缓冲内存的理论最大值推导
为什么要有缓冲区
Redis工作原理-单客户端视角简单版:
Redis工作原理-单客户端视角复杂版:
缓冲区的功能其实很简单,主要就是用一块内存空间来暂时存放命令数据,以免出现因为数据和命令的处理速度慢于发送速度而导致的数据丢失和性能问题。
因此,Redis工作原理-多客户端视角简单版(含缓冲区)。
输入缓冲区
定义
内存占用
输出缓冲区
定义
内存占用
Redis Server 的输出大小通常是不可控制的。存在bigkey的时候,就会产生体积庞大的返回数据。另外也有可能因为执行了太多命令,导致产生返回数据的速率超过了往客户端发送的速率,导致服务器堆积大量消息,从而导致输出缓冲区越来越大,占用过多内存,甚至导致系统崩溃。Redis 通过设置 client-output-buffer-limit来保护系统安全。
不出意外,默认是:32MB 8MB 60s
对于 Pub/Sub 连接:
● 硬限制:每个 Pub/Sub 客户端连接的输出缓冲区最大可以达到 32MB 。
● 连接池最大连接数:300 个连接,其中所有连接假设都在处理 Pub/Sub 消息且达到了最大缓冲区限制。
故理论上,最大输出缓冲区可以达到:
最大输出缓冲区占用=硬限制×连接池最大连接数最大输出缓冲区占用=硬限制×连接池最大连接数=32MB×300=9600MB=9.375GB
因此,在这种配置下,所有 Pub/Sub 连接的输出缓冲区理论上的最大占用内存为 9.375 GB。
因此,在client-output-buffer-limit是默认的情况下,最大占用内存为 9.375 GB。
所以,MAX(输出缓冲区+输入缓冲区)是否会造成内存使用率100%?
当然!
MAX(输出缓冲区+输入缓冲区)=10.375GB >> 一个实例的内存规格(在本case中,是2G)
最后的效果就是:
对象存储的部分因为是有过期时间的,过期了自然被清理了。
● 【缓冲内存】↑ (涌入)
● 【对象内存】↓ (定时清理)
● 并受MAX内存掣肘(上限)
最终的结局:Redis 的内存完全被缓冲区占据。
自然,每当有SET请求进来的时候,SET不进来——因为「内存淘汰策略」(maxmemory-policy) 淘汰的是【对象内存】,压根起不到作用!!!
结论:
Redis 的内存完全被缓冲区占据,实际上 Redis 将无法正常工作,包括数据存储(SET 操作)和数据读取(GET 操作)。