通过管道传输快速将MySQL的数据导入Redis

通过管道传输pipe将MySQL数据批量导入Redis
自Redis 2.6以上版本起,Redis支持快速大批量导入数据,即官网的Redis Mass Insertion,即Pipe传输,
通过将要导入的命令转换为Resp格式,然后通过MySQL的concat()来整理出最终导入的命令集合,以达到快速导入的目的。

  1. 根据需求设计好Redis的hash结构,关键是Key的设计

    Redis其实就是内存数据库,而其中最常用的就是hash结构,key-value,查询时需要使用到key,所以key的设计决定了查询的效率,

    而你的需求则决定了你的key如何设计,这里推荐一个例子:浅谈REDIS数据库的键值设计

    建表语句:
    复制代码

    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;

复制代码

 key的一般定义格式为: 表名:主键值:列名   不是硬性要求

 所以我们这里的key设置为 person:id

2.确定使用的Redis命令

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

 HMSET myhash field1 "Hello" field2 "World"
  1. 最终处理的结果如下:

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

    Linux下的命令为:
    复制代码

    SELECT CONCAT(
    “*8\r\n”,
    KaTeX parse error: Can't use function '\r' in math mode at position 22: …TH(redis_cmd),'\̲r̲\n',redis_cmd,'…’,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',
   '$',LENGTH(hkey1),'\n',hkey1,'\n','$',LENGTH(hval1),'\n',hval1,'\n',
   '$',LENGTH(hkey2),'\n',hkey2,'\n','$',LENGTH(hval2),'\n',hval2,'\n',
   '$',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

复制代码

 命令解释:

 

  最终的命令由两部分组成,红色框是将MySQL的数据select出来,为了方便都是用了别名(细心的你会发现,这些别名在紫色框中被引用),

  紫色框引用了select出来的数据,然后转换成符合RESP协议格式:

  第一行的 *8\r\n  :  *表示数组,8表示数组元素个数, \r\n是规定分隔符

  第二行的  '$',LENGTH(redis_cmd),'\r\n',redis_cmd,'\r\n',     : $表示长字符串,LENGTH(redis_cmd)表示字符串长度,redis_cmd字符串变量,\r\n还是规定字符串

     通过数数,发现这样的长字符串有8个,都是外面数组的元素

   所以,这一堆很难懂的东西表示,一个包含8个字符串的数组的一个Redis命令,

           内容如下:

*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

特别特别注意:

    1、根据RESP协议,长字符串(bulk Strings)的格式要求是$字符长度\r\n字符串\r\n的,但是从上面命令的最后一行可以看到,

在Linux下,最后变成了\r,而在Windows下就直接什么都没有了。

    2、上图中箭头指向处,'\r\n'后面这个逗号,可以可无,如果没有逗号,一定要空一格空格,否则出错。

4.运行命令,进行数据导入

将第三步的命令保存到文件中,这里是person.sql

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

或:

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

  其中:

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

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

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

    | 管道符号(意思是将该符号左边的运算结果提交给右边的命令处理,这里是先通过MySQL到处数据,然后用redis-cli导入到Redis)          

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

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

All data transferred. Waiting for the last reply…

Last reply received from server.

errors: 0, replies: 2

  可以打开 Redis-cli 输入dbsize或者keys *命令来进行查询。
  1. 错误异常处理
    5.1. ERR Protocol error: expected ‘$’, got ’ ’

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

    如果是在Windows下使用了\r\n作为分隔符就会如此,应改成\n。
 5.2. ERR Protocol error: expected '$', got '1' 就是got后面的内容不为空 ' '

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

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

猜你喜欢

转载自blog.csdn.net/pf1234321/article/details/85956950