UDP数据包循环负载均衡

我需要在许多“真实服务器”之间对UDPstream量进行负载平衡,并以真正的循环方式进行。 我已经开始keepalived,但意外地发现,LVS把UDPstream量视为“连接”(无论是在UDP ..)。 实际上,这意味着所有来自特定客户端的stream量都会一直到达同一个“真实服务器”(这是一个大问题,因为有些客户端可能会产生如此大的stream量,单个后端将不堪重负) 。

显然,这是预期的行为, 但是最近的LVS版本有一个“–ops”标志,这使得LVS绕过了上述的行为,使得每个UDP数据报都被独立处理(这就是我想要的!)。 但是(总是有一个但是..)这个function没有暴露在keepalived.conf。

有没有解决scheme,这将让我

  • 在UDP后端之间进行循环分配
  • 检测“死”的后端,并将它们从循环中删除(当它们变成“活着”时将它们加回来也是有用的)

应该是基于Linux的,显然。 任何forms的DNS循环都不会在这里真正起作用,因为客户端不能识别DNS。

PS我会尝试脉冲/食人鱼,但从阅读我收集的文件,它并不暴露“ – ”标志以及。 我也打算试一试(通过直接调用ipvsadm来使后端检测和添加/删除realserver)。

要求满足如下:

我已经安装了更新版本的ipvsadm(及其内核模块),它支持--ops标志(1.26)。 由于keepalived不在configuration文件中公开这个标志,所以你必须手动应用它。 幸运的是, 创build“虚拟服务” 之后 ,可以这样做(就纯ipvsadm而言,可以先ipvsam -A虚拟服务不带--ops ,然后ipvsadm -E它添加一个数据包调度)。

由于keepalived为您创build了虚拟服务,您只需在创build虚拟服务器之后对其进行编辑,在虚拟服务器(基本上,有足够数量的正在运行的服务器)达到法定数量时会发生这种情况。 以下是它在keepalived.conf文件中的外观:

 virtual_server <VIP> <VPORT> { lb_algo rr lb_kind NAT protocol UDP ... # Enable one-packet scheduling when quorum is gained quorum_up "ipvsadm -E -u <VIP>:<VPORT> --ops -s rr" ... realserver definitions, etc ... } 

这个工作,但我遇到了一些问题(种)与此设置:

  1. 在仲裁quorum_upquorum_up的脚本得到执行之间,时间间隔很小(小于1秒,更像1/10)。 任何在那段时间内通过导向器的数据报都将在ipvsadm中创build一个连接入口,并且即使在添加了--ops标志之后,来自该源主机/端口的进一步的数据报将被卡在相同的realserver上。 通过确保虚拟服务一旦创build就不会被删除,可以最大限度地减less这种情况的发生。 您可以通过在realserver定义中指定inhibit_on_failure标志来inhibit_on_failure ,以便在相应的realserverclosures时(所有realserver被删除时,虚拟服务也被删除),它们不会被删除,而是它们的权重被设置为零(它们停止接收交通)。 因此,在keepalived启动过程中,唯一的时间数据报可以通过(假设您至less有一个realserver启动,以便立即获得仲裁)。
  2. --ops处于活动状态时,director不重写数据报的源主机/端口,realserver发送给客户机,所以源主机/端口是那些发送这个特定数据报的realserver。 这可能是一个问题(这是我的客户)。 你可以通过SNAT用iptables修改这些数据报。
  3. 当导演处于负载状态时,我注意到了显着的系统 CPU负载。 原来,CPU被ksoftirqd占用。 如果closures--ops ,则不会发生。 据推测,问题在于数据包调度algorithm在每个数据报上被触发,而不是在“连接”中的第一个数据报(如果甚至适用于UDP ..)。 实际上我没有find“修复”的方法,但也许我没有努力。 系统有一些特定的负载要求,在这个负载下处理器的使用率不会达到最大值,也没有任何丢失的数据报,所以这个问题不被认为是一个阻碍。 尽pipe如此,这还是相当惊人的。

总结:安装程序绝对有效(也是在加载的情况下),但是我必须跳过的问题以及我遇到的问题(特别是№3..也许有人知道解决scheme?)意思是说,已经使用了一个用户空间程序(用C语言写的)来监听一个UDP套接字,并在真实服务器之间分配接收到的数据报,这将检查真实服务器的健康状况,在iptables中的SNAT重写源主机/端口并保持HA的VRRP模式。

必须有多path路由这样做….

负载均衡器和realserver共享一个子网(10.0.0 / 24)中的IP。 对于这两个真实服务器,您都可以从另一个子网添加相同的IP,作为回送接口(172.16.1.1/32)的辅助节点。 在这个地址,你的服务将听取。

  +-------------------------------------+ +----|A: eth0:10.0.0.2/24 lo:172.16.1.1/32 | +--------------------+ | +-------------------------------------+ |LB eth0:10.0.0.1/24 |---| +--------------------+ | +-------------------------------------+ +----|B: eth0:10.0.0.3/24 lo:172.16.1.1/32 | +-------------------------------------+ 

然后你可以使用:

  ip route add 172.16.1.1/32 nexthop via 10.0.0.2 nexthop via 10.0.0.3 

但是到目前为止,还是有一个好消息:显然最近的linux内核会caching这些路由,这样来自同一个源的数据包仍然会在同一个目的地。 有一些补丁可以禁用这种行为,但是它们似乎都适用于较老的内核(例如2.4内核的多path均衡补丁,2.6中的mpath)。 也许一个更彻底的search可能会find一个最近的内核工作补丁。

通过为10.0.0.2和10.0.0.3运行CARP,您可以轻松实现故障转移。 所以当A发生故障时,B接pipe了10.0.0.2。