UDP 的每包循环负载平衡

shy*_*ent 4 high-availability load-balancing udp lvs keepalived

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

显然,这是预期的行为,但是最近的 LVS 版本有一个“--ops”标志,这使 LVS 绕过其上述行为,以便独立处理每个 UDP 数据报(这就是我想要的!)。但是(总是有一个但是……)这个功能没有从 keepalived.conf 中暴露出来。

有什么解决方案可以让我

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

显然应该是基于 Linux 的。任何形式的 DNS 轮询在这里都不起作用,因为客户端不知道 DNS。

PS我将尝试脉冲/食人鱼,但从阅读我收集的文档来看,它也没有公开“--ops”标志。我还将尝试mon(通过直接调用 ipvsadm使mon检查后端并添加/删除真实服务器)。

shy*_*ent 5

满足要求如下:

我已经安装了更新版本的 ipvsadm(及其内核模块),该版本支持该--ops标志 (1.26)。由于 keepalived 不会在其配置文件中公开此标志,因此您必须手动应用它。幸运的是,您可以创建“虚拟服务”执行此操作(就普通 ipvsadm 而言,您可以先创建ipvsam -A一个没有 的虚拟服务--ops,然后再ipvsadm -E添加一个数据包调度)。

由于 keepalived 为您创建了虚拟服务,您只需在创建后对其进行编辑,这会在此虚拟服务器获得法定人数时发生(基本上,有足够数量的工作真实服务器)。这是它在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 ...
}
Run Code Online (Sandbox Code Playgroud)

这有效,但我在此设置中遇到了许多问题(有点):

  1. 在法定人数上升和脚本quorum_up执行之间有很小的时间间隔(不到一秒,更像是 1/10)。在此期间设法通过控制器的任何数据报都将在 ipvsadm 中创建一个连接条目,即使--ops添加了标志,来自该源主机/端口的进一步数据报也将停留在同一个 realserver 上。您可以确保虚拟服务在创建后永远不会被删除,从而最大限度地减少发生这种情况的机会。你通过指定来做到这一点inhibit_on_failure在您的 realserver 定义中设置标志,以便在相应的 realserver 关闭时它们不会被删除(当所有 realserver 都被删除时,虚拟服务也被删除),而是将它们的权重设置为零(然后它们停止接收流量)。因此,数据报唯一可以忽略的时间是在 keepalived 启动期间(假设您当时至少有一台真实服务器,因此将立即获得仲裁)。
  2. --ops处于活动状态时,director 不会重写 realserver 发送给客户端的数据报的源主机/端口,因此源主机/端口是发送此特定数据报的 realserver 的主机/端口。这可能是一个问题(这是为我的客户准备的)。您可以通过SNAT使用 iptables来修改这些数据报。
  3. 我注意到当控制器负载时系统CPU 负载很大。事实证明,CPU 被 ksoftirqd 占用了。如果您关闭,则不会发生这种情况--ops。据推测,问题在于数据包调度算法是在每个数据报上触发的,而不仅仅是“连接”中的第一个数据报(如果这甚至适用于 UDP..)。我实际上还没有找到“解决”这个问题的方法,但也许我还没有足够努力。系统有一些特定的负载要求,在该负载下,处理器使用率不会达到最大值;也没有任何丢失的数据报,所以这个问题不被认为是一个阻碍。尽管如此,它仍然相当令人担忧。

总结:设置肯定有效(也在负载下),但必须跳过箍和我遇到的问题(尤其是?3..也许有人知道解决方案?),这意味着,给定时间,我会的我使用了一个用户空间程序(可能是用 C 编写的)来监听 UDP 套接字并在 realservers 之间分发接收到的数据报,结合一些可以检查 realservers 健康状况的东西,SNAT在 iptables 中重写源主机/端口和HA 在 VRRP 模式下保活。