目录
Big Key 问题是指某个键(key)的值(value)过大,这会导致 Redis 的性能下降
1、Big Key的产生
- 业务设计不合理
在设计应用时,如果对数据结构的设计不够精细,可能会导致单个 key 存储的数据量过大,没有合理地拆分成多个较小的 key
如:存储了大量数据的字符串、哈希表(hash)、列表(list)等,这会导致在执行涉及该键的操作时消耗更多的时间和资源。
- 未及时清理无用数据
如:忘记设置过期时间,没有定期删除过期或不再需要的数据,List结构中数据持续增加而没有弹出数据的机制,那么数据会越来越多
- 数据类型选择不当
不同的数据类型有不同的内存使用特点。例如,使用字符串类型存储大量数据可能不如使用哈希(HASH)类型来得高效。
选择不适合的数据类型可能导致内存使用效率低下,进而产生 Big Key
如:文件二进制数据不使用 String 保存、使用 HyperLogLog 统计页面 UV、Bitmap 保存状态信息(0/1)
- 动态增长管理不当
某些数据结构可能随着时间和用户行为的变化而不断增长,如果没有适当的管理机制来控制其增长,就可能导致 Big Key 的出现。
如:日志记录、历史数据存储、某个明星热点粉丝列表或者评论的列表等功能如果没有合理的清理策略,可能会导致 key 的数据量逐渐增大
2、BigKey场景分析
以以下常见的场景分析Big Key的问题以及解决方案:
1. 用户行为日志记录
场景描述:应用程序记录用户的行为日志,如点击事件、浏览历史等,通常会将这些数据存储在一个用户的键中。
问题产生:随着用户行为的增多,单一用户的日志数据量会逐渐增大,形成 BigKey。
解决方案:分割日志数据到多个键中,例如按照日期分割。定期归档或清理旧的日志数据
2. 产品目录或商品信息
场景描述:电商平台或零售系统中,每个商品可能包含大量的属性信息,如规格、价格、库存等。
问题产生:如果将所有商品信息都存储在一个键中,随着商品数量的增加,键的大小也会增加。
解决方案:将商品信息拆分为多个键,例如按类别或品牌存储。使用更高效的数据结构,如使用哈希表存储商品的属性
3. 社交网络的好友关系
场景描述:社交应用中,每个用户都有自己的好友列表。
问题产生:当用户的好友数量非常多时,存储好友列表的键可能会变得非常大。
解决方案:将好友列表拆分为多个键,例如按照字母顺序或好友活跃度进行分组。使用有序集合(Sorted Set)存储好友列表,便于快速查找和排序
4. 会话状态存储
场景描述:Web 应用程序中,会话状态通常需要在服务器端存储。
问题产生:如果每个用户的会话状态包含了大量数据,如购物车、登录信息等,会话状态键可能会变得非常大。
解决方案:将会话状态拆分为多个键,例如将购物车和其他状态分开。定期清理过期的会话状态。
3、Big Key的危害
- 性能下降
对 BigKey 执行批量操作,如 HGETALL 或 HSETALL,这些命令的时间复杂度通常是 O(N),其中 N 是键中元素的数量。当 N 很大时,这些操作会变得非常耗时,尤其是在 Redis 的单线程模型下
- 内存占用
BigKey 占用过多的内存,可能导致 Redis 的整体内存使用过高,从而触发内存淘汰策略,影响其他键的性能
- 网络拥塞
BigKey 在网络上传输时会占用较多带宽,特别是当客户端频繁读取或写入 BigKey 时,可能会导致网络拥塞。
- 超时阻塞
Redis 的主要命令执行是在单线程中完成的,这意味着在执行 BigKey 相关操作时,其他客户端的请求会被阻塞,直到该操作完成
- 备份和恢复时间增加
Big Key 会使 RDB 快照文件或 AOF 日志文件增大,从而增加备份和恢复所需的时间。
大量的 Big Key 存在时,可能会导致备份和恢复过程变得非常缓慢
- 复制延迟/删除异常
在主从复制场景中,Big Key 的复制会消耗更多的时间,导致从节点的延迟增加
当Big Key 过期需要删除时,由于数据量过大,可能发生主库较响应时间过长,主从数据同步异常(删除掉的数据,从库还在使用)
4、检测 BigKey
- 使用 redis-cli 工具:可以通过 redis-cli 工具来检测 BigKey
- 使用 Redis 自带的命令:Redis 提供了 BIGKEYS 命令来查询当前 Redis 中所有 key 的信息,帮助统计分析键值对的大小情况
使用以下命令扫描Redis中所有的键,并返回前1000个Big Key
redis-cli --scan --pattern '*' --count 1000
redis-cli -a "password" -- bigkeys
5、解决 BigKey 问题
-
Big Key拆分
将大键拆分成多个小键,使用更合适的数据结构来存储数据
拆分方式:
(1)按时间/业务拆分
如果 Big Key 包含的是按时间顺序排列的数据,可以考虑按时间范围拆分
(2)按哈希(Hash)拆分
使用哈希函数将大 Key 拆分成多个小 Key,并将其存储在不同的 Redis 实例中
(3)按前缀树拆分
使用前缀树将大 Key 拆分成多个层级结构,每个层级的 Key 都更小
前缀树是一种树形数据结构,用于高效地存储和检索字符串集合
标签:Key,Big,Redis,BigKey,user,key From: https://blog.csdn.net/qq_36451127/article/details/141261563