当前位置: 首页 > news >正文

广州知名网站知名软装设计公司

广州知名网站,知名软装设计公司,网站定制制作,手机网站制作天强科技Redis进阶:管道 管道是啥?我们做开发的同学们经常会在 Linux 环境中用到管道命令,比如 ps -ef | grep php 。在之前学习 Laravel框架时的 【Laravel6.4】管道过滤器https://mp.weixin.qq.com/s/CK-mcinYpWCIv9CsvUNR7w 这篇文章中&#xff0c…

Redis进阶:管道

管道是啥?我们做开发的同学们经常会在 Linux 环境中用到管道命令,比如 ps -ef | grep php 。在之前学习 Laravel框架时的 【Laravel6.4】管道过滤器https://mp.weixin.qq.com/s/CK-mcinYpWCIv9CsvUNR7w 这篇文章中,我们也详细的讲过管道这个概念。如果有不清楚的小伙伴可以回去复习一下哦。

在 Redis 中,也有管道的概念。不过说白了,就是为了节省网络连接的通信成本而让多个操作一次发送。没错,概念就是这么简单。不过,咱们还是要好好掰扯掰扯到底是为啥要这样。

请求与响应

Redis 服务大部分情况下也是一个传统的 TCP 服务,客户端需要通过 TCP 连接到服务端,然后把命令发送到服务端,服务端处理完成后再返回给客户端。用我们这些 Web 工程师最熟悉的概念来说,就是一个请求和响应的过程。

既然有了这个过程,那么必然的,在请求和响应的传输过程中,网络带来的性能损耗肯定是会存在的。内网或本机传输还好,外网传输则可能会要了老命了。从一个请求发出,到一个响应接收到,这中间消耗的时间叫做 RTT(Round Trip Time 往返时间)。

设想,如果我们执行一个命令,RTT 用了 250ms ,那么一秒我们就只能执行 4 个命令。本身对于 Redis 来说,执行速度是非常快的,毕竟咱们操作的是内存。结果因为 RTT 的原因,被网络传输的速度给拖慢了,这就得不偿失了嘛。

那么,是不是可以把多条命令合在一起,然后一起发送出去呢?这样同样的 RTT 时间,我们就可以执行更多的命令,从而达到提高效率的目的。

没错,就是管道啦。

管道

这个东西不新鲜,怎么说呢?MySQL 会吧?大批量插入的时候我们最优先选择的一个处理方案是啥?

insert into t values (xxx,xxx),(xxx,xxx),(xxx,xxx)

是不是这样的批量插入,为的是什么?一样的,减少来回连接 MySQL 的开销,从而加快插入速度。

在 Redis 中也有类似的命令,要是想不起来 MSET 这个命令的话那么您得回到基础篇再好好复习一下了。不过,不只是插入,对于其它命令来说,我们通过管道的方式也能在一次请求中进行批量的执行。如果使用命令行的话,可以这样测试:

