如何高效地向如何高效地向Redis插入大量的数据(推荐)插入大量的数据(推荐)
最近有个哥们在群里问,有一个日志,里面存的是IP地址(一行一个),如何将这些IP快速导入到Redis中。
我刚开始的建议是Shell+redis客户端。
今天,查看Redis官档,发现文档的首页部分(http://www.redis.io/documentation)有一个专门的主题是讲述“Redis Mass
Insertion”的,才知道自己的建议很low。
官方给出的理由如下:
Using a normal Redis client to perform mass insertion is not a good idea for a few reasons: the naive approach of sending
one command after the other is slow because you have to pay for the round trip time for every command. It is possible to
use pipelining, but for mass insertion of many records you need to write new commands while you read replies at the same
time to make sure you are inserting as fast as possible.
Only a small percentage of clients support non-blocking I/O, and not all the clients are able to parse the replies in an
efficient way in order to maximize throughput. For all this reasons the preferred way to mass import data into Redis is to
generate a text file containing the Redis protocol, in raw format, in order to call the commands needed to insert the required
data.
大意是:
1> 每个redis客户端命令之间有往返时延。
2> 只要一部分客户端支持非阻塞I/O。
个人理解是,redis命令从执行到结果返回,有一定的时延,即便采用多个redis客户单并发插入,也很难提高吞吐量,因为,
只有非阻塞I/O只能针对有限个连接操作。
那么如何高效的插入呢?那么如何高效的插入呢?
官方在2.6版本推出了一个新的功能-pipe mode,即将支持Redis协议的文本文件直接通过pipe导入到服务端。
说来拗口,具体实现步骤如下:说来拗口,具体实现步骤如下:
1. 新建一个文本文件,包含redis命令
SET Key0 Value0
SET Key1 Value1
...
SET KeyN ValueN
如果有了原始数据,其实构造这个文件并不难,譬如shell,python都可以
2. 将这些命令转化成Redis Protocol。
因为Redis管道功能支持的是Redis Protocol,而不是直接的Redis命令。
如何转化,可参考后面的脚本。
3. 利用管道插入
cat data.txt | redis-cli --pipe
Shell VS Redis pipe
下面通过测试来具体看看Shell批量导入和Redis pipe之间的效率。
测试思路:分别通过shell脚本和Redis pipe向数据库中插入10万相同数据,查看各自所花费的时间。
Shell
脚本如下:
#!/bin/bash
for ((i=0;i<100000;i++))
do
echo -en "helloworld" | redis-cli -x set name$i >>redis.log
done
评论0