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

时间:2014-11-14 16:48:26

标签: c sockets unix redis server

我正在开发高性能Web服务器,它应该能够处理大约2k的同时连接和40k QPS,从而实现resp时间< 7毫秒。

它的作用是查询Redis服务器(在同一主机上运行)并将响应返回给客户端。 在测试期间,我观察到使用TCP STREAM_SOCKETs的实现比连接unix套接字更好。有大约1500个连接,TCP保持大约8ms,而unix插座大约为50.

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

有人知道可能导致这种行为的原因是什么吗? 。我被卡住了。感谢。

2 个答案:

答案 0 :(得分:19)

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

如果我使用默认值(没有管道)运行redis-benchmark,我会看到每秒160k的请求,主要是因为单线程redis服务器受TCP套接字限制,160k请求以6微秒的平均响应时间运行。

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

但是有一个限制,实际上我们在Torusware上已经使用我们的产品Speedus,这是一个高性能的TCP套接字实现,平均延迟为200纳秒(在info @ torusware上ping我们。 com请求极限性能版本)。由于延迟几乎为零,我们看到redis-benchmark每秒可实现约500,000个请求。所以我们可以说redis-server延迟平均每个请求大约2微秒。

如果您想尽快回答并且您的负载低于redis-server峰值性能,那么避免流水线操作可能是最佳选择。但是,如果您希望能够处理更高的吞吐量,那么您可以处理请求的管道。响应可能需要更长时间,但您可以在某些硬件上处理更多请求。

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

Unix Domain Sockets分别处理大约每秒1.1M和1.7M的SET / GET请求。 TCP环回每秒处理1M和1.5个SET / GET请求。

通过流水线操作,瓶颈从传输协议转移到管道处理。

这与redis-benchmark网站中提到的信息一致。

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

所以你必须权衡响应时间和最大吞吐量。

答案 1 :(得分:1)

虽然这是一个老问题,但我想补充一下。其他答案谈论500k甚至1.7M响应/秒。这可以通过Redis实现,但问题是:

客户 - #Network# - >网络服务器 - #Something# - > Redis

Web服务器的功能类似于Redis的HTML代理我认为。

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

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

所以:

  • 持久连接只需要一点内存,因此请启用它。它可以使您的表现翻两番。 (最好的情况)
  • 如果需要,可以使用gzip / deflate缩小响应大小,以便尽可能少地使用数据包。 (丢失的每个数据包都可能丢失响应)
  • 通过剥离调试数据或长xml标记等不需要的“垃圾”来减少响应大小。
  • HTTPS连接将增加巨大的(在此处进行比较)开销
  • 添加网卡并将其中继
  • 如果响应总是小于175字节,请使用专用网卡进行此项服务,并减小网络帧大小以增加每秒发送的包。
  • 不要让服务器做其他事情(比如提供正常的网页)
  • ...