摘要:为了解决负载分布不均匀导致的高延迟问题,SaaS Web 搜索产品 Algolia 将其 基础设施 的 DNS 轮询负载均衡模型 换掉 了。他们引入了 NGINX 和 OpenResty 作为软件负载均衡器,Redis 使用自定义的 Go 程序来管理后端服务器列表。

为了解决负载分布不均匀导致的高延迟问题,SaaS Web 搜索产品 Algolia 将其 基础设施 的 DNS 轮询负载均衡模型 换掉 了。他们引入了 NGINX 和 OpenResty 作为软件负载均衡器,Redis 使用自定义的 Go 程序来管理后端服务器列表。这个解决方案在 Algolia 的基础设施之上提供了一个新的抽象层。InfoQ 联系了 Algolia 站点可靠性工程师 Paul Berthaux ,了解更多关于这个做法的信息。

Algolia“应用”有 3 个服务器集群和分布式搜索网络(DSN)服务器,后者提供搜索查询服务。DSN 在功能上类似于内容交付网络接入点(POP),因为它们从离用户最近的地方提供数据。每个应用都有一个 DNS 记录。Algolia 的 DNS 配置 使用 了多个顶级域名(TLD),并且为了获得弹性使用了两个 DNS 提供商。此外,每个应用的 DNS 记录都被配置为以 轮询方式 返回 3 个集群服务器的 IP 地址。这是试图将负载分布到集群中的所有服务器上。搜索集群的常见用例是通过前端应用程序或移动应用程序。然而,一些客户也有访问搜索 API 的后端应用程序。后一种情况会造成负载不均,因为所有请求都将到达同一服务器,直到特定服务器的 DNS 生存时间(TTL)到期为止。

Algolia 的一个应用在黑色星期五(Black Friday)搜索量很大时,搜索速度变得很慢。这导致了查询的不均匀分布。团队瞄准了 NGINX 作为客户端应用程序和应用服务器之间的软件负载均衡器。虽然这确实解决了负载分配的一般问题,但是仍然存在使该设置具有通用性和自动化操作的问题。团队选择了 OpenResty ,它为 NGINX 中的请求 - 响应生命周期提供 Lua 脚本支持。使用这个模型,NGINX 可以根据客户“了解到”将请求发送到哪个后端服务器。此信息缓存在 Redis 中。一个名为 lb-helper 的自定义 Go 守护进程从内部 API 获取服务器列表。

在回答是否可以使 Redis 缓存失效的问题时,Berthaux 解释说,他们这样做是“使用了内部公开的用于维护目的的 lib -helper 中的 API 端点”。如果团队必须删除大量的后端服务器,并且不希望 LB 客户端在响应时间上有任何差异,那么就可能需要这样做。

图片来自: https://blog.algolia.com/one-year-load-balancing/,已获授权。

通过此更改,负载均衡器可能成为单点故障。Berthaux 解释了为什么现在还不用担心:

为了获得弹性,我们运行着多个 LB——LB 的选择是通过轮询 DNS。目前,这没有问题,因为与我们的搜索 API 服务器相比,LB 执行非常简单的任务,所以我们不需要在它们之间进行均匀的负载均衡。也就是说,我们有一些非常长期的计划,从轮询 DNS 转移到基于 Anycast 路由的东西。

lb-helper 还负责从列表中删除不健康的服务器。按照 Berthaux 的说法:

NGINX/OpenResty 中嵌入了对上游故障的检测以及针对不同上游流的重试功能。我使用 OpenResty 中的 log_by_lua 指令和一些自定义的 Lua 代码进行失败计数,从活动 Redis 条目中删除失败的上游,并在连续 10 次失败后向 lib -helper 发出警告。我设置了这个故障阈值,以避免短时自解“事件(incident)”(如准时丢包)中很多不必要的事件(event)。这样,lb-helper 将探测失败的上游 FQDN,并在它恢复后将其放回 Redis 中。

通过此更改,Algolia 的搜索负载趋于平稳。他们目前正在进一步改进负载均衡算法。

查看英文原文: Load Balancing Search Traffic at Algolia With NGINX and OpenResty

相关文章