前段时间,看到这个 BigKey 的问题,因为理解的模糊不清的不太舒服,于是就有了下文的总结。
🤞这次都给他拿下,整得明明白白的🤞
正菜来了🛴🛴🛴
BigKey 的具体表现是 redis 中的 key 对应的 value 很大,占用的 redis 空间比较大,本质上是大 value 问题。
对于 redis 中不同的数据结构类型,常几个常见的例子:
● 对于 String 类型的 value 值,值超过 10MB(数据值太大);
● 对于 Set 类型的 value 值,含有的成员数量为 10000 个(成员数量多);
● 对于 List 类型的 value 值,含有的成员数量为 10000 个(成员数量多);
● 对于 Hash 格式的 value 值,含有的成员数量 1000 个,但所有成员变量的总 value 值大小为 1000MB(成员总的体积过大);
C:\Users\93676\Desktop>redis-cli
127.0.0.1:6379> set a "sadasd"
OK
127.0.0.1:6379> debug object a
Value at:00007FCD3EC12FE0 refcount:1 encoding:embstr serializedlength:7 lru:14754079 lru_seconds_idle:15
serializedlength 表示的是 a 这个 key 对应的 value 经过 embstr 压缩之后的字节数,这里涉及到一点 redis 中的 String 底层结构的之后,redis3.2 版本之后,当 string 不是数字字符串的时候,字节数大于 44,使用 raw 的方式存储,当下雨 44 字节的时候使用 embstr 的方式存储,也就是压缩后的字符串。
相比于正常的 Key,读取大 key 需要的内存会有所增大,如果像是 value 中的 list 不断变大,可能会造成 OOM(内存溢出),还有一种就是达到 redis 设置的最大内存 maxmemory 值会造成写阻塞或者部分重要的 Key 被 redis 的淘汰策略给删除了。
在读取大 key 的时候,由于读取的内容较多,占用较大的带宽,造成网络带宽的阻塞,也会影响其他的应用,导致网络阻塞延迟变大。
BigKey 问题对应的 value 相对较大,当对较大的 value 进行读写,耗费的时间较长,这样就可能阻塞后续的请求处理,其实主要是 BigKey 的 value 进行 IO 写的时候会耗费较长的时时间,IO 写是把处理之后值通过网络返回给请求端,因为 Redis 的核心线程是单线程,也就是工作线程是单线程,单线程中的任务处理是串行执行的,前面的任务完成之后,后面的任务才能继续执行,所以因为单个 BigKey 的原因可能造成 IO 阻塞延迟。
这个问题是出现在 Redis 集群中,当需要对大 value 进行迁移(对于 Redis 集群 slot 的迁移),主要是使用 migrate 命令进行迁移的,migrate 命令是通过 dump 和 restore 和 del 三个命令组合成原子命令完成,如果是存在 bigkey 的话,可能会因为大 value 的原因导致迁移失败,而且较慢的 migrate 会阻塞 Redis,影响 Redis 服务。
通过将 BigKey 拆分成多个小 Key 的键值对,并且拆分后的对应的 value 大小和拆分成的成员数量比较合理,然后进行存储即可,在获取的时候通过 get 不同的 key 或是用 mget 批量获取存储的键值对。
这个主要是针对像是 list 和 set 这种类型,在使用的过程中,list 和 set 中对应的内容不断增加,但是由于之前存储的已经是无效的了,需要定时的对 list 和 set 进行清理。
可以通过序列化或者压缩的方法对 value 进行压缩,是其变为较小的 value,但是如果压缩之后如果对应的 value 还是特别大的话,就需要使用拆分的方法进行解决了。
通过监控系统,监控 redis 中的内存占用大小和网络带宽的占用大小,以及固定时间内的内存占用增长率,当超过设定的阈值的时候,进行报警通知处理。温馨提醒:这个有点多,请仔细看下去
相对于 BigKey,热 Key 也是一个值得关注的点。
热 key:对于 Redis 中的某个 Key 接收到的 QPS、显著高于其它 Key,我们称之为热 Key,常见的热 Key 如
热 key 产生的问题:热 Key 因为频繁的访问。占用大量的 Redis CPU 时间使其性能变差并影响其它请求;
热 key 的解决方案:可以使用使用读写分离架构,如果热 Key 的产生来自于读请求,那么读写分离是一个很好的解决方案。在使用读写分离架构时可以通过不断的增加从节点来降低每个 Redis 实例中的读请求压力。
对于 BigKey 的问题的原因:也就是 Redis 键值对中对应的 value 比较大。
对于 BigKey 问题的发现:可以通过第三方工具或者自带的命令进行扫描发现。
对于 BigKey 问题的解决方案:通过拆分,压缩,清理无效数据等方法对这些大 value 进行处理即可。
领取专属 10元无门槛券
私享最新 技术干货