当前位置:首页 > 问答 > 正文

一步搞定批量数据塞进Redis,省时又高效的操作分享

手里有一大堆数据,比如用户信息、商品列表、配置项什么的,要从数据库或者一个巨大的CSV文件里搬进Redis?如果一条一条地用命令往里插,那感觉就像是用勺子给游泳池换水,慢得让人想哭,而且中间万一网络抖一下或者程序崩了,还得担心数据有没有塞全,特别麻烦。

今天要分享的这个方法,说白了就是“抄近道”,它不要求你懂那些特别复杂的Redis模块或者高级命令,核心就是利用Redis原生的一个协议,叫做Redis序列化协议(RESP),然后我们自己动手做一个能被Redis服务器直接“吃掉”的数据文件,这个方法在Redis的官方文档里就有提到,是官方认证的高效数据导入方式。

想象一下,平常我们给Redis下命令,像是SET name "张三",这个命令是从客户端通过网络发送给Redis服务器的,我们换个思路:能不能直接把这条命令以及成千上万条类似的命令,按照Redis服务器能听懂的“语言”(也就是RESP协议),预先写在一个文件里,然后让Redis服务器一次性读取并执行这个文件呢?当然可以!这就好比是,本来你需要跟厨师说一句他做一道菜(网络往返一次),现在你直接给他一张详细的菜谱(数据文件),他照着菜谱一口气就把所有菜都炒出来了,效率自然天差地别。

关键就在于如何制作这张“菜谱”——也就是生成符合RESP协议的文件,这个文件通常以.txt是有严格格式的,RESP协议用一些简单的符号来标记数据的类型和长度,举个例子,对于一条简单的SET key value命令,在RESP文件里要写成这样:

*3
$3
SET
$4
name
$6
张三

我来简单解释一下这堆“天书”:

  • *3 表示这条命令总共有3个参数(SET, name, 张三)。
  • $3 表示紧跟着的参数长度是3个字节,也就是SET
  • $4 表示下一个参数长度是4个字节,即name
  • $6 表示下一个参数长度是6个字节(一个汉字按3字节算),即张三

看到这里你可能头大了,难道要手动写这几行代码来生成几万条数据?那肯定不行。“一步搞定”的精髓在于用程序自动生成这个文件,你可以用你最熟悉的编程语言,比如Python、Java、PHP,甚至Shell脚本,来批量处理你的原始数据,然后输出成严格符合RESP格式的文本文件。

比如你用Python,伪代码大概是这个感觉: 假设你有一个包含用户信息的列表 user_list

# 这是一个示例思路,非直接可运行代码
with open('redis_data.txt', 'w') as f:
    for user in user_list:
        # 构造一条 SET user:1001 '{"name": "张三", "age": 30}' 命令
        command = f"SET user:{user['id']}"  # 键
        value = json.dumps(user)  # 值,将用户对象转为JSON字符串
        # 开始按照RESP格式写入
        f.write(f"*3\r\n")  # 3个参数:SET, key, value
        f.write(f"${len('SET')}\r\nSET\r\n")  # 第一个参数 SET
        f.write(f"${len(command.split()[1])}\r\n{command.split()[1]}\r\n")  # 第二个参数 key
        f.write(f"${len(value)}\r\n{value}\r\n")  # 第三个参数 value

这样,循环结束后,你就得到了一个充满RESP指令的redis_data.txt文件。

文件生成之后,最后一步就是“喂”给Redis,这需要用到Redis-cli(Redis的命令行工具),但需要加上一个神奇的参数 --pipe,你只需要在终端里执行一条命令:

redis-cli -h your_redis_host -p your_redis_password --pipe < redis_data.txt

(请把your_redis_hostyour_redis_password换成你实际的Redis地址和密码)

这个--pipe参数就是告诉redis-cli:“别跟我一句一句聊了,我直接给你个大文件,你赶紧处理。” Redis服务器会以极快的速度(官方说能接近每秒百万次操作)流水线般地执行文件中的所有命令,速度比普通的逐条插入可能快几十甚至上百倍。

一步搞定”的三个关键步骤:

  1. 准备数据源:把你的批量数据从MySQL、CSV等处拿出来。
  2. 编写转换脚本:用你拿手的编程语言,写个循环,把每条数据都“翻译”成RESP协议的格式,并写入到一个文本文件中,这是唯一的开发工作,但一次编写,终身受益。
  3. 管道导入:使用redis-cli --pipe < your_data.txt命令,完成批量导入。

这种方法的好处是实实在在的:

  • 速度飞快:极大减少了网络往返次数,性能提升惊人。
  • 原子性保证:虽然管道内的命令不是事务,但Redis会尽可能快地连续执行,对于批量初始化数据的场景,通常可以接受。
  • 通用性强:不仅限于SET命令,HSET、SADD、ZADD等所有Redis命令都可以用这种方式批量导入。

下次再遇到需要给Redis“喂”大量数据的时候,别再傻乎乎地一条条插了,试试这个“制作协议文件+管道导入”的方法,你一定会回来感谢它的,这绝对是提升效率、节省时间的利器。

一步搞定批量数据塞进Redis,省时又高效的操作分享