zoukankan      html  css  js  c++  java
  • 通过管道传输快速将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"

    3. 最终处理的结果如下:

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

         Linux下的命令为:

    SELECT CONCAT(
       "*8
    ",
       '$',LENGTH(redis_cmd),'
    ',redis_cmd,'
    ',
       '$',LENGTH(redis_key),'
    ',redis_key,'
    ',
       '$',LENGTH(hkey1),'
    ',hkey1,'
    ','$',LENGTH(hval1),'
    ',hval1,'
    ',
       '$',LENGTH(hkey2),'
    ',hkey2,'
    ','$',LENGTH(hval2),'
    ',hval2,'
    ',
       '$',LENGTH(hkey3),'
    ',hkey3,'
    ','$',LENGTH(hval3),'
    ',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

         Windows下的命令为:

    SELECT CONCAT(
       "*8
    ",
       '$',LENGTH(redis_cmd),'
    ',redis_cmd,'
    ',
       '$',LENGTH(redis_key),'
    ',redis_key,'
    ',
       '$',LENGTH(hkey1),'
    ',hkey1,'
    ','$',LENGTH(hval1),'
    ',hval1,'
    ',
       '$',LENGTH(hkey2),'
    ',hkey2,'
    ','$',LENGTH(hval2),'
    ',hval2,'
    ',
       '$',LENGTH(hkey3),'
    ',hkey3,'
    ','$',LENGTH(hval3),'
    ',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  :  *表示数组,8表示数组元素个数, 是规定分隔符

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

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

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

                   内容如下:

        *8 $5 HMSET $8 person:1 $2 id $1 1 $4 name $5 Tommy $3 age $2 18

       特别特别注意

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

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

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

    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 *命令来进行查询。

    5. 错误异常处理

        5.1. ERR Protocol error: expected '$', got ' '

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

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

         5.2. ERR Protocol error: expected '$', got '1' 就是got后面的内容不为空 ' '

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

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

    参考:http://baijian.github.io/2013/10/12/import-data-from-mysql-to-redis.html

  • 相关阅读:
    hdu4122
    poj3410单调队列(单调栈)
    hdu3415 单调队列模板题
    网站指纹识别工具Whatweb的使用
    Python中shodan模块的使用
    Shodan的使用
    Google Hacking的用法
    PyCharm调试程序
    Python脚本与Metasploit交互进行自动永恒之蓝攻击
    关于PHP动态的接收传递的GET,POST和COOKIE变量
  • 原文地址:https://www.cnblogs.com/tommy-huang/p/4703514.html
Copyright © 2011-2022 走看看