➜  (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG

一次性发送了 3 个 PING ,返回了 3 个 PONG 。或者使用命令行客户端。

➜ printf "*3\r\n\$3\r\nSET\r\n\$1\r\na\r\n\$3\r\n111\r\n*2\r\n\$4\r\nincr\r\n\$1\r\na\r\n" |  redis-cli --pipeAll data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 2➜  redis-cli
127.0.0.1:6379> get a
"112"

在应用程序的客户端中,使用就更加方便了,我们直接就来进行速度的测试,使用 SET 插入十万条数据,然后看一下不使用管道和使用管道之间的区别。

首先是不使用管道的(Go语言测试)。

// main.go
t1 := time.Now()for i := 1; i < 100000; i++ {rdb.Set("info:"+strconv.Itoa(i), "val", -1)
}t2 := time.Now()fmt.Println(t2.Sub(t1))// 命令行执行结果
➜ go run main.go 
5.374380805s

循环插入十万条数据,耗时 5.37 秒。接下来我们再使用管道来进行插入。

// main.go
t1 := time.Now()pipe := rdb.Pipeline()
for i := 1; i < 100000; i++ {pipe.Set("info:"+strconv.Itoa(i), "val", -1)
}
pipe.Exec()t2 := time.Now()fmt.Println(t2.Sub(t1))// 命令行执行结果
➜  go run main.go
299.236659ms

是不是要起立鼓掌了,299 毫秒搞定。这里的示例语言用的是 Go ,使用的是 go-redis 这个包。我这里没有开协程,也是线性执行的哦。抛开语言因素,咱们用 PHP 再试一把。

// pipe.php
$redis = new \Redis();
$redis->connect('127.0.0.1');
$redis->flushDB();$t1 = microtime(true);$pipe = $redis->pipeline();
for($i=0;$i<100000;$i++){$pipe->set("info:".$i, "val");
}
$pipe->exec();$t2 = microtime(true);
echo $t2-$t1;// 命令行执行结果
➜ php pipe.php
0.2947039604187

好嘛,这回还快了 5 毫秒,294 毫秒就搞定了。

管道就这么无敌吗?也不是全是,使用管道发送命令时,服务器将被迫回复一个队列答复,占用很多内存。所以,如果你需要发送大量的命令,最好是把他们按照合理数量分批次的处理,例如 10000 条命令,读回复,然后再发送另一个 10000 条的命令,等等。这样速度几乎是相同的,但是在每次回复这 10000 条命令队列时需要非常大量的内存用来组织返回数据内容。

其实话说回来,Redis 足够快,平常我们的 Redis 服务也不会放到外网,基本都是内网连接,总体来说效率应该还是没问题的,除非真的是遇到上面这种需要不停执行大量命令的极端情况。因此,这套功能使用过的同学可能真的不多。

额外

为啥我们在本地 127.0.0.1 的这个回环连接循环执行 SET 会这么慢呢?照理说本地是没有网络开销的呀,只是内存、CPU的通信问题嘛。

好吧,都提到内存和CPU了,那咱们也应该知道,系统进程不是总在执行同一个进程的,会有时间片调度的。当写入一个新命令的时候,会进入到回环接口的缓冲区中,然后等待系统内核安排CPU执行调度,因此,也会有像网络延迟一样的效果。

我们可以配置 redis.conf ,打开 unixsocket 连接方式。unixsocket 是通过描述符连接的方式,不走网络回环请求,MySQL 也有这样的连接方式,但是,只能本地使用,也就是说,真实业务场景下,这样用得不多。

unixsocket /tmp/redis.sock
unixsocketperm 700

然后在命令行使用 redis-cli -s /tmp/redis.sock 连接,同样也可以在程序代码中使用 unix:/tmp/redis.sock进行连接。然后再次测试不使用管道执行十万条的 SET 结果就像下面这样了。

➜ go run main.go
428.709968ms

可以看出,速度还是没有使用管道来得快。

管道与脚本

脚本还记得吧,就是我们之前学习过的 Lua 脚本。如果是非常大量的管道操作可以通过脚本得到更高效的处理,不过呢,前提就是你得先会 Lua ,所以说,这是应对更加极端情况下的一种选择,大部分情况下,我们使用普通的管道就已经非常够用了。

另外就是,Lua 以及 MSET 之类的批量命令是原子的,而 Pipeline 不是,它只是将命令一起发送,到服务端后还是一条一条按顺序地执行。

总结

又是一个好玩的功能吧,不过确实也是一个非常冷门的功能,毕竟这货在日常的普通使用中就已经够快了,而且就像在文章中一直说过的,一次性非常大量的命令执行这种极端业务需求也是不常见的。所以,至少了解一下吧,遇到的时候至少不会抓瞎。

参考文档:

https://redis.io/docs/manual/pipelining/

代码地址:

[https://github.com/zhangyue0503/dev-blog/tree/master/redis/2022/source](

http://www.yayakq.cn/news/899886/

相关文章:

  • 大型网站建设历史淡蓝黑色大气企业网站模板
  • 做网站是不是也是暴利专业开发app公司
  • 快速搭建网站推荐wordpress 评论贴图
  • 兰州兼职做网站网站页面尺寸大小
  • 网站建设的策划文案中国建设银行对公网站
  • 网站建设完成确认书和君网站建设
  • 如何在网站上做自动弹出织梦模板 行业网站
  • 南通网站建设优化有没有专门做一件代发的网站
  • 武夷山市网站建设福州网站建设 找燕狂徒 05
  • 什么是大型门户网站深圳网站制作公司在那
  • 莱芜网络公司网站单位网站建设情况总结
  • 做网站点击挣钱不?wordpress配置多个页面
  • 什么是网站反向链接企业如何申请网址
  • 现在什么网站做基础销量好广州最近传染病情况
  • 网站代建设费用wordpress会员评论
  • 网站建设备案多长时间模板无忧
  • 石家庄信息网官方网站如何在360做网站SEO
  • 网站开发的语言有什么软件郑州做网站的外包公司有哪些
  • 网站建设公司的流程太原网站建设 网站制作
  • 上社网站建设国家企业信息信用系统
  • 外国有没有中国代做数学作业的网站方微商城网站开发
  • 微信怎么开店泰州网站优化公司
  • 河南送变电建设有限公司网站软文营销是什么
  • 国际精品互联网专线如何优化关键词的方法
  • 县局网站建设招标华为商城官网
  • 网站的建设域名空间织梦模板大气网站建设类网站模板
  • 龙华做手机网站做进口假体下巴的网站
  • 建设银行指定网站动漫设计和动画设计
  • 网站需要服务器吗?青岛设计优化公司
  • 网站建设需要什么东西网站再就业培训班