Redis在网络上的出列速度慢10倍



我在具有1Gbps LAN速度的网络上测试redis的入队和出队速率,并且两台机器都具有1Gbps以太网卡。Redis版本:3.2.11

lpush 1L项目,每个项目使用python客户端1个字节。使用rpop对项目进行排队需要在网络上花费大约55秒,即1800秒。而相同的操作在5秒内完成,我从本地排队,即大约20000秒。

入队率几乎接近出队率。

这是在没有太多使用的情况下使用办公网络完成的。生产环境也是如此!

网络上小于3倍的压降是可以接受的。大约10倍看起来我做错了什么。

如果我需要在服务器或客户端进行任何配置更改,请提出建议。

提前感谢。

如果有其他人发现这个问题,请回复。

往返延迟和并发可能是您的瓶颈。如果所有出列调用都是串行的,那么您就是在叠加网络延迟。如果有100万个延迟为2毫秒的呼叫,则至少会有200万毫秒的延迟开销,即33分钟)。也就是说,您的应用程序正在等待服务器接收有效负载,执行某些操作,并回复以确认操作成功。一些redis客户端还执行多个调用来对单个作业(pop&ack/del)进行入队/出队,这可能会使这个数字翻倍。

以下链接说明了不同库使用redis键的不同方法(ruby的resque与clojure的carmine,请注意在redis服务器上为单个消息执行多个redis命令)。这很可能是您所期望的10倍与3倍性能的原因。

https://kirshatrov.com/2018/07/20/redis-job-queue/

一个过于简单的例子,每个消息出队列有两个调用(延迟1ms,redis服务器操作耗时1ms):

|client                    | server
~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1ms | pop msg      >--(1ms)-->  receive pop request
2ms |                           [process request (1ms)]
3ms | receive msg  <--(1ms)--<  send msg to client
4ms | send del     >--(1ms)-->  receive del
5ms |                           [delete msg from queue (1ms)]
6ms | receive ack  <--(1ms)--<  reply with delete ack

提高出列时间通常需要使用支持多线程或多进程并发的客户端(即,10个并发工作者将显著减少完成的总时间)。这可以通过发送出列请求流来确保您的网络得到更好的利用,而不是等待一个请求完成后再获取下一个请求。

对于1字节与500字节,默认的TCP MTU是1500字节。减去TCP报头,有效载荷约为1460字节(如果使用GRE/IPsec进行隧道传输,则更少,如果使用巨型帧,则更多)。由于两种有效载荷大小都适合单个TCP数据包,因此它们将具有相似的性能特征。

1gbps以太网接口每秒可以传输81274到1488096个数据包(取决于有效负载大小)。

所以实际上,这是一个有多少过程的问题;线程可以在客户端上同时运行以保持网络&redis服务器正忙。

Redis通常是I/O绑定的,而不是CPU绑定的。它可能达到了网络带宽限制。考虑到消息的大小很小,大部分带宽可能会被TCP开销占用。

在本地机器上,您受到内存带宽的限制,这比1Gbps的网络带宽快得多。您可以通过增加一次获取的数据量来提高网络吞吐量。

最新更新