Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix套接字连接到redis时比tcp慢_C_Sockets_Unix_Redis_Server - Fatal编程技术网

Unix套接字连接到redis时比tcp慢

Unix套接字连接到redis时比tcp慢,c,sockets,unix,redis,server,C,Sockets,Unix,Redis,Server,我正在开发高性能web服务器,该服务器应能同时处理约2k个连接和40k个QPS,响应时间小于7ms 它所做的是查询Redis服务器(在同一台主机上运行)并将响应返回给客户端。 在测试过程中,我观察到使用TCP流_套接字的实现比连接unix套接字的效果更好。对于约1500个连接,TCP保持约8毫秒,而unix套接字保持约50毫秒。 服务器是用C写的,它基于常量Posix线程池,我使用阻塞连接到Redis。我的操作系统是CentOS 6,使用Jmeter、wrk和ab进行测试。 对于与redis的连

我正在开发高性能web服务器,该服务器应能同时处理约2k个连接和40k个QPS,响应时间小于7ms

它所做的是查询Redis服务器(在同一台主机上运行)并将响应返回给客户端。 在测试过程中,我观察到使用TCP流_套接字的实现比连接unix套接字的效果更好。对于约1500个连接,TCP保持约8毫秒,而unix套接字保持约50毫秒。

服务器是用C写的,它基于常量Posix线程池,我使用阻塞连接到Redis。我的操作系统是CentOS 6,使用Jmeter、wrk和ab进行测试。 对于与redis的连接,我使用hiredis lib,它提供了两种连接redis的方法
据我所知,unix套接字至少应该和TCP一样快


有人知道是什么导致了这种行为吗。我卡住了。谢谢。

通过环回接口,Unix域套接字通常比TCP套接字更快。通常,Unix域套接字的平均延迟为2微秒,而TCP套接字的平均延迟为6微秒

如果我使用默认值(无管道)运行redis基准测试,我会看到每秒160k个请求,基本上是因为单线程redis服务器受到TCP套接字的限制,160k个请求以平均6微秒的响应时间运行

使用Unix域套接字时,重做每秒可实现320k的SET/GET请求

但有一个极限,事实上,我们在Torusware的产品已经达到了这个极限,这是一个平均延迟为200纳秒的高性能TCP套接字实现(在info@torusware.com用于请求极限性能版本)。在几乎零延迟的情况下,我们看到redis基准测试实现了每秒约500k的请求。因此,我们可以说,redis服务器平均每个请求的延迟约为2微秒

如果您希望尽快回答,并且您的负载低于redis服务器的峰值性能,那么避免管道可能是最好的选择。然而,如果您希望能够处理更高的吞吐量,那么您可以处理请求管道。响应可能需要更长的时间,但您将能够在某些硬件上处理更多的请求

因此,在前面的场景中,使用32个请求的管道(在通过套接字发送实际请求之前缓冲32个请求),您可以通过环回接口每秒处理多达100万个请求。在这种情况下,UDS的好处并不高,特别是因为处理这种流水线是性能瓶颈。事实上,管道为32的1M请求约为每秒31k个“实际”请求,我们已经看到redis服务器每秒能够处理160k个请求

Unix域套接字每秒分别处理约110万和170万个SET/GET请求。TCP环回每秒处理1M和1.5个SET/GET请求

通过管道传输,瓶颈从传输协议转移到管道处理

这与网站中提到的信息一致

然而,流水线大大增加了响应时间。因此,在没有管道的情况下,100%的操作通常在不到1毫秒的时间内运行。当管道32请求时,在高性能服务器中的最大响应时间为4毫秒,如果redis server在其他机器或虚拟机中运行,则最大响应时间为数十毫秒


因此,您必须权衡响应时间和最大吞吐量。

虽然这是一个老问题,但我想补充一点。其他答案是500k甚至170万个响应/秒。使用Redis可能可以实现这一点,但问题是:

客户端--#网络-->Webserver--#某物-->Redis

我假设Web服务器的功能类似于Redis的HTML代理

这意味着您的请求数量也受限于Web服务器可以实现的请求数量。 有一个经常被忘记的限制:如果您有一个100位的连接,那么每秒有100.000.000位可供您使用,但在1518位的包中是默认的(包括包后所需的空间)。这意味着:65k网络包。假设您的所有响应都较小,则由于CRC错误或包丢失,必须重新发送此类包和非包的数据部分

此外,如果不使用持久连接,则需要为每个连接执行TCP/IP握手。这会为每个请求添加3个包(2个接收,1个发送)。因此,在这种未经优化的情况下,您的Web服务器仍然有21k个可获得的请求。(或210k用于“完美”千兆连接)-如果您的响应适合一个175字节的数据包

因此:

  • 持久连接只需要一点内存,所以启用它。它可以使你的表现翻两番。(最佳案例)
  • 如果需要,可以使用gzip/deflate来减少响应大小,以便尽可能少地装入数据包。(每个数据包丢失都是一个可能的响应丢失)
  • 通过剥离不需要的“垃圾”(如调试数据或长xml标记)来减少响应大小
  • HTTPS连接将增加巨大的(与此相比)开销
  • 添加网卡并将其中继
  • 如果响应总是小于175字节,请为此服务使用DeDistricted网卡,并减小网络帧大小以增加每秒发送的包数
  • 不要让服务器做其他事情(比如服务普通网页)

您能否使用redis benchmark在应用程序之外复制这种较慢的速度?根据unix域套接字相对于TCP/IP的性能优势,当大量使用管道时(即长管道),环回往往会减少。您是否设置了延迟?我看到这在某些情况下很有帮助。谢谢大家的回答@TimCooper redis bench在redis unix套接字上运行良好,因此需要与我的应用程序相关。@geert3不幸