这是一位同学今年秋招参加得物 JAVA 一面遇到的问题,完整面经如下:
文章插图
这个问题在面试中还是比较容易遇到的,尤其是在考察 redis 性能优化相关知识点的时候 。
通常情况下,问了 bigkey(大 Key)还会继续问 hotkey(热 Key) 。即使不准备面试也建议看看,实际开发中也能够用到 。
hotkey 相关的内容会在下一篇文章中提问,同样会收录在 《Java 常见面试题详解》 这个面试题专辑中 。
什么是 bigkey?简单来说,如果一个 key 对应的 value 所占用的内存比较大,那这个 key 就可以看作是 bigkey 。具体多大才算大呢?有一个不是特别精确的参考标准:
- String 类型的 value 超过 1MB
- 复合类型(List、Hash、Set、Sorted Set 等)的 value 包含的元素超过 5000 个(不过 , 对于复合类型的 value 来说,不一定包含的元素越多,占用的内存就越多) 。
文章插图
bigkey 判定标准
bigkey 是怎么产生的?有什么危害?bigkey 通常是由于下面这些原因产生的:
- 程序设计不当,比如直接使用 String 类型存储较大的文件对应的二进制数据 。
- 对于业务的数据规模考虑不周到,比如使用集合类型的时候没有考虑到数据量的快速增长 。
- 未及时清理垃圾数据 , 比如哈希中冗余了大量的无用键值对 。
在 Redis 常见阻塞原因总结[1]这篇文章中我们提到:大 key 还会造成阻塞问题 。具体来说,主要体现在下面三个方面:
- 客户端超时阻塞:由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应 。
- 网络阻塞:每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的 。
- 工作线程阻塞:如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令 。
综上,大 key 带来的潜在问题是非常多的,我们应该尽量避免 Redis 中存在 bigkey 。
如何发现 bigkey?1、使用 Redis 自带的 --bigkeys 参数来查找 。
# redis-cli -p 6379 --bigkeys# Scanning the entire keyspace to find biggest keys as well as# average sizes per key type.You can use -i 0.1 to sleep 0.1 sec# per 100 SCAN commands (not usually needed).[00.00%] Biggest string found so far '"ballcat:oauth:refresh_auth:f6cdb384-9a9d-4f2f-af01-dc3f28057c20"' with 4437 bytes[00.00%] Biggest listfound so far '"my-list"' with 17 items-------- summary -------Sampled 5 keys in the keyspace!Total key length in bytes is 264 (avg len 52.80)Biggestlist found '"my-list"' has 17 itemsBiggest string found '"ballcat:oauth:refresh_auth:f6cdb384-9a9d-4f2f-af01-dc3f28057c20"' has 4437 bytes1 lists with 17 items (20.00% of keys, avg size 17.00)0 hashs with 0 fields (00.00% of keys, avg size 0.00)4 strings with 4831 bytes (80.00% of keys, avg size 1207.75)0 streams with 0 entries (00.00% of keys, avg size 0.00)0 sets with 0 members (00.00% of keys, avg size 0.00)0 zsets with 0 members (00.00% of keys, avg size 0.00
从这个命令的运行结果,我们可以看出:这个命令会扫描(Scan) Redis 中的所有 key ,会对 Redis 的性能有一点影响 。并且,这种方式只能找出每种数据结构 top 1 bigkey(占用内存最大的 String 数据类型 , 包含元素最多的复合数据类型) 。然而,一个 key 的元素多并不代表占用内存也多,需要我们根据具体的业务情况来进一步判断 。在线上执行该命令时 , 为了降低对 Redis 的影响 , 需要指定 -i 参数控制扫描的频率 。redis-cli -p 6379 --bigkeys -i 3 表示扫描过程中每次扫描后休息的时间间隔为 3 秒 。
2、使用 Redis 自带的 SCAN 命令
SCAN 命令可以按照一定的模式和数量返回匹配的 key 。获取了 key 之后,可以利用 STRLEN、HLEN、LLEN等命令返回其长度或成员数量 。
推荐阅读
- 72岁的她穿旗袍配短发飒爽大气,身姿轻盈,完全看不出年龄
- 《一念关山》大结局:看懂梧帝两封遗诏,才知宁远舟为何假死遁隐
- 《亮剑》播出18年后,护士“田雨”大变样,背负巨额债务复出还债
- 52岁杨钰莹太狠了!素颜同框大3岁任静像女儿,单身果然更养人
- 零下十二度的北京,赵丽颖与表弟的“雪地大战”引发热议
- 湖北小伙被外国美女模特倒追,生下两个混血女儿,大女儿超像杨幂
- 曝汤洛雯婆婆消费情况:买名牌包不心疼,出行开大奔,还吃补品
- 王鹤棣田曦薇红毯互动超甜,《大奉》有望成爆款,棣欣引力破大防
- 混血儿也有心酸,刘烨儿子近照大变样,周华健看着比儿子还年轻
- 杀疯了!韩剧又出大爆款!《鱿鱼游戏》之后,最火的韩剧出现了