什么是 BigKey?

Redis BigKey 深度解析:识别、危害与优化方案

什么是 BigKey?

在 Redis 中,BigKey 是指存储大量数据的单个键,这些键通常具有异常大的内存占用或包含大量元素。BigKey 不是由数据类型定义,而是由其资源消耗决定的。

BigKey 的判定标准

数据类型BigKey 阈值示例
String值大小 > 10KB大文本/序列化对象
Hash字段数 > 5,000用户行为记录表
List元素数 > 10,000系统操作日志队列
Set元素数 > 10,000用户标签集合
ZSet元素数 > 5,000排行榜数据
Stream条目数 > 5,000消息历史记录

BigKey 的五大危害

1. 性能瓶颈

图表

代码

2. 内存碎片化

BigKey 频繁修改会导致:

  • 内存分配器频繁调整

  • 内存碎片率上升

  • 有效内存减少

3. 网络阻塞

python

# 1MB的String键传输时间计算
data_size = 1024 * 1024  # 1MB
network_speed = 100 * 1024 * 1024 / 8  # 100Mbps ≈ 12.5MB/s
transfer_time = data_size / network_speed  # ≈ 80ms

80ms内Redis无法处理其他请求!

4. 主从同步问题

  • 主节点生成RDB时间过长

  • 从节点加载BigKey时超时

  • 复制缓冲区溢出

5. 集群迁移失败

当集群进行数据迁移时:

  • BigKey 迁移超时

  • 迁移任务失败

  • 槽位分配不一致

检测 BigKey 的四种方法

1. 官方工具 redis-cli

bash

# 扫描所有键并报告大键
redis-cli --bigkeys -i 0.1  # 每100ms扫描一次# 输出示例
[00.00%] Biggest string found so far 'bigstr' with 10240000 bytes
[12.34%] Biggest hash   found so far 'user:1000:data' with 50000 fields

2. MEMORY USAGE 命令

bash

# 精确测量键内存使用
> MEMORY USAGE user:1000:profile
(integer) 15728640  # 15MB

3. 开源工具 RDB Tools

bash

# 分析RDB文件
rdb -c memory dump.rdb --bytes 10240 > memory.csv# 输出CSV格式
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element
0,hash,user:1000:data,10485760,hashtable,50000,1024

4. 自定义扫描脚本

python

import redis
from redis.exceptions import ResponseErrordef scan_bigkeys(host, port, db, threshold):r = redis.Redis(host=host, port=port, db=db)cursor = '0'while cursor != 0:cursor, keys = r.scan(cursor=cursor, count=100)for key in keys:try:key_type = r.type(key).decode()size = 0if key_type == 'string':size = r.memory_usage(key)elif key_type == 'hash':size = r.hlen(key) * 100  # 估算字段平均大小elif key_type == 'list':size = r.llen(key) * 100  # 估算元素平均大小if size > threshold:print(f"BigKey: {key} | Type: {key_type} | Size: {size}")except ResponseError:continue

BigKey 优化策略

1. 数据分片

python

# 原始BigKey
big_key = "user:1000:behavior_log"# 分片方案
for i in range(10):shard_key = f"user:1000:behavior_log:{i}"r.ltrim(shard_key, 0, 999)  # 每个分片最多1000元素

2. 数据压缩

java

// Java示例:使用GZIP压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(baos);
gzip.write(largeData.getBytes(StandardCharsets.UTF_8));
gzip.close();
redis.set("compressed:key", baos.toByteArray());

3. 数据结构优化

原结构问题优化方案内存减少
Hash存储用户属性使用Ziplist编码60-70%
String存储序列化对象使用MessagePack格式30-50%
Set存储用户标签使用HyperLogLog估算95%

4. 渐进式删除

bash

# 删除大Hash
redis-cli --eval del_big_hash.lua big_hash_key , 1000# del_big_hash.lua
local key = KEYS[1]
local batch = tonumber(ARGV[1])
local cursor = 0
repeatlocal result = redis.call('HSCAN', key, cursor, 'COUNT', batch)cursor = tonumber(result[1])local fields = result[2]for i=1, #fields, 2 doredis.call('HDEL', key, fields[i])end
until cursor == 0
redis.call('DEL', key)

BigKey 预防措施

1. 设计规范

  • 键命名约定:<type>:<id>:<field>

  • 值大小限制:String ≤ 10KB,集合元素 ≤ 5,000

  • 过期时间:所有键必须设置TTL

2. 监控体系

图表

代码

监控关键指标:

  • redis_memory_used_bytes

  • redis_key_size{type="string"}

  • redis_key_length{type="list"}

3. 自动化检测

python

