【Redis实用技巧#12】如何向 Redis 批量写入海量数据?

很多工程师第一次遇到这个问题,往往不是在面试,而是在生产事故现场:系统运行正常、接口没有超时、Redis 服务器负载也不高,但​数据导入就是慢得离谱​。当写入规模从几十万上升到几千万甚至上亿时,直觉中的"内存数据库应该飞快"开始失效。

真正的瓶颈,通常不在 Redis,而在​写入方式​。

为什么「for 循环 + SET」几乎必败?

最常见的实现方式如下:

Java 复制代码
for (Record r : records) {
    jedis.set(r.key(), r.value());}

乍看没有问题,逻辑清晰,Redis 也确实很快。但一旦写入规模变大,程序表现往往是:

  • Redis CPU 使用率不高
  • 网络带宽看似空闲
  • 客户端执行速度却持续偏慢

问题的根源在于:​网络往返成本(RTT)被无限放大​。

一次普通写操作,至少包含:

  1. 客户端 → Redis 网络发送
  2. Redis 解析命令
  3. 内存执行
  4. Redis → 客户端返回响应
  5. 客户端接收响应

当写入上千万条数据时,这个往返过程要重复上千万次。哪怕单次延迟只有 0.3 ms,累计开销也会变得惊人。

Redis 的计算几乎不是瓶颈,​等待网络才是​。

关键词:Pipeline

在工程实践和面试场景中,第一层正确答案通常是:​使用 Pipeline 批量发送命令​。

典型写法:

Java 复制代码
Pipeline pipe = jedis.pipelined();for (Record r : records) {
    pipe.set(r.key(), r.value());}

pipe.sync();

Pipeline 的核心价值是:

多条命令一次性发送,减少网络往返次数。

客户端不再每条命令都等待响应,而是集中提交、集中接收。这一改变在高延迟网络环境下尤为明显,往往能带来数量级提升。

但如果场景是​离线导入数亿数据​,Pipeline 仍然不是终点。

被低估的利器:redis-cli 的 Pipe Mode

Redis 2.6 起,redis-cli 提供了专门面向海量写入的模式:

Bash 复制代码
cat data.txt | redis-cli --pipe

这个模式的设计理念非常激进:

只管发送命令流,不等待逐条响应。

与普通模式的区别:

服务器端依然是顺序执行命令,但客户端侧的等待时间几乎被压缩到极限。

在纯导入场景中,这种方式通常比 Java Pipeline 更快。

Pipe Mode 本质上做了什么?

可以将其理解为:

  • 最大化 socket 写入
  • 避免对象封装与序列化成本
  • 极限减少 RTT 影响

它几乎是​贴着 Redis 协议层飞行​,而不是通过高层客户端 API 逐条调用。

RESP 协议级写入:更底层的思路

当数据规模达到"迁移 / 冷启动 / 灾备恢复"等级时,工程上常见做法是​直接构造 RESP 协议数据流​。

示例(简化):

Plain 复制代码
*3\r\n
$3\r\nSET\r\n
$4\r\nkey1\r\n
$5\r\nvalue\r\n

将批量命令预生成文本文件,再通过 redis-cli --pipe 导入:

Bash 复制代码
cat commands.resp | redis-cli --pipe

这种方式的优势:

  • 客户端开销最低
  • IO 利用率高
  • 写入吞吐稳定

适合一次性海量数据灌入,而非在线业务路径。

为什么 Pipe Mode 往往比 Java Pipeline 更快?

典型原因有三类:

  1. 客户端层级更薄无业务对象封装、无额外抽象层。
  2. 无频繁对象创建避免 GC 与序列化成本。
  3. IO 模型更激进持续写入数据流,而非命令级交互。

换句话说,redis-cli --pipe 是一个近似"协议工具",而不是"应用客户端"。

工程视角:不同场景的技术选型

实践中可以按写入场景做简单划分:

关键并不在"哪种方式最先进",而在于​是否匹配使用场景​。

总结

Redis 很少成为批量写入慢的真正原因。真正的差距,往往来自客户端行为模型 与​网络交互模式​:

  • 命令快 ≠ 写入快
  • 内存快 ≠ 网络快
  • 架构正确 ≠ 使用方式正确

在数据规模足够大时,写入策略本身就是性能工程的一部分。

理解这一点,既能避免生产问题,也能在应用中拉开差距。

相关推荐
冰暮流星2 小时前
sql语言之having语句使用
java·数据库·sql
虹科网络安全2 小时前
艾体宝洞察 | “关系+图”混用VS艾体宝ArangoDB多模型数据库,为什么混用的架构越复杂?
数据库·oracle·架构
麦聪聊数据2 小时前
从数据采集到 API 市场的完整技术链路
数据库·sql·低代码·微服务
linux_cfan2 小时前
WordPress 视频播放痛点解决方案:支持 RTSP/WebRTC 与字幕检索的 ZWPlayer 插件实测
php·音视频·webrtc
qh0526wy2 小时前
python 连接Oracle 数据库厚连接方式
数据库·oracle
wanderful_2 小时前
MySQL当中的修改外键关联主键字段属性
数据库·mysql
小刘的大模型笔记2 小时前
POP原理落地到实际微调
数据库·人工智能·深度学习·算法·机器学习
~央千澈~2 小时前
抖音弹幕游戏开发之第4集:第一个WebSocket连接·优雅草云桧·卓伊凡
开发语言·python·php
WHS-_-20222 小时前
Sensing in Bistatic ISAC Systems With Clock Asynchronism
开发语言·php