Redis进阶实践之十六 Redis大批量增加数据
一、介紹
????????? 有時候,Redis實例需要在很短的時間內(nèi)加載大量先前存在或用戶生成的數(shù)據(jù),以便盡可能快地創(chuàng)建數(shù)百萬個鍵。這就是所謂的批量插入,本文檔的目標是提供有關(guān)如何以盡可能快的速度向Redis提供數(shù)據(jù)的信息。如果想查看英文原文,地址如下:https://redis.io/topics/mass-insert
二、操作詳解
?????
?????????? 話不多說,直接進入主題了。
????????? 1、使用協(xié)議,盧克(Use the protocol, Luke)
???????????????? 使用普通Redis客戶端的方式執(zhí)行批量插入的操作并不是一個很好的辦法,原因如下:發(fā)送一個命令的方式很慢,因為您必須為每個命令都會有往返的時間消耗。雖然可以使用管道模式來操作,但為了批量插入多條記錄,您需要在讀取回復(fù)的同時編寫新命令,以確保盡可能快地插入。
???????????????? 另外,只有一小部分客戶端支持非阻塞 I/O 操作,而且并不是所有的客戶端都能夠以最大化吞吐量這種有效的方式來解析這些回復(fù)。 由于以上這些原因,將大量數(shù)據(jù)導(dǎo)入Redis的首選方式是生成包含Redis協(xié)議的文本文件(原始格式),以便調(diào)用插入所需數(shù)據(jù)所需的命令。
??????????????? 例如,如果我需要生成一個大型數(shù)據(jù)集,其中包含數(shù)十億個鍵:“keyN - > ValueN”,我將創(chuàng)建一個包含如下Redis協(xié)議格式的命令的文件:
???????????????? 一旦創(chuàng)建了該文件,剩下的操作就是盡可能快地將其提供給Redis。在過去,做法是使用如下的netcat的命令:
??????????????? 然而,這并不是一個非常可靠的方式來執(zhí)行批量導(dǎo)入,因為 netcat 命令并不會真正知道所有數(shù)據(jù)何時傳輸完畢,并且也無法檢查發(fā)生的錯誤。在Redis的2.6或更高版本中,redis-cli實用程序支持稱為管道的新模式,該模式就是為了執(zhí)行批量插入而存在的。
??????????????? 使用管道模式,運行的命令如下所示:
????????? ? ? ? 這將產(chǎn)生類似于這樣的輸出:
?????????????? redis-cli實用程序還將確保只將從Redis實例收到的錯誤重定向到標準輸出。
???????? 2、生成Redis協(xié)議(Generating Redis Protocol)
????????????????? Redis協(xié)議生成和解析非常簡單,如果想了解協(xié)議的詳情,英文原地址點擊《這里》,我翻譯的文章的地址點擊《Redis進階實踐之十七 Redis協(xié)議的規(guī)范》。然而,為了生成用于大容量插入?yún)f(xié)議的目標,您不需要了解協(xié)議的每個細節(jié),只需要按照以下方式書寫每個命令:
???????????? ?? 其中<cr>表示“\r”(或ASCII字符13),<lf>表示“\n”(或ASCII字符10)。
??????????????? 例如,命令 SET key value 由以下協(xié)議表示:
????????????? 或者表示為引用的字符串:
???????????? 為批量插入而生成的文件只不過是由以上述方式表示的一個接一個的命令組成的。
???????????? 以下Ruby函數(shù)生成有效的協(xié)議:
???????????? 使用上述功能,可以使用此程序輕松生成上例中的鍵值對:
????????????? 我們可以在redis-cli的管道中直接運行程序,以執(zhí)行我們的第一次海量導(dǎo)入會話。
??????? 3、管道模式如何在引擎下工作(How the pipe mode works under the hoods)
???????????????? redis-cli管道模式的速度和netcat一樣快,與此同時,仍然能夠明白服務(wù)器最后一次發(fā)送回復(fù)的時間。
???????????????? 這是通過以下方式獲得的:
????????????????? 3.1、redis-cli --pipe Redis客戶端會盡可能快的向服務(wù)器發(fā)送數(shù)據(jù)。
???????????? ? ?? 3.2、同時,會盡可能快的讀取并解析數(shù)據(jù)文件中的內(nèi)容。
????????????????? 3.3、一旦從標準輸入設(shè)備讀取數(shù)據(jù)完畢,它將會發(fā)送一個帶有20個字節(jié)的字符串的特殊的ECHO命令到服務(wù)器:我們確信這是最新發(fā)送的命令,如果我們收到作為批量回復(fù)的相同的20個字節(jié)的消息,我們確信可以做“答復(fù)匹配檢查”。
????????????????? 3.4、這個特殊的最終命令一經(jīng)發(fā)送,Redis服務(wù)器端將接收到回復(fù)和這20個字節(jié)的回復(fù)消息做匹配。如果匹配,它可以成功退出,表示插入完畢。
?????????????? 使用這個技巧,我們不需要解析我們發(fā)送給服務(wù)器的協(xié)議,以了解我們發(fā)送了多少條命令,僅僅是一個答復(fù)而已。
?????????????? 但是,在解析回復(fù)時,我們會對所有解析的回復(fù)進行計數(shù),以便在最后我們能夠告訴用戶傳輸?shù)椒?wù)器的命令的數(shù)量在這次批量插入的會話中。
???? 4、示例代碼操作
?????????? 4.1、準備數(shù)據(jù)文件,格式是文本文件,名稱是:redis_commands.txt。
???????????? ? ? ? 我在Windows環(huán)境下生成了一個txt文件,一條數(shù)據(jù)一行,代碼如下:
?????????????????? 我生成了500萬的數(shù)據(jù),因為這個文本文件我是在Windows環(huán)境下生成的,所以需要格式轉(zhuǎn)換。
????????? 4.2、如果使用Windows環(huán)境下生成的文件,需要進行格式轉(zhuǎn)換,如果是在Linux環(huán)境下生成的文件就不需要格式轉(zhuǎn)換,如果文本文件比較大,執(zhí)行轉(zhuǎn)換時間會有幾秒,等待即可。
????????????????? 執(zhí)行格式轉(zhuǎn)換
????????????????? 以上代碼進行格式轉(zhuǎn)換完畢
????????????????? 需要說明一點,unix2dos這個命令需要先安裝,如果沒有安裝,會提示:command not found。
????????????????? 執(zhí)行以下命令安裝:
?????????? 4.3、進行數(shù)據(jù)批量插入
????????????????? 批量插入數(shù)據(jù)成功,一千萬的數(shù)據(jù)大概要花費50幾秒左右。
三、總結(jié)
?????????? 好的,今天就寫到這里,大批量數(shù)據(jù)插入的就是這么容易。只要理解了,其實也不是很難,技術(shù)就是一層窗戶紙,一捅就破,但是沒人捅就比較麻煩。下一篇文章,我們將寫一些關(guān)于redis協(xié)議格式的文章,如果要涉及大批量數(shù)據(jù)插入,就會涉及到redis規(guī)范協(xié)議的問題。
總結(jié)
以上是生活随笔為你收集整理的Redis进阶实践之十六 Redis大批量增加数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux基本命令+Makefile
- 下一篇: oracle 设置查询条数,SQL、My