通過管道傳輸快速將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 即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章