简介

通过pipe将MySQL数据批量导入Redis,自Redis 2.6以上版本起,Redis支持快速大批量导入数据,即官网的Redis Mass Insertion,即Pipe传输,

现在的业务场景是将mysql中某张表的所有数据传输到redis中存储起来。

大致思路是用MySql的concat()方法将查询出来的数据按照resp协议的格式拼接成redis命令集合,再通过redis-cli --pipe批量执行命令

redis存储设计

假设数据库为test,表结构如下:

create database if not exists test;

use test;

CREATE TABLE person (

id int(10) unsigned NOT NULL AUTO_INCREMENT,

name varchar(200) NOT NULL,

age varchar(200) NOT NULL,

PRIMARY KEY (id)

) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

考虑用hash来对mysql数据库的数据进行存储,每条数据库记录对应一条hash存储,表名+主键值为key值,列名为field值,value为对应的列值

这里使用的是HMSET命令,格式如下:

HMSET ‘person:id值’ field1 “Hello” field2 “World” 至于这个命令的resp格式,可以参照另外一篇文章resp

sql脚本

特别注意:因为RESP协议中的分隔符为在Linux下是\r\n,而在Windows下则为\n

Linux下的命令为:

SELECT CONCAT(

“*8\r\n”,

‘$’,LENGTH(redis_cmd),’\r\n’,redis_cmd,’\r\n’,

‘$’,LENGTH(redis_key),’\r\n’,redis_key,’\r\n’,

KaTeX parse error: Can't use function '\r' in math mode at position 18: …LENGTH(hkey1),'\̲r̲\n',hkey1,'\r\n…’,LENGTH(hval1),’\r\n’,hval1,’\r\n’,

KaTeX parse error: Can't use function '\r' in math mode at position 18: …LENGTH(hkey2),'\̲r̲\n',hkey2,'\r\n…’,LENGTH(hval2),’\r\n’,hval2,’\r\n’,

KaTeX parse error: Can't use function '\r' in math mode at position 18: …LENGTH(hkey3),'\̲r̲\n',hkey3,'\r\n…’,LENGTH(hval3),’\r\n’,hval3,’\r’

)FROM(

SELECT ‘HMSET’ AS redis_cmd,

concat_ws(’:’,‘person’, id) AS redis_key,

‘id’ AS hkey1, id AS hval1,

‘name’ AS hkey2, name AS hval2,

‘age’ AS hkey3, age AS hval3

From person

)AS t

Windows下的命令为:

SELECT CONCAT(

“*8\n”,

‘$’,LENGTH(redis_cmd),’\n’,redis_cmd,’\n’,

‘$’,LENGTH(redis_key),’\n’,redis_key,’\n’,

KaTeX parse error: Undefined control sequence: \n at position 18: …LENGTH(hkey1),'\̲n̲',hkey1,'\n','’,LENGTH(hval1),’\n’,hval1,’\n’,

KaTeX parse error: Undefined control sequence: \n at position 18: …LENGTH(hkey2),'\̲n̲',hkey2,'\n','’,LENGTH(hval2),’\n’,hval2,’\n’,

KaTeX parse error: Undefined control sequence: \n at position 18: …LENGTH(hkey3),'\̲n̲',hkey3,'\n','’,LENGTH(hval3),’\n’,hval3

)FROM(

SELECT ‘HMSET’ AS redis_cmd,

concat_ws(’:’,‘person’, id) AS redis_key,

‘id’ AS hkey1, id AS hval1,

‘name’ AS hkey2, name AS hval2,

‘age’ AS hkey3, age AS hval3

From person

)AS t

这个查询语句最后的结果每一行都是如下的一个resp协议格式的命令:

*8\r\n$5\r\nHMSET\r\n$8\r\nperson:1\r\n$2\r\nid\r\n$1\r\n1\r\n$4\r\nname\r\n$5\r\nTommy\r\n$3\r\nage\r\n$2\r\n18

然后将上面的查询语句存储到一个脚本文件比如/usr/local/person.sql

调用sql脚本并执行redis命令

mysql -uroot -ppassword dbname --default-character-set=utf8 --skip-column-names --raw < /usr/local/person.sql | redis-cli --pipe

其中:

-u 是数据库用户名 -p 是数据库密码 -D 指定数据库,也可以直接输入数据库名字

–default-character-set=utf8 使用utf8作为默认编码

–raw 使mysql不转换字段值中的换行符 --skip-column-names 使mysql输出的每行中不包含列名

| 管道符号(意思是将该符号左边的运算结果提交给右边的命令处理)

redis-cli 是调用Redis的客户端命令 --pipe 使用管道传输

执行命令后,如果出现类似以下提示,这说明导入正确:

All data transferred. Waiting for the last reply…

Last reply received from server.

errors: 0, replies: 2

错误处理

ERR Protocol error: expected ‘$’, got ’ ’

如果执行命令时,出现 ERR Protocol error: expected ‘$’, got ’ ’ , 先判断你的操作系统

如果是在Windows下使用了\r\n作为分隔符就会如此,应改成\n。

ERR Protocol error: expected ‘$’, got ‘1’ 就是got后面的内容不为空 ’ ’

看起来与5.1的错误提示极为相似,但这个一般是数据库中有特殊符号所导致的的,

所以在命令中加上 --default-character-set=utf8 即可

相关资源:从MySQL到Redis的简单数据库迁移方法_rediswriter-其它代码类资源…

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