真正零停机 HAProxy 重载

Yelp 础设施团队的主要目标之一就是为了尽可能接近零停机时间。那也就是说当用户访问www.yelp.com作出动作的时候,网站的响应速度必须尽可能的快。一种方法是使用 HAProxy 负载均衡能够保持 www.yelp.com 网站的响应速度。通常我们在任何地方都使用 HAProxy 来保持网站的外部负载均衡、内部负载均衡,甚至运用到构建面向服务的架构中。我们发现在 Yelp 的每台机器上运行 HAProxy,均可作为 SmartStack 的一部分。 我们喜欢在发展 SOA 的时候使用 SmartStack 给我们带来的灵活性,但这种灵活性是有代价的。通常当服务或在服务后端执行增加或永久删除命令的的时候,整个基础设施不得不重新加载 HAProxy。这种重载方式会导致可靠性问题,因为 HAProxy 一旦运转起来就一直保持在工作状态且不会中断流量,但在重载的时候它会中断流量。 HAProxy 重载丢流量 HAProxy 的 1.5.11 版本不支持重启或重新加载配置时的零停机时间。相反,它支持快速重载——当一个新的 HAProxy 实例启动时,它尝试使用 SO_REUSEPORT 去绑定老 HAProxy 监听的相同端口并给老 HAProxy 实例发送信号去关闭。这种技术非常接近现代 Linux 内核的零停机时间,但这仍旧会经历一个短暂的时隙——当两个进程都绑定到端口时。在这个关键的时隙中,由于Linux内核自身(丢弃)处理多个接受进程的方式可能有流量会被丢掉。特别要提出来的,这个问题会潜在导致从 HAProxy 过来的新连接有一个 RST。这个问题是 SYN 包在老 HAProxy 被调用关闭前会被先放进其套接字队列中,这导致了这些连接的 RST。 这个问题有许多解决办法。例如,Willy Tarreau,HAProxy 的主要维护者,建议用户在重启 HAProxy 时丢掉 SYN 包,利用 TCP 的自动修复。不幸的是,RFC 6298 规定的初始 SYN 的超时时间是1s,Linux 内核坚守此规定。 因此,丢弃 SYN 意味着任何试图在 HAProxy 加载的 20-50ms 之间重建的连接将会遭受一个额外的秒级或更长的延迟。确切的时间依赖于客户端的 TCP 实现,而一些移动设备重试时间为 200ms,很多设备只在 3S 后重试。鉴于 HAProxy 重载的次数和和 Yelp 的流量,这成为了我们服务可靠性的一个障碍。 让HAProxy重载不丢包 为了避免延迟,我们采用了Willy提议的方案。他的方案实际上在不丢弃数据包上表现很好,但是额外的一秒延时是个问题。我们更好的解决方案是延迟SYN包直到重载已经完成,因为这样做只会对新的连接产生HAProxy重载所需要的延迟。 为了实现这种方案,我们求助于Linux队列原则(qdiscs)。Linux队列原则是用来管理Linux内核处理网络数据包的方式。具体地说就是你可以控制数据包是如何入队和出队,这提供了速率限制,优先或指定输出数据包的能力。有关更多qdiscs的详情, 我极力推荐lartc howto以及相关的man页面。 我们的一个SRE(网站可靠性工程师),Josh Snyder花了一些晚上的时间阅读了Linux内核源代码,发现了一个文档记录很少的工具:plug排队原则(qdisc),qdisc是从Linux 3.4以来就存在了。使用plug qdisc和以下标准Linux技术, 我们可以实现HAProxy重载零宕机:

  • tc:Linux流量控制。这使我们能够建立基于过滤器路由连接的排队规则。在最新的Linux版本上自带libnlutils,它提供了一些较新的qdiscs接口(如plug qdisc)。
  • iptables:用于包过滤和NAT(网络地址转换)的Linux工具。这个工具允许我们标识进入的SYN包。

SmartStack客户端连接到loopback接口向HAProxy请求,HAProxy幸好将进入的包变成为输出包。这意味着我们可以在loopback接口上建立如图1的队列原则。

Figure 1: Queueing Discipline 该设置的一个分类实现了使用 prio qdisc 队列规定的标准 pfifo_fast, 但只是使用了第四个“plug“通道。plug qdisc 并没有使他们退出队列,而是拥有队列数据包的性能。与一个 iptables 命令相结合的性能来允许我们在整个 HAProxy 重载期间重新定向,然后拔掉后重载的 SYN 插头的数据包。该控键(‘1:1’, ‘30:’等等)是允许我们一起连接 qdiscs,并且使用过滤器发送特定 qdiscs 的数据包。有关更多的信息,请查阅 lartc howto上面所引用的。 然后,我们把我们调用 qdisc_tool 的这个功能编进脚本。该工具允许我们的基础设施“保护”HAProxy 重载我们 plug 流量,重启haproxy,然后松开这个插头,交付延迟所有的 SYN 数据包。这个调用看起来像: qdisc_tool protect <normal HAProxy reload command> 由 GitHub 托管的 qdisc 命令 我们可以轻易地在诸如 Ubuntu Trusty 的 linux 发行版本上使用标准的用户空间实用工具来复制该技术。如果你的设置并没有 nl-qdisc-add,但有3.4+ Linux 内核,那么你可以通过 netlink 来手动地操纵该插头。

原文发布于微信公众号 - 马哥Linux运维(magedu-Linux)

原文发表时间:2015-04-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

计算机的启动过程(详细)

对于使用电脑用户来说,打开电源启动电脑几乎是每天必做的事情,但计算机在显示这些启动画面的时候都在做什么呢?大多数用户都未必清楚。 下面就向大家介绍一下从打开电源...

31950
来自专栏北京马哥教育

CentOS 7.0.1406 正式版发布

美国当地时间2014年7月7日 17:39:42,CentOS官方放出CentOS7.0.140 64位的版本下载地址,主要更新:内核更新至 3.10.0、支持...

36360
来自专栏云计算

将基于MicroProfile的应用程序部署到IBM Cloud Private

Eclipse MicroProfile是一个开源项目,用于优化Java企业版的微服务体系结构。基于MicroProfile的应用程序可以部署到K...

228100
来自专栏finleyMa

docker学习系列9 Docker的技术原理介绍

Docker就是虚拟化的一种轻量级替代技术。Docker的容器技术不依赖任何语言、框架或系统,可以将App变成一种 标准化的、可移植的、自管理的组件,并脱离服...

13820
来自专栏生信技能树

跟着jimmy学docker系列之第4讲:docker容器资源调度问题(MAC版本)

前面我们复习了docker的用法,而且我还带领大家亲自构建了一个自己的docker容器,也成功的在测试数据集里面运行了,但是前面我说的,我这次搞docker是因...

17720
来自专栏北京马哥教育

haproxy思维导图

今天给大家带来的思维导图之haproxy。 小伙伴们一起来学习吧! ? HAProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)...

33050
来自专栏IT大咖说

如何利用开源DevOps工具完成云上的自动运维

内容概况 云计算的特点是开箱即用,可以随时的扩缩容,不用考虑硬件的损坏问题,也有丰富的云服务和云平台供我们选择。在本次演讲中,黎山通过实际应用场景为我们讲述了基...

47170
来自专栏宝哥的专栏

Docker系列学习文章 - 镜像仓库的介绍(七)

| 导语 前面我们讲了镜像的制作,知道了镜像是怎么生成的。但是镜像制作好了后,要怎么管理?他们存在哪里。通过本篇文章的讲解,大家就清楚了。

2.4K180
来自专栏Debian社区

在 Debian Stretch 上安装 FFmpeg

FFmpeg 是一款流行的多媒体框架,可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化...

25840
来自专栏deed博客

安卓SDK镜像

27740

扫码关注云+社区

领取腾讯云代金券