# 定时扫描脚本
import schedule
import timedef bigkey_scan_job():# 执行扫描逻辑scan_bigkeys('localhost', 6379, 0, 10*1024)# 每天凌晨2点执行
schedule.every().day.at("02:00").do(bigkey_scan_job)while True:schedule.run_pending()time.sleep(60)

真实案例:电商平台BigKey优化

问题描述:

  • 用户购物车键:cart:user_12345

  • 数据结构:Hash

  • 问题:单个用户购物车包含15,000+商品

  • 内存占用:48MB

优化方案:

  1. 分片存储

    python

    SHARD_COUNT = 10
    user_id = "user_12345"# 添加商品
    shard_index = hash(item_id) % SHARD_COUNT
    key = f"cart:{user_id}:{shard_index}"
    r.hset(key, item_id, quantity)# 获取全部商品
    cart = {}
    for i in range(SHARD_COUNT):cart.update(r.hgetall(f"cart:{user_id}:{i}"))
  2. 数据归档

    • 活跃购物车:Redis存储最近30天商品

    • 历史购物车:迁移到MySQL

  3. 结果

    • 最大分片大小:1.2MB

    • 内存减少:96%

    • 操作延迟:从120ms降至8ms

BigKey处理最佳实践

  1. 避免在事务中操作BigKey

  2. 禁用KEYS命令,使用SCAN代替

  3. 集群模式下分散BigKey到不同节点

  4. 使用Lazy Free特性(Redis 4.0+)

    bash

    # 配置异步删除
    lazyfree-lazy-eviction yes
    lazyfree-lazy-expire yes
    lazyfree-lazy-server-del yes
  5. 定期执行内存分析

    bash

    redis-cli MEMORY DOCTOR
    redis-cli MEMORY MALLOC-STATS

总结:BigKey处理路线图

图表

代码

关键原则

  1. 设计阶段预防优于后期修复

  2. 监控持续化,检测自动化

  3. 删除操作必须渐进式

  4. 集群环境分散存储

通过合理的数据建模、严格的设计规范和持续的监控优化,可以有效避免BigKey问题,确保Redis高性能稳定运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/87025.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/87025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

量化选股策略 聚宽

# 量化选股策略完整分析与优化建议 ## 策略整体架构分析 这个量化交易策略主要由以下几个核心部分组成&#xff1a; 1. **初始化设置**&#xff1a;配置基准指数、交易参数和全局变量 2. **选股逻辑**&#xff1a;通过财务指标筛选优质股票 3. **股票过滤**&#xff1a;排除…

Python 数据分析:numpy,抽提,布尔索引2。

目录 1 示例代码2 欢迎纠错3 论文写作/Python 学习智能体------以下关于 Markdown 编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右S…

解决leetcode第3597题分割字符串

3597. 分割字符串 难度&#xff1a;中等 问题描述&#xff1a; 给你一个字符串 s&#xff0c;按照以下步骤将其分割为 互不相同的段 &#xff1a; 从下标 0 开始构建一个段。 逐字符扩展当前段&#xff0c;直到该段之前未曾出现过。 只要当前段是唯一的&#xff0c;就将其…

电源芯片之DCDC初探索ING

1. 概述 DC-DC转换器的意思是直流变直流&#xff08;不同的直流电源值得转换&#xff09;&#xff0c;是一种在直流电路中将一个电压值的电能变为另一个电压值的电能装置。 DC-DC转换器一般由控制芯片、电感线圈、二极管、三极管、电容器构成。 2. 基本拓扑结构 2.1 非隔离…

JavaEE:分布式session

一、使用Redis存储分布式session&#xff1a; 1.SpringBoot整合Redis&#xff0c;见如下地址&#xff1a; JavaEE&#xff1a;SpringBoot整合Redis_a526001650a-CSDN博客 2.代码实现分布式session存储(此处以token为例)&#xff1a; Autowired private RedisTemplate<St…

OpenCV CUDA模块设备层-----“大于阈值设为零” 的图像处理函数 thresh_to_zero_inv_func()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 OpenCV 的 CUDA 模块&#xff08;cudev&#xff09; 中的一个仿函数生成器&#xff0c;用于创建一个 “大于阈值设为零” 的图像处理函数对象。 …

FastGPT与MCP:解锁AI新时代的技术密码

一、AI 浪潮中的新星&#xff1a;FastGPT 与 MCP 登场 在当今科技飞速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动各行业变革的核心力量。从智能语音助手到复杂的图像识别系统&#xff0c;AI 的应用无处不在&#xff0c;而其中的关键技术 —— 语言模…

browser-tools-mcp + excel-mcp-server + cursor 实现读取网页信息自动写入Excel

