Algolia藉助NGINX和OpenResty實現搜索流量負載均衡

爲了解決負載分佈不均勻導致的高延遲問題,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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章