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

rea*_*iek 8 c unix sockets redis server

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

它的作用是查询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一样快.

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

Gui*_*pez 20

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

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

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

但是有一个限制,事实上我们在Torusware上已经达到了我们的产品Speedus,这是一种高性能的TCP套接字实现,平均延迟为200纳秒(请发送电子邮件至info@torusware.com申请Extreme Performance版本).由于延迟几乎为零,我们看到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在不同的计算机或虚拟机中运行,则最长响应时间为数毫秒.

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

  • 奇怪的是,没有人对这个漫长而美好的答案发表评论.感谢您分享您的体验! (4认同)