browser-tools-mcp excel-mcp-server cursor 实现读取网页信息自动写入Excel 文章目录 browser-tools-mcp excel-mcp-server cursor 实现读取网页信息自动写入Excel一、安装node.js和npm1、安装nvm2、安装最新版本的node.js 二、安装browser-tools-mcp1、安装 BrowserTools…

Linux安装JDK和Maven

Linux安装JDK和Maven 安装JDK1.8 oracle官网 https://www.oracle.com 下载包地址&#xff1a;https://www.oracle.com/java/technologies/downloads/archive/ 步骤1&#xff1a;官网下载压缩包 点击想要下载的版本&#xff0c;需要登录Oracle的账号&#xff0c;没有的话需要…

MySQL主从复制与数据库集群深度解析

一、主从复制核心架构与复制模式 MySQL主从复制是构建分布式数据库的基础技术&#xff0c;通过日志同步机制实现数据冗余与读写分离。其核心架构分为三层&#xff1a; 日志记录层&#xff1a;主库将数据变更写入二进制日志&#xff08;Binlog&#xff09;网络传输层&#xff…

安装emsdk 4.0.10报Connection reset by peer解决

出错如下: 使用浏览器下载所需文件 https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v22.16.0-darwin-x64.tar.gz 移动到到emsdk/downloads下 修改emsdk.py download_even_if_exists=True 设置环境变量

win11,visual studio 2022,配置dcmtk,opencv

一、配置dcmtk 1 文件下载---地址&#xff0c;Software Development based on DCMTK - dicom.offis.de 源文件下载&#xff0c;选择.zip下载&#xff0c;.tar.gz为Linux和macOS下面常见的压缩包 支持库下载 解决 DCMTK 在 Windows 上编译时所需的依赖库问题 libiconv GNU有…

2025 最新 Appium Inspector 环境搭建教程

1 环境搭建背景 版本升级&#xff1a;Appium 2.0 版本替代 1.x&#xff0c;原 Appium Desktop 因安全漏洞和功能废弃不再适用。需求痛点&#xff1a;Android Studio 仅支持 debug 程序元素定位&#xff0c;需通过 Appium Inspector 实现通用 APK 元素定位。 2 环境搭建步骤 …

Vue 安装使用教程

一、Vue 简介 Vue&#xff08;读作 /vjuː/&#xff0c;类似于“view”&#xff09;是一款用于构建用户界面的渐进式 JavaScript 框架。它易于上手&#xff0c;轻量高效&#xff0c;适合快速构建前端界面&#xff0c;广泛应用于各类 Web 项目中。 二、Vue 安装方式 2.1 直接通…

通过http调用来访问neo4j时报错,curl -X POST 执行指令报错

curl -X POST ^ More? http://localhost:7474/db/neo4j/tx/commit ^ More? -H Authorization: Basic bmVvNGo6MTIzNDU2Nzg ^ More? -H Content-Type: application/json ^ More? -d { \"statements": [{\"statement": \"MATCH (n) RETURN n, label…

Node.js到底是什么

我想像是npm、vite这些名词大家都很熟悉&#xff0c;对它们的作用也有大致印象&#xff0c;但是可能都像我一样不明白Node.js到底是什么&#xff0c;这里给大家带来一个简单介绍。 Node.js 详解&#xff1a;历史发展、生态构建与底层原理 一、Node.js 的起源与历史发展 诞生背…

Rust与Go:GAN实战对决

Rust与Go生成对抗 GAN概念 GAN的全称是Generative Adversarial Network,中文翻译为生成对抗网络。这是一种深度学习模型,由两部分组成:生成器(Generator)和判别器(Discriminator)。生成器的任务是创建数据,而判别器的任务是区分生成器创建的数据和真实数据。这两部分…

pyspark driver 上传pod本地文件到对象存储

前提: pyspark driver on k8s,环境变量或者spark_home/jars 下有相关对象存储的包,报错包问题就这里添加jar即可 from py4j.java_gateway import java_import from pyspark.sql import SparkSession# ----------------------------------------------------------------------…

使用GeoServer发布地图shapefi(.shp)数据

1.创建新的工作区 2.添加新的数据存储&#xff0c;选择Shapefile - ESRI™ Shapefiles (*.shp) 如果这个发布页面退出了 可以这样找回来 点击发布返回图层我们发布的数据在图层显示 点击Layer Preview 预览 现在前端就可以用 OpenLayers地图来调用这个服务了

python+uniapp基于微信小程序的PS社区系统

文章目录 具体实现截图本项目支持的技术路线源码获取详细视频演示&#xff1a;文章底部获取博主联系方式&#xff01;&#xff01;&#xff01;&#xff01;本系统开发思路进度安排及各阶段主要任务java类核心代码部分展示主要参考文献&#xff1a;源码获取/详细视频演示 ##项目…