1. 程式人生 > >通過管道傳輸快速將MySQL的資料匯入Redis(自己做過測試)

通過管道傳輸快速將MySQL的資料匯入Redis(自己做過測試)

通過管道傳輸快速將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下是\r\n

,而在Windows下則為\n

     Linux下的命令為:

按 Ctrl+C 複製程式碼

 

按 Ctrl+C 複製程式碼

     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'後面這個逗號,可以可無,如果沒有逗號,一定要空一格空格,否則出錯。

       3. person.sql裡面是mysql語句,不是RESP協議格式的redis語句。

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下使用了\r\n作為分隔符就會如此,應改成\n。

     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

來源:https://www.cnblogs.com/tommy-huang/p/4703514.html