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

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

一、介绍

          有时候,Redis实例需要在很短的时间内加载大量先前存在或用户生成的数据,以便尽可能快地创建数百万个键。这就是所谓的批量插入,本文档的目标是提供有关如何以尽可能快的速度向Redis提供数据的信息。如果想查看英文原文,地址如下:https://redis.io/topics/mass-insert


二、操作详解
     

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

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

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

                 另外,只有一小部分客户端支持非阻塞 I/O 操作,而且并不是所有的客户端都能够以最大化吞吐量这种有效的方式来解析这些回复。 由于以上这些原因,将大量数据导入Redis的首选方式是生成包含Redis协议的文本文件(原始格式),以便调用插入所需数据所需的命令。

                例如,如果我需要生成一个大型数据集,其中包含数十亿个键:“keyN - > ValueN”,我将创建一个包含如下Redis协议格式的命令的文件:

                 SET Key0 Value0SET 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协议生成和解析非常简单,如果想了解协议的详情,英文原地址点击《这里》,我翻译的文章的地址点击《Redis进阶实践之十七 Redis协议的规范》。然而,为了生成用于大容量插入协议的目标,您不需要了解协议的每个细节,只需要按照以下方式书写每个命令:

              *<args><cr><lf>$<len><cr><lf><arg0><cr><lf><arg1><cr><lf>...<argN><cr><lf>


                其中<cr>表示“\r”(或ASCII字符13),<lf>表示“\n”(或ASCII字符10)。

                例如,命令 SET key value 由以下协议表示:

              *3<cr><lf>$3<cr><lf>SET<cr><lf>$3<cr><lf>key<cr><lf>$5<cr><lf>value<cr><lf>


              或者表示为引用的字符串:

              "*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"}protoendputs 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 --pipeAll 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 Value0SET Key1 Value1SET Key2 Value2SET Key3 Value3SET Key4 Value4SET Key5 Value5SET Key6 Value6SET Key7 Value7SET Key8 Value8SET Key9 Value9SET Key10 Value10...SET KeyN ValueN


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


          4.2、如果使用Windows环境下生成的文件,需要进行格式转换,如果是在Linux环境下生成的文件就不需要格式转换,如果文本文件比较大,执行转换时间会有几秒,等待即可。

                  执行格式转换

              [root@linux ~]# unix2dos redis_commands.txtunix2dos: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 --pipeAll data transferred.Waiting for the last reply...Last reply received from server.errors:0,replies:10000000


                  批量插入数据成功,一千万的数据大概要花费50几秒左右。


三、总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目经理沟通的四个好习惯

一名项目经理沟通的时间占到工作时间的80%&#xff0c;所以如何提高沟通效率就变成了项目经理提高工作效率的重点。 一名优秀的项目经理&#xff0c;无疑是一个好的沟通者。因为&#xff0c;专业的技能可以使你成为某个领域的专家&#xff0c;但出色的沟通技能&#xff0c…

u盘安装成功计算机里找不到文件夹,u盘里的文件不见了,详细教您U盘内容不显示怎么办...

在工作、学习中&#xff0c;我们需要把资料携带外出的时候&#xff0c;首选的存储工具基本上都是U盘。不过有用户在使用U盘时却遇到了U盘的所有的文件夹不见了的情况&#xff0c;但内存的明明文件还在&#xff0c;这到底是为什么呢&#xff1f;难道U盘的文件真的不见了吗&#…

五分钟实现SpringBoot快速入门

文章目录一、创建Maven工程二、添加SpringBoot的起步依赖三、编写SpringBoot引导类四、编写Controller五、测试六、SpringBoot工程热部署一、创建Maven工程 二、添加SpringBoot的起步依赖 文件位置&#xff1a;pom.xml SpringBoot要求&#xff0c;项目要继承SpringBoot的起步…

分布式系统开发工具包 —— 基于Kryo的Java对象序列化

Kryo是用于Java语言的一个快速和高效的对象图序列化框架。Kryo项目的目的是快速、高效、方便地使用API。当需要持久化对象的时候&#xff0c;不论是持久化到文件、数据库还是网络&#xff0c;都可以使用Kryo。 目前Kryo已经到了4.0.1版本以上了。本文的介绍适用于V2.0以上版本。…

代码编辑器Sublime Text 可以跨平台(linux,window,os x)

说到代码编辑器&#xff0c;大部分人首先会想到UltraEdit&#xff0c;EmEditor和notepad。但今天要介绍的是另一款功能非常强大的代码编辑器——Sublime Text。Sublime Text还是一款跨 OS X、Linux 和 Windows 三大平台的文字/代码编辑器。除了Sublime Text出色的功能&#xff…

计算机画图怎样更改文字,如何在图片上改字|超简单的修改图片里文字方法

