shy*_*ent 4 high-availability load-balancing udp lvs keepalived
我需要在多个“真实服务器”之间对 UDP 流量进行负载平衡,并以真正的循环方式进行。我已经开始使用 keepalived,但意外地发现,LVS 将 UDP 流量视为“连接”(无论 UDP 是什么......)。实际上,这意味着来自特定客户端的所有流量始终都流向同一个“真实服务器”(这是一个大问题,因为某些客户端可能会产生如此大的流量,以至于单个后端将不堪重负) .
显然,这是预期的行为,但是最近的 LVS 版本有一个“--ops”标志,这使 LVS 绕过其上述行为,以便独立处理每个 UDP 数据报(这就是我想要的!)。但是(总是有一个但是……)这个功能没有从 keepalived.conf 中暴露出来。
有什么解决方案可以让我
显然应该是基于 Linux 的。任何形式的 DNS 轮询在这里都不起作用,因为客户端不知道 DNS。
PS我将尝试脉冲/食人鱼,但从阅读我收集的文档来看,它也没有公开“--ops”标志。我还将尝试mon(通过直接调用 ipvsadm使mon检查后端并添加/删除真实服务器)。
满足要求如下:
我已经安装了更新版本的 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)
这有效,但我在此设置中遇到了许多问题(有点):
quorum_up
执行之间有很小的时间间隔(不到一秒,更像是 1/10)。在此期间设法通过控制器的任何数据报都将在 ipvsadm 中创建一个连接条目,即使--ops
添加了标志,来自该源主机/端口的进一步数据报也将停留在同一个 realserver 上。您可以确保虚拟服务在创建后永远不会被删除,从而最大限度地减少发生这种情况的机会。你通过指定来做到这一点inhibit_on_failure
在您的 realserver 定义中设置标志,以便在相应的 realserver 关闭时它们不会被删除(当所有 realserver 都被删除时,虚拟服务也被删除),而是将它们的权重设置为零(然后它们停止接收流量)。因此,数据报唯一可以忽略的时间是在 keepalived 启动期间(假设您当时至少有一台真实服务器,因此将立即获得仲裁)。--ops
处于活动状态时,director 不会重写 realserver 发送给客户端的数据报的源主机/端口,因此源主机/端口是发送此特定数据报的 realserver 的主机/端口。这可能是一个问题(这是为我的客户准备的)。您可以通过SNAT
使用 iptables来修改这些数据报。--ops
。据推测,问题在于数据包调度算法是在每个数据报上触发的,而不仅仅是“连接”中的第一个数据报(如果这甚至适用于 UDP..)。我实际上还没有找到“解决”这个问题的方法,但也许我还没有足够努力。系统有一些特定的负载要求,在该负载下,处理器使用率不会达到最大值;也没有任何丢失的数据报,所以这个问题不被认为是一个阻碍。尽管如此,它仍然相当令人担忧。总结:设置肯定有效(也在负载下),但必须跳过箍和我遇到的问题(尤其是?3..也许有人知道解决方案?),这意味着,给定时间,我会的我使用了一个用户空间程序(可能是用 C 编写的)来监听 UDP 套接字并在 realservers 之间分发接收到的数据报,结合一些可以检查 realservers 健康状况的东西,SNAT
在 iptables 中重写源主机/端口和HA 在 VRRP 模式下保活。