AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 503211
Accepted
shylent
shylent
Asked: 2013-04-28 11:00:36 +0800 CST2013-04-28 11:00:36 +0800 CST 2013-04-28 11:00:36 +0800 CST

UDP 的每数据包循环负载平衡

  • 772

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

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

有什么解决办法吗?

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

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

PS 我打算尝试 pulse/piranha,但通过阅读我收集的文档,它也不会公开“--ops”标志。我也打算给mon一个尝试(让mon检查后端并通过直接调用 ipvsadm 添加/删除 realservers)。

load-balancing
  • 2 2 个回答
  • 6925 Views

2 个回答

  • Voted
  1. Best Answer
    shylent
    2013-05-25T02:12:01+08:002013-05-25T02:12:01+08:00

    要求满足如下:

    我已经安装了更新版本的 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 ...
    }
    

    这行得通,但是我在这个设置中遇到了很多问题(有点):

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

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

    • 5
  2. Zabuzzman
    2013-04-29T12:31:18+08:002013-04-29T12:31:18+08:00

    必须有一种方法可以通过多路径路由来做到这一点……

    负载均衡器和 realserver 在子网 (10.0.0/24) 中共享 IP。对于两个真实服务器,您从另一个子网添加相同的 IP 作为环回接口 (172.16.1.1/32) 的辅助 IP。您的服务将在此地址上侦听。

                                  +-------------------------------------+
                             +----|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 内核将缓存路由,以便来自同一源的数据包仍将最终到达同一目的地。有一些补丁可以禁用这种行为,但它们似乎都是针对旧内核的(例如 2.4 内核的多路径均衡补丁,2.6 中的 mpath)。也许更彻底的搜索可能会为您找到最新内核的工作补丁。

    您可以通过为 10.0.0.2 和 10.0.0.3 运行 CARP 轻松实现故障转移。这样,当 A 出现故障时,B 接管 10.0.0.2。

    • 1

相关问题

  • 网络负载平衡服务器无法相互通信

  • 用于网络监控的路由/代理 SNMP 陷阱(或 Netflow、通用 UDP 等)的解决方案?

  • 防止拒绝服务攻击的最佳技术是什么?

  • 添加备份互联网连接需要哪些硬件?

  • 什么是最有效的 Windows 负载平衡解决方案?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve