由于高流量和我们应用程序保持连接的性质,我们的 haproxy 进程消耗大量 RAM(通常为可用 RAM 的 30-40%)。现在,当我们想要添加/删除任何后端时,我们必须重新加载 haproxy。在优雅重新加载期间(通过 ubuntu 的默认初始化重新加载),将创建一个新的 haproxy 进程,该进程将为新连接提供服务,并且现有进程保留在那里,直到旧连接被应用程序关闭或由于超时等原因被清理。这种行为很好。
但是这两个进程几乎都占用了所有可用的 RAM,事实上,如果第一个进程已经消耗了超过 50% 的 RAM,那么任何重新加载都可能导致中断(还没有经历过,但增加的流量会很快发生) . 这迫使我们要么强制终止旧进程(丢失旧连接),要么必须始终保持足够(> 50%)可用的 RAM(浪费资源)。
在这种情况下,我将不胜感激任何帮助/指针。我们在 Ubuntu 12.04 和 haproxy 1.4.18 上。
这是一个众所周知的问题。这就是我们支持 DLMALLOC 的原因。只需下载它,使用它重建 haproxy,问题就会消失。这就是我们在设备 (ALOHA) 中使用的确切原因。Dlmalloc 使用 mmap() 分配内存并支持其地址空间中的空洞,因此每次调用 free() 导致至少一个页面被释放将有效地导致该页面被释放。标准 malloc 几乎不支持这一点(它倾向于仅在释放大的连续区域时才支持它),因此它仅在该点之后的所有页面也被释放时才释放内存。这是一个很大的区别。