
String类型:单Value > 10KB。 Hash/Set/Sorted Set:元素数量 > 5000。 List类型:元素数量 > 10000。 Stream类型:消息数量 > 5000。

业务场景需求:如购物车场景中,一个用户可能会添加多个商品到购物车,若将所有商品信息存储在一个 key 中,随着商品数量的增加,key 的大小也会不断增长。 数据结构选择不当:比如用 List 存储重复元素或冗余数据,用 String 存储长文本或大文件元数据。 缺乏过期策略:日志数据未设置 TTL 持续累积。 业务规模增长:未预判数据量级导致结构臃肿。
用户购物车Hash结构存储了12000+商品项。 单个Key体积达到8.2MB。 每次hgetall操作平均耗时127ms。 导致集群出现连锁超时故障。


redis-cli --bigkeys:快速定位内存占用 TOP Key。 MEMORY USAGE key:精确查询单个 Key 内存(复杂结构为近似值)。 OBJECT encoding key:分析 Key 编码类型(如 raw/embstr)。但这些命令在生产环境中使用需谨慎,因为它们可能会对 Redis 的稳定性产生影响。
# 原生大Key扫描(生产慎用)
redis-cli --bigkeys --memkeys 10
复制
redis-rdb-tools:解析 RDB 文件生成内存分布报告。 RedisInsight:可视化监控 Key 大小与内存使用。
# 内存分析工具
redis-rdb-tools -c memory data/dump.rdb --bytes 10240 --type string
复制
def scan_big_keys(host, port, threshold):
cursor = 0
r = redis.StrictRedis(host=host, port=port)
while True:
cursor, keys = r.scan(cursor, count=100)
for key in keys:
key_type = r.type(key)
size = 0
if key_type == b'string':
size = r.memory_usage(key)
elif key_type in [b'hash', b'list', b'set', b'zset']:
size = r.memory_usage(key, samples=0)
if size > threshold:
yield key.decode(), key_type.decode(), size
if cursor == 0:
break
复制
redis_key_size{type="string"} 1024000
redis_key_element_count{type="hash"} 15000
redis_memory_fragmentation_ratio 1.8
复制


public class KeySharder {
private static final int SHARD_COUNT = 16;
private static final CRC32 crc32 = new CRC32();
public static String getShardKey(String baseKey, String data) {
crc32.reset();
crc32.update(data.getBytes());
return baseKey + ":" + (crc32.getValue() % SHARD_COUNT);
}
}
复制
# 原始大Key
HSET user:1001:cart sku1 "{...}" sku2 "{...}" ... skuN "{...}"
# 拆分后结构
HMSET user:1001:cart:0 sku1 "{...}" sku2 "{...}"
HMSET user:1001:cart:1 sku3 "{...}" sku4 "{...}"
SADD user:1001:cart:index 0 1
复制
-- KEYS[1] 原始列表key
-- ARGV[1] 分页大小
-- ARGV[2] 最后游标
local new_cursor = tonumber(ARGV[2]) or 0
local elements = redis.call('LRANGE', KEYS[1], new_cursor, new_cursor + tonumber(ARGV[1]) - 1)
new_cursor = new_cursor + #elements
return {new_cursor, elements}
复制


在处理 Excel 数据导入时,可以将大 key 拆分成多个 key-value 对,每个 key 包含部分数据。
def update_cart(user_id, sku, data):
# 旧结构写入
redis.hset(f"user:{user_id}:cart", sku, data)
# 新结构写入
shard = crc32(sku) % 16
redis.hset(f"user:{user_id}:cart:{shard}", sku, data)
复制
./redis-migrate --source redis://old:6379 --target redis://new:6380 \
--filter "user:*:cart" --transform "sharded_cart_key" --threads 8
复制
SELECT
COUNT(DISTINCT sku) AS original_count,
SUM(shard_count) AS new_count
FROM (
SELECT COUNT(*) AS shard_count FROM new_cart_shards
UNION ALL
SELECT HLEN('user:1001:cart') FROM redis_snapshot
);
复制
location /cart {
redis_pass $upstream;
set $shard_key '';
access_by_lua_file /etc/nginx/lua/cart_router.lua;
}
复制
rules:
- name: BigKeyProtection
threshold: 100ms
duration: 10s
minRequests: 5
ratio: 0.5
action: circuitBreak
复制

自动化拆分系统:基于机器学习的动态分片策略。 协议层优化:RESP3协议支持分片元数据。 存储引擎改进:原生支持自动分片功能。 混合存储方案:冷热数据分层存储。

文章转载自老王两点中,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
486次阅读
2025-04-14 09:40:20
最近我为什么不写评论国产数据库的文章了
白鳝的洞穴
435次阅读
2025-04-07 09:44:54
优炫数据库成功入围新疆维吾尔自治区行政事业单位数据库2025年框架协议采购!
优炫软件
344次阅读
2025-04-18 10:01:22
国产数据库时代,一些20年前的数据库设计小技巧又可以拿出来用了
白鳝的洞穴
255次阅读
2025-04-10 11:52:51
关于征集数据库标准体系更新意见和数据库标准化需求的通知
数据库标准工作组
231次阅读
2025-04-11 11:30:08
TDengine 3.3.6.0 发布:TDgpt + 虚拟表 + JDBC 加速 8 大升级亮点
TDengine
198次阅读
2025-04-09 11:01:22
Apache Doris 2025 Roadmap:构建 GenAI 时代实时高效统一的数据底座
SelectDB
186次阅读
2025-04-03 17:41:08
优炫数据库成功应用于晋江市发展和改革局!
优炫软件
182次阅读
2025-04-25 10:10:31
GoldenDB助力江苏省住房公积金国产数据库应用推广暨数字化发展交流会成功举办
GoldenDB分布式数据库
175次阅读
2025-04-07 09:44:49
全国首部图数据库国家标准发布!达梦数据深度参与!
达梦数据
166次阅读
2025-04-02 09:34:13