卡飞资源网

专业编程技术资源共享平台

Redis源码解析(五)管道

Redis的网络交互模式

Redis服务器在与客户端交互的时候采用TCP协议。在交互过程中,由客户端发起命令请求,随后服务端返回结果响应。

在一个命令请求只包含一个命令的情况下,对于多个命令我们可以看到Redis的处理序列如下:

  • 客户端:INCR TESTSET
  • 服务器:1
  • 客户端:INCR TESTSET
  • 服务器:2
  • 客户端:INCR TESTSET
  • 服务器:3
  • 客户端:INCR TESTSET
  • 服务器:4


Redis管道

Redis管道指的是Redis可以处理在一个命令请求中放入多个命令,并同时返回多个命令处理结果的功能。显而易见的是,因为网络交互次数的减少,使用管道功能后总响应时间也会减少。

值得注意的是,因为Redis使用内存来记录响应结果,推荐在使用管道功能后每次的命令请求中的命令数量保持一致。这样可以获得一个比较均匀的处理时间。

在使用管道功能后,对于多个命令我们可以看到Redis的处理序列如下:

  • 客户端:INCR TESTSET
  • 客户端:INCR TESTSET
  • 客户端:INCR TESTSET
  • 客户端:INCR TESTSET
  • 服务器:1
  • 服务器:2
  • 服务器:3
  • 服务器:4


Redis管道性能提升

使用管道后,不仅能在网络性能上得到提升。事实上,对于Redis来说,在处理命令时不会消耗很多时间,但在通过读写操作读写命令时会消耗很多时间。所以在用户层和核心层的互相传递上会获得一个相当大的速度惩罚。

使用管道后,多个命令可以通过一次系统读取来获得。多个命令结果也可以通过一次系统写入操作来输出。随着命令数量的上升,使用管道后可以获得10倍的性能提升。

以下是实际的一个测试案例。因案例较为简单,性能的差异比理论值更大。

#!/bin/bash

echo "pipeline test"
echo -en "PING\n"|nc localhost 6379

#使用管道一次性进行10000次自增
echo "with pipelining" > result
echo -en "SET STR1 0\n"|nc localhost 6379
scom="INCR STR1\n"
com_str=""
for i in {1..10000};do
    com_str="$com_str$scom"
done

start=`date +%s%N`
echo $start

echo -en $com_str|nc localhost 6379

end=`date +%s%N`
echo $end

spend=`echo "scale=3; ($end-$start)/1000000000.0" | bc`
echo $spend >> result

#进行10000次单笔自增
echo "without pipelining" >> result
echo -en "SET STR1 0\n"|nc localhost 6379

start=`date +%s%N`
echo $start

for i in {1..10000};do
    echo -en "INCR STR1\n"|nc localhost 6379
done

end=`date +%s%N`
echo $end

spend=`echo "scale=3; ($end-$start)/1000000000.0" | bc`
echo $spend >> result


管道和脚本的比较

Redis支持脚本进行多命令的操作。在使用上,管道因为批量读写的特性适合进行批量化操作。但正因为是批量读写,管道无法对于其中的某个处理结果做实时响应。在这方面,脚本可以对处理结果快速响应,适合实时操作。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言