一、介紹
二、操作詳解
話不多說,直接進入主題了。
1、使用協定,盧克(Use the protocol, Luke)
使用普通Redis用戶端的方式執行批量插入的操作并不是一個很好的辦法,原因如下:發送一個指令的方式很慢,因為您必須為每個指令都會有往返的時間消耗。雖然可以使用管道模式來操作,但為了批量插入多條記錄,您需要在讀取回複的同時編寫新指令,以確定盡可能快地插入。
另外,隻有一小部分用戶端支援非阻塞 I/O 操作,而且并不是所有的用戶端都能夠以最大化吞吐量這種有效的方式來解析這些回複。 由于以上這些原因,将大量資料導入Redis的首選方式是生成包含Redis協定的文本檔案(原始格式),以便調用插入所需資料所需的指令。
例如,如果我需要生成一個大型資料集,其中包含數十億個鍵:“keyN - > ValueN”,我将建立一個包含如下Redis協定格式的指令的檔案:
一旦建立了該檔案,剩下的操作就是盡可能快地将其提供給Redis。在過去,做法是使用如下的netcat的指令:
然而,這并不是一個非常可靠的方式來執行批量導入,因為 netcat 指令并不會真正知道所有資料何時傳輸完畢,并且也無法檢查發生的錯誤。在Redis的2.6或更高版本中,redis-cli實用程式支援稱為管道的新模式,該模式就是為了執行批量插入而存在的。
使用管道模式,運作的指令如下所示:
這将産生類似于這樣的輸出:
redis-cli實用程式還将確定隻将從Redis執行個體收到的錯誤重定向到标準輸出。
2、生成Redis協定(Generating Redis Protocol)
其中<cr>表示“\r”(或ASCII字元13),<lf>表示“\n”(或ASCII字元10)。
例如,指令 SET key value 由以下協定表示:
或者表示為引用的字元串:
為批量插入而生成的檔案隻不過是由以上述方式表示的一個接一個的指令組成的。
以下Ruby函數生成有效的協定:
使用上述功能,可以使用此程式輕松生成上例中的鍵值對:
我們可以在redis-cli的管道中直接運作程式,以執行我們的第一次海量導入會話。
3、管道模式如何在引擎下工作(How the pipe mode works under the hoods)
redis-cli管道模式的速度和netcat一樣快,與此同時,仍然能夠明白伺服器最後一次發送回複的時間。
這是通過以下方式獲得的:
3.1、redis-cli --pipe Redis用戶端會盡可能快的向伺服器發送資料。
3.2、同時,會盡可能快的讀取并解析資料檔案中的内容。
3.3、一旦從标準輸入裝置讀取資料完畢,它将會發送一個帶有20個位元組的字元串的特殊的ECHO指令到伺服器:我們确信這是最新發送的指令,如果我們收到作為批量回複的相同的20個位元組的消息,我們确信可以做“答複比對檢查”。
3.4、這個特殊的最終指令一經發送,Redis伺服器端将接收到回複和這20個位元組的回複消息做比對。如果比對,它可以成功退出,表示插入完畢。
使用這個技巧,我們不需要解析我們發送給伺服器的協定,以了解我們發送了多少條指令,僅僅是一個答複而已。
但是,在解析回複時,我們會對所有解析的回複進行計數,以便在最後我們能夠告訴使用者傳輸到伺服器的指令的數量在這次批量插入的會話中。
4、示例代碼操作
4.1、準備資料檔案,格式是文本檔案,名稱是:redis_commands.txt。
我在Windows環境下生成了一個txt檔案,一條資料一行,代碼如下:
我生成了500萬的資料,因為這個文本檔案我是在Windows環境下生成的,是以需要格式轉換。
4.2、如果使用Windows環境下生成的檔案,需要進行格式轉換,如果是在Linux環境下生成的檔案就不需要格式轉換,如果文本檔案比較大,執行轉換時間會有幾秒,等待即可。
執行格式轉換
以上代碼進行格式轉換完畢
需要說明一點,unix2dos這個指令需要先安裝,如果沒有安裝,會提示:command not found。
執行以下指令安裝:
4.3、進行資料批量插入
批量插入資料成功,一千萬的資料大概要花費50幾秒左右。
三、總結
好的,今天就寫到這裡,大批量資料插入的就是這麼容易。隻要了解了,其實也不是很難,技術就是一層窗戶紙,一捅就破,但是沒人捅就比較麻煩。下一篇文章,我們将寫一些關于redis協定格式的文章,如果要涉及大批量資料插入,就會涉及到redis規範協定的問題。