目录
1. RESP 协议
(1)RESP 协议的优点
(2)RESP 支持的 5 种数据类型
(3)RESP 的用途
(4)RESP 协议示例
redis-cli%20%E7%9A%84%20pipe%20%E6%A8%A1%E5%BC%8F-toc" name="tableOfContents" style="margin-left:40px">2. redis-cli 的 pipe 模式
(1)pipe 模式的作用
(2)pipe 模式的使用场景
(3)pipe 模式的使用方法
(4)pipe 模式的输出
(5)pipe 模式的优点
3. 生成测试数据
4. 使用 SQL 构造导入文件
5. 编写脚本导入 Redis
参考:
1. RESP 协议
RESP(REdis Serialization Protocol)是 Redis 的通信协议,用于客户端和服务器之间的数据传输。它简单、高效,支持多种数据类型。
(1)RESP 协议的优点
- 高效:RESP 是二进制安全的,支持高效的数据传输。
- 简单:格式简单,易于实现和解析。
- 灵活:支持多种数据类型,适用于各种场景。
(2)RESP 支持的 5 种数据类型
- 简单字符串
格式:+<字符串>\r\n
示例:+OK\r\n(表示字符串 OK)
- 错误
格式:-<错误信息>\r\n
示例:-ERR unknown command\r\n(表示错误信息)
- 整数
格式::<整数>\r\n
示例::1000\r\n(表示整数 1000)
- 批量字符串
格式:$<长度>\r\n<数据>\r\n
示例:$6\r\nfoobar\r\n(表示字符串 foobar)
- 数组
格式:*<元素数量>\r\n<元素1><元素2>...<元素N>
示例:*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n(表示数组 ["foo", "bar"])
(3)RESP 的用途
- Redis 客户端与服务器通信:客户端发送命令,服务器返回响应。
- 数据导入导出:用于 Redis 的数据备份和恢复。
- 主从复制:主节点通过 RESP 协议将数据同步到从节点。
(4)RESP 协议示例
客户端发送一个 SET 命令:
*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n
解析:
- *3:表示一个包含 3 个元素的数组。
- $3\r\nSET\r\n:第一个元素是字符串 SET,长度为 3。
- $5\r\nmykey\r\n:第二个元素是字符串 mykey,长度为 5。
- $7\r\nmyvalue\r\n:第三个元素是字符串 myvalue,长度为 7。
服务器返回一个成功响应:
+OK\r\n
服务器返回一个错误响应:
-ERR unknown command\r\n
redis-cli%20%E7%9A%84%20pipe%20%E6%A8%A1%E5%BC%8F" name="2.%20redis-cli%20%E7%9A%84%20pipe%20%E6%A8%A1%E5%BC%8F">2. redis-cli 的 pipe 模式
redis-cli 的 --pipe 模式是一种高效批量处理数据的功能,特别适合处理大规模数据。
(1)pipe 模式的作用
- 高效批量处理:一次性发送大量命令或数据到 Redis 服务器,减少网络往返时间(RTT,Round-Trip Time),提升性能。
- 减少开销:Redis 服务器会批量处理接收到的命令,减少每条命令的解析和响应开销。
(2)pipe 模式的使用场景
- 大规模数据导入:适合导入数百万甚至数千万条数据。
- 数据迁移:将数据从一个 Redis 实例迁移到另一个实例。
- 批量命令执行:批量执行大量 Redis 命令(如 SET、INCR 等)。
(3)pipe 模式的使用方法
- 命令格式:将 Redis 命令写入文件,每行一个命令。如示例文件 f1:
SET key1 value1 SET key2 value2 INCR counter
- RESP 格式:将 RESP 协议格式的数据写入文件。如示例文件 f2:
*3\r\n$3\r\nSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n *3\r\n$3\r\nSET\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n
- 通过 pipe 导入数据:使用 cat 命令将文件内容通过管道传递给 redis-cli --pipe,例如:
cat f1 | redis-cli --pipe cat f2 | redis-cli --pipe
(4)pipe 模式的输出
导入完成后,redis-cli 会显示统计信息,例如:
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 1000
errors 是错误数量,replies 是成功执行的命令数量。
(5)pipe 模式的优点
- 高性能:批量发送数据,减少网络和解析开销。
- 简单易用:只需将数据写入文件并通过管道传递即可。
- 支持多种格式:支持命令格式和 RESP 格式。
3. 生成测试数据
use test;
create table t_book
(id int, name varchar(50), descrition varchar(50));drop procedure if exists sp_insert;
delimiter //
create procedure sp_insert(cnt int)
begindeclare s int default 1;set session autocommit=0;insert into t_book select s, concat('book',s), concat('book_description',s);while s<=cnt doinsert into t_book select n, concat('book',n), concat('book_description',n) from (select id+s n from t_book where id+s <=cnt) t;set s=s*2;end while;commit;
end;
//
delimiter ;call sp_insert(1000000);
4. 使用 SQL 构造导入文件
将下面这个构造 RESP 内容的查询语句保存到文件 RESP.sql
select concat("*4\r\n","$",length(redis_cmd),"\r\n",redis_cmd,"\r\n","$",length(redis_key),"\r\n",redis_key,"\r\n","$",length(hkey),"\r\n",hkey,"\r\n","$",length(hval),"\r\n",hval,"\r")from (select "hset" as redis_cmd, id as redis_key, name as hkey, descrition as hvalfrom t_book) as t;
5. 编写脚本导入 Redis
一百万数据,命令格式文件的数据导入用时 4 秒,RESP 格式文件的数据导入用时 3 秒:
# date;mysql -uroot -p123456 -h127.0.0.1 -P3306 -Dtest --default-character-set=utf8mb4 --skip-column-names --raw -e "select concat('hset ',id,' ',name,' ',descrition) from t_book" | \
> redis-cli -p 6379 -a 123456 --pipe;date;
Tue Mar 4 16:33:51 CST 2025
mysql: [Warning] Using a password on the command line interface can be insecure.
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 1000000
Tue Mar 4 16:33:55 CST 2025
#
# redis-cli -p 6379 -a 123456 flushdb
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
#
# date;mysql -uroot -p123456 -h127.0.0.1 -P3306 -Dtest --default-character-set=utf8mb4 --skip-column-names --raw < RESP.sql | \
> redis-cli -p 6379 -a 123456 --pipe;date;
Tue Mar 4 16:34:19 CST 2025
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
mysql: [Warning] Using a password on the command line interface can be insecure.
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 1000000
Tue Mar 4 16:34:22 CST 2025
#
参考:
MySQL百万级数据高效导入Redis