HAProxy
在执行负载平衡时如何避免请求时间开销?
我测试了HAProxy
,并将其与用Twisted
(Python
)编写的简单端口转发器进行了比较。在我的初步测试中,与将HTTP request
直接发送到后端服务器相比,通过HAProxy
负载均衡器创建overhead[1]
会在请求时添加HTTP request
。而我自己的python脚本在响应时间中添加了~3x overhead
。
现在我的脚本是用Python
和HAProxy
C
编写的,所以先验,HAProxy
具有避免调用开销的优势(来自{{} 1 {}代码Python
),syscalls
代码经历。但这可以解释性能上的巨大差异,还是Python
利用一些操作系统技巧来进一步改善性能?我尝试对我的HAProxy
代码进行分析,但它没有在Python
代码中显示任何热点,因此我的猜测是它大部分时间都在Python
中没有考虑到在剖析中。
[1]:由ab报告,有100个并发连接和10,000个总请求。 syscalls
的平均时间为37毫秒,而HAProxy
脚本的平均时间为128毫秒。
设置是一个Python
负载均衡器,带有两个后端TCP
服务器,只提供静态文本。我故意想测试TCP负载平衡,然后测试协议变成nodejs
。这三台机器都是HTTP
的虚拟主机,单线程,512MB Ram,1核心。
The Python script can be seen here和我的haproxy.cfg can be found here
答案 0 :(得分:11)
原来HAProxy
网站已经覆盖了这个区域(我忽略了它的错误)。答案基本上是很多低级优化。直接从HAProxy网站复制:
HAProxy涉及操作系统体系结构中常见的几种技术,以实现绝对最大性能:
单进程,事件驱动模型大大降低了上下文切换和内存使用的成本。可以在一毫秒内处理数百个任务,并且每个会话的内存使用量大约为几千字节,而Apache
中消耗的内存 - 类似于每个进程的兆字节数量。
O(1)
事件检查器允许它(Linux
和FreeBSD
)允许在成千上万的任何连接上即时检测任何事件。
单缓冲,尽可能在读取和写入之间不进行任何数据复制。这节省了大量CPU
周期和有用的内存带宽。通常,瓶颈将是I/O
和网络接口之间的CPU
总线。在10 Gbps
时,内存带宽也可能成为瓶颈。
使用splice()
下的Linux
系统调用可以进行零拷贝转发,从而导致从Linux
3.5开始的实际零拷贝。这允许小于3瓦的设备(例如Seagate Dockstar
)在HTTP
转发gigabit/s
流量。
MRU
内存分配器使用固定大小的内存池进行直接内存分配,有利于热缓存区域而不是冷缓存区域。这大大减少了创建新会话所需的时间。
工作因子,例如一次多个accept()
,并且能够在多进程模式下运行时限制每次迭代accept()
的数量,从而使负载均匀分布进程之间。
基于树的存储,大量使用我已经开发了几年的Elastic Binary
树。这用于保持定时器的顺序,以保持命令的运行队列,管理循环和最少连接队列,只需O(log(N))
费用。
优化HTTP
标头分析:解析标头,动态解释,并优化解析以避免重新读取任何先前读取的内存区域。当使用不完整的头到达缓冲区的末尾时使用检查点,这样当读取更多数据时,解析不会从头开始。解析平均HTTP
请求通常需要Pentium-M 1.7 GHz
上的2微秒。
小心减少昂贵的系统调用次数。大多数工作默认在用户空间中完成,例如时间读取,缓冲区聚合,文件描述符启用/禁用。