核心问题是网络往返和持久化干扰,而非redis性能本身;应使用redis-cli --pipe批量发送resp协议命令、加载前禁用rdb/aof、按业务分片并控制批次大小。

Redis数据量大时加载慢,核心问题不在“能不能加载”,而在于“怎么加载才不卡主线程、不压垮内存、不拖垮网络”。直接暴力 SET 或 HSET 百万级数据,几乎必然导致 Redis 阻塞、客户端超时、甚至 OOM。关键不是加机器,而是改方式。
用 redis-cli --pipe 替代逐条命令写入
逐条 SET 或 HMSET 本质是 N 次 TCP 往返,网络开销和 Redis 解析成本叠加,数据量一过 10 万就明显变慢。而 redis-cli --pipe 把所有命令拼成二进制协议流一次性发过去,由 Redis 批量解析执行,省掉 90% 以上连接/解析时间。
- 生成符合 RESP 协议的命令文件(每行一条命令,如
*3\r\n$3\r\nSET\r\n$5\r\nkey1\r\n$5\r\nvalue1\r\n),再用cat commands.txt | redis-cli --pipe - 注意:命令总数不宜超过 100 万条/次,否则子进程可能因内存不足崩溃;可拆成多个 20 万条的批次
- 不适用于含 Lua 脚本或事务的场景,纯原子命令才安全
加载前先关闭持久化,加载完再恢复
RDB 快照或 AOF 重写会在数据写入时并发触发,严重拖慢加载速度。尤其 AOF appendfsync always 模式下,每条命令都刷盘,吞吐直接掉一个数量级。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 加载前执行
CONFIG SET save ""(禁用 RDB)和CONFIG SET appendonly no(停 AOF) - 加载完成后再
CONFIG SET save "3600 1 300 100"和CONFIG SET appendonly yes恢复 - 风险:期间宕机丢失全部数据,仅限离线预热或灾备重建等可控场景
用 SCAN + 分片 Key 拆分加载压力
如果加载逻辑本身依赖已有数据结构(比如要批量更新某类 Hash 的字段),不能简单用 pipe,就得靠客户端控制节奏。此时硬上 KEYS * 或全量 HGETALL 会阻塞 Redis,必须用游标式遍历。
- 用
SCAN cursor MATCH pattern COUNT 1000分批拉取 Key 列表,每次只处理一批(如 500 个) - 对每个 Key,用
HGETALL改为多次HGET或HMGET拉部分字段,避免单次返回 MB 级响应 - Key 设计时就按业务维度分片,例如把
user:123拆成user:123:profile、user:123:stats,加载时可并行多连接分别处理
RDB 文件直灌比从源库重建快得多
如果数据源是关系型数据库或其他外部系统,从源头查、序列化、再发给 Redis,中间链路长、序列化耗 CPU、网络易丢包。最稳最快的路径是绕过应用层,走存储层。
- 用
redis-cli --rdb /path/to/dump.rdb直接将 RDB 文件内容导入目标实例(需 Redis 6.2+) - 提前在空实例上用生产数据生成 RDB(例如用
redis-cli --rdb backup.rdb bgsave触发快照),再 scp 到目标机后加载 - 注意:RDB 版本必须兼容(源/目标 Redis 版本差不能跨大版本),且目标实例不能有正在运行的持久化任务
真正卡住加载速度的,往往不是带宽或磁盘 IO,而是单线程模型下命令堆积、持久化干扰、以及客户端没意识到自己正在让 Redis “一口吞下一头牛”。操作节奏、协议选择、配置开关,三者缺一不可。漏掉任意一个,百万级数据加载都可能从分钟级变成小时级。










