针对redis大量插入键值对的情况-官方redis建议-mass insertion(用redis的协议或用管道pipeline)


官方链接

1.Use the protocol, Luke

  • 1.首选方式是生成包含 Redis 协议的文本文件,以原始格式调用插入所需数据所需的命令

例如:如果我需要生成一个大型数据集,其中表单中有数十亿个密钥:“keyN-> ValueN”,我将创建一个文件,其中包含 Redis 协议格式中的以下命令:
SET Key0 Value0
SET Key1 Value1

SET KeyN ValueN

  • 2.创建此文件后,剩余的操作是尽快将其馈送至 Redis。过去,这样做的方法是使用以下命令:netcat
(cat data.txt; sleep 10) | nc localhost 6379 > /dev/null
  • 3.然而,这不是一个非常可靠的方法来执行大规模导入,因为 Netcat 不知道何时传输了所有数据,并且无法检查是否有错误。在 2.6 或以后版本的 Redis 中,该实用程序支持一种称为管道模式的新模式,该模式旨在执行大规模插入。使用管道模式运行的命令如下所示:
cat data.txt | redis-cli --pipe

That will produce an output similar to this:

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

2.Generating Redis Protocol

  • The Redis protocol is extremely simple to generate and parse, and is Documented here. However in order to generate protocol for the goal of mass insertion you don’t need to understand every detail of the protocol, but just that every command is represented in the following way:

*
$



  • Where means “\r” (or ASCII character 13) and means “\n” (or ASCII character 10).

  • For instance the command SET key value is represented by the following protocol:

*3
$3
SET
$3
key
$5
value
Or represented as a quoted string:

“*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n”

  • The file you need to generate for mass insertion is just composed of commands represented in the above way, one after the other.

  • The following Ruby function generates valid protocol:

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

  • Using the above function it is possible to easily generate the key value pairs in the above example, with this program:

(0…1000).each{|n|
STDOUT.write(gen_redis_proto(“SET”,“Key#{n}”,“Value#{n}”))
}

  • We can run the program directly in pipe to redis-cli in order to perform our first mass import session.

$ ruby proto.rb | redis-cli --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 hood

  • 笔者公司为了压缩数据,使用protobuf充当redis的数据,没用redis的协议,用了redis的协议的化,序列化和反序列更快,但是二进制更省内存

通过以下方式获得:

  • 重新分配 - 管道尝试以最快的速度将数据发送到服务器。
  • 同时,它会在可用时读取数据,试图解析数据。
  • 一旦没有更多的数据从 stdin 读取,它发送一个特殊的ECHO命令与随机 20 字节字符串: 我们确信这是发送的最新命令, 我们相信我们可以匹配的答复检查, 如果我们收到相同的 20 字节作为批量答复.
  • 一旦发送此特殊的最终命令,接收回复的代码开始与这 20 字节匹配回复。当到达匹配的答复时,它可以成功退出。

使用此技巧,我们不需要解析我们发送到服务器的协议,以了解我们发送了多少命令,但只是回复。但是,在分析回复时,我们会对所有解析的回复进行计数,以便最终我们能够告诉用户通过大规模插入会话传输到服务器的命令量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值