您好,欢迎来到测品娱乐。
搜索
您的当前位置:首页Redis进阶实践之十六Redis大批量增加数据

Redis进阶实践之十六Redis大批量增加数据

来源:测品娱乐
Redis进阶实践之⼗六Redis⼤批量增加数据

⼀、介绍

有时候,Redis实例需要在很短的时间内加载⼤量先前存在或⽤户⽣成的数据,以便尽可能快地创建数百万个键。这就是所谓的批量插⼊,本⽂档的⽬标是提供有关如何以尽可能快的速度向Redis提供数据的信息。如果想查看英⽂原⽂,地址如下:

⼆、操作详解

话不多说,直接进⼊主题了。

1、使⽤协议,卢克(Use the protocol, Luke)

使⽤普通Redis客户端的⽅式执⾏批量插⼊的操作并不是⼀个很好的办法,原因如下:发送⼀个命令的⽅式很慢,因为您必须为每个命令都会有往返的时间消耗。虽然可以使⽤管道模式来操作,但为了批量插⼊多条记录,您需要在读取回复的同时编写新命令,以确保尽可能快地插⼊。

另外,只有⼀⼩部分客户端⽀持⾮阻塞 I/O 操作,⽽且并不是所有的客户端都能够以最⼤化吞吐量这种有效的⽅式来解析这些回复。 由于以上这些原因,将⼤量数据导⼊Redis的⾸选⽅式是⽣成包含Redis协议的⽂本⽂件(原始格式),以便调⽤插⼊所需数据所需的命令。

例如,如果我需要⽣成⼀个⼤型数据集,其中包含数⼗亿个键:“keyN - > ValueN”,我将创建⼀个包含如下Redis协议格式的命令的⽂件:

SET Key0 Value0 SET Key1 Value1 ...

SET KeyN ValueN

⼀旦创建了该⽂件,剩下的操作就是尽可能快地将其提供给Redis。在过去,做法是使⽤如下的netcat的命令:

(cat data.txt; sleep 10) | nc localhost 6379 > /dev/null

然⽽,这并不是⼀个⾮常可靠的⽅式来执⾏批量导⼊,因为 netcat 命令并不会真正知道所有数据何时传输完毕,并且也⽆法检查发⽣的错误。在Redis的2.6或更⾼版本中,redis-cli实⽤程序⽀持称为管道的新模式,该模式就是为了执⾏批量插⼊⽽存在的。 使⽤管道模式,运⾏的命令如下所⽰:

cat data.txt | redis-cli --pipe

这将产⽣类似于这样的输出:

All data transferred. Waiting for the last reply... Last reply received from server. errors: 0, replies: 1000000

redis-cli实⽤程序还将确保只将从Redis实例收到的错误重定向到标准输出。

2、⽣成Redis协议(Generating Redis Protocol)

Redis协议⽣成和解析⾮常简单,如果想了解协议的详情,英⽂原地址点击《》,我翻译的⽂章的地址点击《》。然⽽,为了⽣成⽤于⼤容量插⼊协议的⽬标,您不需要了解协议的每个细节,只需要按照以下⽅式书写每个命令:

* $ ...

其中表⽰“\\r”(或ASCII字符13),表⽰“\\n”(或ASCII字符10)。 例如,命令 SET key value 由以下协议表⽰:

*3 $3 SET $3 key $5 value

或者表⽰为引⽤的字符串:

\"*3\\r\\n$3\\r\\nSET\\r\\n$3\\r\\nkey\\r\\n$5\\r\\nvalue\\r\\n\"

为批量插⼊⽽⽣成的⽂件只不过是由以上述⽅式表⽰的⼀个接⼀个的命令组成的。 以下Ruby函数⽣成有效的协议:

def gen_redis_proto(*cmd) proto = \"\"

proto << \"*\"+cmd.length.to_s+\"\\r\\n\" cmd.each{|arg|

proto << \"$\"+arg.to_s.bytesize.to_s+\"\\r\\n\" proto << arg.to_s+\"\\r\\n\" } proto end

puts gen_redis_proto(\"SET\",\"mykey\",\"Hello World!\").inspect

使⽤上述功能,可以使⽤此程序轻松⽣成上例中的键值对:

(0...1000).each{|n|

STDOUT.write(gen_redis_proto(\"SET\",\"Key#{n}\",\"Value#{n}\")) }

我们可以在redis-cli的管道中直接运⾏程序,以执⾏我们的第⼀次海量导⼊会话。

$ ruby proto.rb | redis-cli -h 192.168.127.130 -p 6379 --pipe All data transferred. Waiting for the last reply... Last reply received from server. errors: 0, replies: 1000

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⽂件,⼀条数据⼀⾏,代码如下:

SET Key0 Value0 SET Key1 Value1 SET Key2 Value2 SET Key3 Value3 SET Key4 Value4 SET Key5 Value5 SET Key6 Value6 SET Key7 Value7 SET Key8 Value8 SET Key9 Value9 SET Key10 Value10 ...

SET KeyN ValueN

我⽣成了500万的数据,因为这个⽂本⽂件我是在Windows环境下⽣成的,所以需要格式转换。

4.2、如果使⽤Windows环境下⽣成的⽂件,需要进⾏格式转换,如果是在Linux环境下⽣成的⽂件就不需要格式转换,如果⽂本⽂件⽐较⼤,执⾏转换时间会有⼏秒,等待即可。

执⾏格式转换

[root@linux ~]# unix2dos redis_commands.txt

unix2dos:converting file redis_commands.txt to DOS format ...

以上代码进⾏格式转换完毕

需要说明⼀点,unix2dos这个命令需要先安装,如果没有安装,会提⽰:command not found。 执⾏以下命令安装:

[root@linux ~]# yum install unix2dos

4.3、进⾏数据批量插⼊

[root@linux ~]# cat redis_commands.txt | redis-cli -h 192.168.127.130 -p 6379 [-a \"password\"] -n 0 --pipe All data transferred.Waiting for the last reply... Last reply received from server. errors:0,replies:10000000

批量插⼊数据成功,⼀千万的数据⼤概要花费50⼏秒左右。

三、总结

好的,今天就写到这⾥,⼤批量数据插⼊的就是这么容易。只要理解了,其实也不是很难,技术就是⼀层窗户纸,⼀捅就破,但是没⼈捅就⽐较⿇烦。下⼀篇⽂章,我们将写⼀些关于redis协议格式的⽂章,如果要涉及⼤批量数据插⼊,就会涉及到redis规范协议的问题。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- cepb.cn 版权所有 湘ICP备2022005869号-7

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务