Redis【有与无】【UR7】Redis大量插入

本文基于Redis 6.0.9版本,前提至少 Redis 3.0或更高版本。

目录

1.Redis大量插入

1.1.使用Luke协议

1.2.生成Redis协议

1.3.管道模式(pipe mode)在hood下如何工作


1.Redis大量插入

有时,Redis实例需要在短时间内加载大量预先存在或用户生成的数据,以便尽可能快地创建数百万个键。

这称为批量插入,并且本文档的目标是提供有关如何尽可能快地向Redis提供数据的信息。

1.1.使用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并不真正知道何时传输所有数据,也无法检查错误。 在2.6或更高版本的Redis中,redis-cli实用程序支持一种称为管道模式(pipe mode)的新模式,该模式旨在执行批量插入。

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实例收到的错误重定向到标准输出。

1.2.生成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"
    }
    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 --pipe
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 1000

1.3.管道模式(pipe mode)在hood下如何工作

redis-cli的管道模式内部需要与netcat一样快,并且能够理解服务器何时同时发送了最后一个答复。

这是通过以下方式获得的:

  • redis-cli --pipe 尝试将数据尽快发送到服务器。
  • 同时,它会在可用时读取数据,尝试对其进行解析。
  • 一旦没有更多数据可以从stdin中读取,它将发送一个特殊的ECHO命令,该命令带有一个随机的20 byte 字符串:我们确定这是最新发送的命令,并且我们确定,如果我们收到相同的20 bytes作为批量回复,我们可以匹配回复检查 。
  • 发送此特殊的最终命令后,代码接收答复将开始与这20 bytes 的答复进行匹配。 达到匹配的答复后,可以成功退出。

使用此技巧,我们无需解析发送给服务器的协议即可了解要发送的命令数量,而只需了解答复即可。

但是,在解析答复时,我们会对所有已解析的答复进行计数,以便最后我们可以告诉用户通过大容量插入会话传输到服务器的命令数量。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琴 韵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值