这篇文章将要给大家介绍的是&#xff0c;不用联网&#xff0c;不用下载专业的图像处理软件&#xff0c;单纯用画图工具&#xff0c;就能修改表情包、图片上文字的方法&#xff0c;只适合简单的图片处理&#xff0c;复杂的还是交给专业的图像处理工具吧。下面系统吧就给大家带来…

软件维护

所谓软件维护就是在软件已经交付使用之后&#xff0c;为了改正错误或满足新的需要而修改软件的过程。可以通过描述软件交付使用后可能进行的4项活动&#xff0c;具体地定义软件维护。 1.改正性维护 因为软件测试不可能暴露出一个大型软件系统中所有潜藏的错误&#xff0c;所以…

【intellij idea】Project Structure 讲解

参考文章&#xff1a;戳这里 谢谢楼主分享

将以太坊封装为 ERC20

将以太坊封装为 ERC20 TOKEN 很多 DAPP 都是在处理 ERC20接口的 token, 其实很容易将以太坊封装为 ERC20,这样就可以统一处理, 至少我目前在做的雷电网络就是这么处理的. 主要内容复制在网络https://programtheblockchain.com/posts/2018/05/26/wrapping-ether-in-an-erc20-tok…

javascript高级程序设计学习之数值转换 |Number(),parseInt(),parseFloat()

2019独角兽企业重金招聘Python工程师标准>>> 将非数值转换成数值的函数有三个&#xff1a;Number(),parseInt(),parseFloat(); 小记tip&#xff1a;Number()可以用于任何数据类型&#xff1b;parseInt(),parseFloat()针对的是将字符串&#xff1b; Number()的转换规…

软件的可维护性

可以把软件的可维护性定性地定义为&#xff1a;维护人员理解、改正、改动或改进这个软件的难易程度。 提高可维护性是支配软件工程方法学所有步骤的关键目标。

服务器内存延迟,内存带宽、延迟性能测试

内存带宽、延迟性能测试华为FusionServer 2488H V5服务器主板集成了48个内存插槽&#xff0c;但送测机器配备有限。由于送测机型整合了四通道内存控制器&#xff0c;这样使得平台的内存带宽得到了明显的提升。SiSoftware Sandra Lite 2011中提供了内存带宽、内存延迟和缓存性能…

Git学习的最佳教程

身为网页设计师或者网页开发者的你&#xff0c;可能已经听说过Git这个正快速成长的版本控制系统。它由GitHub维护&#xff1b;GitHub是一个开放性的、存储众人代码的网站。如果你想学习如何使用Git&#xff0c;请参考本文。在文章最后&#xff0c;我们罗列了其他Git学习资源。 …

如何使用idea快速创建SpringBoot项目

文章目录一、二、三、四、五、一、 二、 三、 四、 五、

解决pip安装模块报错Cannot fetch index base URL http://pypi.python.org/simple/

产生这个问题的原因呢和github一样,因为他们用的cdn被墙.经小伙伴反馈,解决办法如下. 通过指定国内镜像源来安装: pip --trusted-host 镜像源 install 模块名 -i 镜像源路径 例如:pip --trusted-host pypi.doubanio.com install paramiko -i http://pypi.doubanio.com/simple 注…

闪光css,CSS实现的一闪而过的图片闪光效果

只需要两个html元素和一个css变换&#xff0c;我就能创造出我自己的闪光效果。让我们来实现它&#xff01;呈现光泽图片下面就是这张addy在他博客上使用的图片&#xff1a;比我需要的要大一些&#xff0c;但你可以把它裁剪一些。注意&#xff1a;左边的那张是纯白色的&#xff…

什么是可重用性

所谓重用&#xff08;reuse&#xff09;是指同一事物不做修改或稍加改动就在不同环境中多次重复使用。大量使用可重用的软件构件来开发软件&#xff0c;可以从下述两个方面提高软件的可维护性。 (1) 通常&#xff0c;可重用的软件构件在开发时都经过很严格的测试&#xff0c;可…

MATLAB矩阵操作和算术运算符

矩阵的表示 矩阵之间用空格或者是逗号间隔 矩阵可以拼接&#xff08;可以用矩阵拼接&#xff09; 实部矩阵和虚部矩阵构成复数矩阵&#xff0c;一一对应。 冒号表达式&#xff1a; 格式&#xff1a; e1:e2:e3 e1表示初始值 e2表示步长 e3表示终止值 e2省略则e2为1 lins…

循序渐进学好编程,不要太急!!!

软件开发人员是一个日新月异的领域—–IT中的大师&#xff0c;今天的编程方式与明天的编程或许截然不同&#xff0c;技术在不断地革新&#xff0c;新语言、新平台的如雨后春笋般出现、更好的解决方案的冒出&#xff0c;因此我们需要跟得上节奏&#xff0c;我们别无选择&#xf…