Badoo 如何實現每秒渲染 200 萬張照片的能力

Badoo 如何實現每秒渲染 200 萬張照片的能力

如果沒有媒體內容,現代網路幾乎是不可想像的:幾乎每個祖母都有智慧型手機,每個人都在社群網路上,維護停機對公司來說代價高昂。 這是公司故事的文字記錄 Badoo上 講述了她如何使用硬體解決方案組織照片的交付,過程中遇到了哪些性能問題,是什麼原因導致的,以及如何使用基於 Nginx 的軟體解決方案解決這些問題,同時保證各個級別的容錯能力(視頻)。 我們感謝奧列格故事的作者 桑尼斯 Efimova 和 Alexandra Dymova 在會議上分享了她們的經驗 第 4 天正常運作時間.

— 讓我們先簡單介紹一下如何儲存和快取照片。 我們有一個層用於儲存它們,還有一個層用於快取照片。 同時,如果我們想要實現高欺騙率並減少儲存負載,那麼單一用戶的每張照片都位於快取伺服器上對我們來說很重要。 否則,我們將不得不安裝與伺服器數量一樣多的磁碟。 我們的技巧率約為 99%,也就是說,我們正在將儲存上的負載減少 100 倍,為了做到這一點,10 年前,當這一切正在建置時,我們有 50 台伺服器。 因此,為了提供這些照片,我們基本上需要這些伺服器提供 50 個外部網域。

自然地,問題立刻出現了:如果我們的一台伺服器發生故障並且變得不可用,我們會損失哪一部分流量? 我們查看了市場上的產品,並決定購買一個硬件,這樣它就能解決我們所有的問題。 選擇落在了 F5 網路公司(順便說一下,最近收購了 NGINX, Inc)的解決方案:BIG-IP 本機流量管理器。

Badoo 如何實現每秒渲染 200 萬張照片的能力

這個硬體 (LTM) 的作用是:它是一個鐵路由器,可實現其外部連接埠的鐵冗餘,並允許您根據網路拓撲、某些設定來路由流量,並進行運行狀況檢查。 對我們來說重要的是這個硬體可以編程。 因此,我們可以描述如何從特定快取提供特定用戶的照片的邏輯。 它是什麼樣子的? 有一個硬體在一個網域、一個IP上查看互聯網,進行ssl卸載,解析http請求,從IRule中選擇一個快取號,去哪裡,然後讓流量去那裡。 同時,它會進行健康檢查,如果某些機器不可用,當時我們會這樣做,以便流量流向一台備份伺服器。 從配置的角度來看,當然有一些細微差別,但總的來說,一切都很簡單:我們註冊一張卡,將某個號碼與網路上的 IP 對應,我們說我們將在連接埠 80 上監聽443,我們說如果伺服器不可用,那麼你需要將流量傳送到備份伺服器,在本例中是第35 個伺服器,我們描述了一堆關於如何拆解該架構的邏輯。 唯一的問題是硬體程式語言是 Tcl。 如果有人還記得這一點…這種語言比方便程式設計的語言更只寫:

Badoo 如何實現每秒渲染 200 萬張照片的能力

我們得到了什麼? 我們收到的硬體可以確保基礎設施的高可用性、路由所有流量、提供健康益處並且正常運作。 而且,它的工作時間相當長:在過去的10年裡,沒有任何關於它的投訴。 到 2018 年初,我們已經每秒鐘發送約 80 萬張照片。 我們兩個資料中心的流量約為 80 GB。

然而…

2018年初,我們在排行榜上看到了一幅醜陋的畫面:發送照片所花費的時間明顯增加。 它不再適合我們了。 問題是,這種行為僅在流量高峰期間可見 - 對於我們公司來說,這是周日到週一的晚上。 但其餘時間系統表現如常,沒有故障的跡象。

Badoo 如何實現每秒渲染 200 萬張照片的能力

儘管如此,問題還是必須解決。 我們發現了可能的瓶頸並開始消除它們。 首先當然是擴展了外部上行鏈路,對內部上行鏈路進行了全面的審計,發現了所有可能的瓶頸。 但這一切並沒有給出明顯的結果,問題並沒有消失。

另一個可能的瓶頸是照片快取本身的效能。 我們認為問題可能出在他們身上。 好吧,我們擴展了性能 - 主要是照片快取上的網路連接埠。 但同樣沒有看到明顯的改善。 最後,我們密切關注了 LTM 本身的效能,在這裡我們在圖表上看到了一幅悲傷的畫面:所有 CPU 上的負載開始平穩,但隨後突然陷入平穩狀態。 同時,LTM 停止對運​​行狀況檢查和上行鏈路做出充分響應,並開始隨機關閉它們,這會導致效能嚴重下降。

也就是說,我們找到了問題的根源,找到了瓶頸。 我們將做什麼仍有待決定。

Badoo 如何實現每秒渲染 200 萬張照片的能力

我們能做的第一件最明顯的事情就是以某種方式對 LTM 本身進行現代化改造。 但這裡有一些細微差別,因為這個硬體非常獨特,你不會去最近的超市買它。 這是一份單獨的合同,一份單獨的許可合同,需要花費很多時間。 第二個選擇是開始自己思考,使用自己的元件提出自己的解決方案,最好使用開放存取程式。 剩下的就是決定我們到底要選擇什麼以及我們要花多少時間來解決這個問題,因為用戶沒有收到足夠的照片。 因此,我們需要非常非常快地完成這一切,就像昨天有人可能會說的那樣。

由於任務聽起來像是“盡快做某事並使用我們擁有的硬體”,我們想到的第一件事就是簡單地從前面移除一些不是很強大的機器,將Nginx 放在那裡,我們知道如何使用它工作並嘗試實現與硬體過去所做的所有相同的邏輯。 也就是說,事實上,我們留下了我們的硬件,安裝了另外4 台我們必須配置的伺服器,為它們創建了外部域,類似於10 年前......如果這些機器崩潰,我們會損失一點可用性,但是更重要的是,他們在本地解決了我們用戶的問題。

因此,邏輯保持不變:我們安裝 Nginx,它可以進行 SSL 卸載,我們可以以某種方式對路由邏輯、配置中的運行狀況檢查進行編程,並簡單地複製我們先前的邏輯。

讓我們坐下來寫配置。 起初,一切似乎都很簡單,但不幸的是,很難找到每項任務的手冊。 因此,我們不建議簡單地搜尋「如何為照片配置 Nginx」:最好參考官方文檔,其中會顯示應該觸及哪些設定。 但具體參數最好自己選擇。 好吧,那麼一切都很簡單:我們描述我們擁有的伺服器,我們描述憑證......但事實上,最有趣的是路由邏輯本身。

起初,在我們看來,我們只是簡單地描述我們的位置,匹配其中照片緩存的數量,使用我們的手或生成器來描述我們需要多少個上游,在每個上游中,我們指示流量應該發送到的伺服器去,還有一個備份伺服器 - 如果主伺服器不可用:

Badoo 如何實現每秒渲染 200 萬張照片的能力

但是,如果一切都這麼簡單,我們可能會什麼也不說就回家了。 不幸的是,預設的 Nginx 設定通常是經過多年的開發而製定的,並不完全適合這種情況...配置如下:如果某些上游伺服器有請求錯誤或超時,Nginx 總是將流量切換到下一個。 此外,在第一次失敗後,伺服器也會在 10 秒內因錯誤和逾時而關閉 - 這甚至無法以任何方式進行配置。 也就是說,如果我們刪除或重置upstream指令中的逾時選項,那麼,儘管Nginx不會處理這個請求並且會回應一些不太好的錯誤,但伺服器將會關閉。

Badoo 如何實現每秒渲染 200 萬張照片的能力

為了避免這種情況,我們做了兩件事:

a) 他們禁止 Nginx 手動執行此操作 - 不幸的是,執行此操作的唯一方法是簡單地設定最大失敗設定。

b) 我們記得,在其他項目中,我們使用了一個允許我們進行後台運行狀況檢查的模組 - 因此,我們進行了相當頻繁的運行狀況檢查,以便在發生事故時將停機時間降至最低。

不幸的是,這還不是全部,因為從字面上看,該方案運行的前兩週表明TCP 健康檢查也是一個不可靠的東西:在上游伺服器上它可能不是Nginx,或者處於D 狀態的Nginx,並且在這種情況下,核心將接受連接,健康檢查將通過,但不會工作。 因此,我們立即用 health-check http 替換了它,做了一個特定的,如果它返回 200,那麼這個腳本中的一切都有效。 您可以執行其他邏輯 - 例如,在快取伺服器的情況下,檢查檔案系統是否已正確安裝:

Badoo 如何實現每秒渲染 200 萬張照片的能力

這很適合我們,只不過目前電路完全重複了硬體的功能。 但我們想做得更好。 以前,我們有一台備份伺服器,這可能不太好,因為如果你有一百台伺服器,那麼當幾台伺服器同時出現故障時,一台備份伺服器不太可能應付負載。 因此,我們決定將預留分配到所有伺服器:我們只是創建了另一個單獨的上游,根據它們可以服務的負載使用某些參數寫入所有伺服器,並添加了與之前相同的運行狀況檢查:

Badoo 如何實現每秒渲染 200 萬張照片的能力

由於不可能轉到一個上游中的另一個上游,因此有必要確保如果主上游(我們在其中簡單記錄了正確的、必要的照片快取)不可用,我們只需透過 error_page 進行回退,從我們去哪裡備份上游:

Badoo 如何實現每秒渲染 200 萬張照片的能力

透過字面上添加四台伺服器,這就是我們得到的:我們替換了部分負載- 我們將其從LTM 移至這些伺服器,使用標準硬體和軟體在那裡實現相同的邏輯,並立即收到這些伺服器可以提供的好處可以擴展,因為它們可以簡單地按需供應。 好吧,唯一的缺點是我們失去了對外部用戶的高可用性。 但那一刻我們不得不犧牲這一點,因為我們必須立即解決問題。 所以,我們去掉了部分負載,當時大約是 40%,LTM 感覺很好,而且在問題開始兩週後,我們開始每秒發送的請求不是 45k,而是 55k。 事實上,我們成長了20%——這顯然是我們沒有給用戶的流量。 之後他們開始思考如何解決剩下的問題——確保外部的高可及性。

Badoo 如何實現每秒渲染 200 萬張照片的能力

我們停頓了一會兒,討論了我們將使用什麼解決方案。 有人建議使用 DNS、使用一些自製腳本、動態路由協定來確保可靠性…有很多選擇,但很明顯,為了真正可靠地傳送照片,您需要引入另一個層來監控這一點。 我們稱這些機器為照片導演。 我們依賴的軟體是Keepalived:

Badoo 如何實現每秒渲染 200 萬張照片的能力

首先,Keepalived 由什麼組成? 第一個是 VRRP 協議,為網路人員所熟知,位於網路設備上,為客戶端連接的外部 IP 位址提供容錯功能。 第二部分是IPVS,IP虛擬伺服器,用於在照片路由器之間進行平衡並確保該級別的容錯能力。 第三——健康檢查。

讓我們從第一部分開始:VRRP - 它是什麼樣的? 有一個特定的虛擬 IP,它在客戶端連接的 dns badooctdn.com 中有一個條目。 在某個時間點,我們在一台伺服器上有一個 IP 位址。 Keepalived 封包使用 VRRP 協定在伺服器之間運行,如果主伺服器從雷達中消失(伺服器已重新啟動或其他原因),備份伺服器會自動取得此 IP 位址 - 無需手動操作。 master和backup的區別主要是優先:優先順序越高,機器成為master的機會就越大。 一個非常大的優點是你不需要在伺服器本身上設定IP位址,在設定中描述它們就足夠了,如果IP位址需要一些自訂路由規則,可以直接在設定中描述,使用與VRRP 套件中描述的語法相同。 你不會遇到任何陌生的事情。

Badoo 如何實現每秒渲染 200 萬張照片的能力

這在實踐中是什麼樣子的? 如果其中一台伺服器發生故障會發生什麼事? 一旦主伺服器消失,我們的備份就會停止接收廣告並自動成為主伺服器。 一段時間後,我們修復了主伺服器,重新啟動,啟動了 Keepalived - 廣告到達的優先權高於備份,備份會自動返回,刪除 IP 位址,無需執行任何手動操作。

Badoo 如何實現每秒渲染 200 萬張照片的能力

這樣就保證了外部IP位址的容錯性。 下一部分是以某種方式平衡從外部 IP 位址到已經終止它的照片路由器的流量。 平衡協議的一切都非常清楚。 這要么是簡單的循環,要么是稍微複雜一點的東西,wrr,列表連接等等。 這個基本上文檔裡都有描述,沒有什麼特別的。 但是交付方式......在這裡我們將仔細看看為什麼我們選擇其中一個。 它們是 NAT、直接路由和 TUN。 事實上,我們立即計劃從這些網站提供 100 GB 的流量。 如果你估計的話,你需要10個千兆卡,對吧? 一台伺服器10個千兆卡至少已經超出了我們「標準設備」概念的範圍。 然後我們想起我們不只是送一些流量,我們還會送照片。

有什麼特別的? — 傳入和傳出流量之間存在巨大差異。 傳入流量很小,傳出流量很大:

Badoo 如何實現每秒渲染 200 萬張照片的能力

如果你看一下這些圖表,你會發現此刻導演每秒接收大約 200 MB,這是非常平常的一天。 我們每秒返回 4,500 MB,我們的比率約為 1/22。 很明顯,要向 22 台工作伺服器完全提供傳出流量,我們只需要一台接受此連線的伺服器。 這就是直接路由演算法為我們提供幫助的地方。

它是什麼樣子的? 我們的照片總監,根據他的表格,將連線傳輸到照片路由器。 但是照片路由器將返回流量直接發送到互聯網,發送到客戶端,它不會通過照片導演返回,因此,用最少的機器數量,我們確保完全容錯和泵送所有流量。 在配置中,它看起來像這樣:我們指定演算法,在我們的例子中它是一個簡單的 rr,提供直接路由方法,然後開始列出所有真實伺服器,我們有多少個。 這將決定這個流量。 如果我們在那裡有一台或兩台以上的伺服器,或者有多台伺服器,就會出現這樣的需求 - 我們只需將此部分添加到配置中即可,不必太擔心。 從真實伺服器的角度來看,從照片路由器的角度來看,這種方法需要最少的配置,並且在文件中描述得非常完美,並且沒有任何陷阱。

特別好的是,這樣的解決方案並不意味著對本地網路進行徹底的重新設計;這對我們來說很重要;我們必須以最小的成本來解決這個問題。 如果你看 IPVS 管理命令輸出,然後我們就會看到它是什麼樣子的。 這裡我們有一個虛擬伺服器,在連接埠 443 上偵聽、接受連接,列出所有工作伺服器,您可以看到連接是相同的。 如果我們查看同一虛擬伺服器上的統計數據,我們會發現有傳入資料包、傳入連接,但絕對沒有傳出資料包。 傳出連線直接到達客戶端。 好吧,我們能夠使其失去平衡。 現在,如果我們的其中一個照片路由器發生故障會發生什麼? 畢竟,鐵就是鐵。 它可能會陷入內核恐慌,它可能會崩潰,電源可能會燒壞。 任何事物。 這就是為什麼需要健康檢查。 它們可以像檢查連接埠如何開啟一樣簡單,也可以更複雜,甚至可以檢查業務邏輯的一些家庭編寫的腳本。

我們停在中間的某個地方:我們有一個到特定位置的 https 請求,呼叫腳本,如果它回應第 200 個回應,我們相信該伺服器一切正常,它還活著並且可以完全打開容易。

這在實踐中又如何呢? 讓我們關閉伺服器進行維護 - 例如刷新 BIOS。 在日誌中,我們立即超時,我們看到第一行,然後在三次嘗試後它被標記為“失敗”,並且它只是從列表中刪除。

Badoo 如何實現每秒渲染 200 萬張照片的能力

當 VS 簡單地設定為零時,第二種行為選項也是可能的,但如果傳回照片,則效果不佳。 伺服器啟動,Nginx 在那裡啟動,運行狀況檢查立即了解到連接正在工作,一切都很好,伺服器出現在我們的清單中,並且負載立即開始應用於它。 值班管理員無需手動操作。 伺服器在晚上重新啟動 - 監控部門不會在晚上打電話給我們詢問此事。 他們告訴你這件事發生了,一切都很好。

所以,我們用相當簡單的方式,借助少量伺服器,解決了外部容錯的問題。

剩下要說的是,當然,這一切都需要監控。 另外,應該指出的是,Keepalivede 作為很久以前編寫的軟體,有很多方法來監控它,都使用透過 DBus、SMTP、SNMP 和標準 Zabbix 進行檢查。 另外,他自己幾乎知道如何為每個噴嚏寫字母,說實話,在某些時候我們甚至想過將其關閉,因為他為任何流量切換、打開、每個IP連接寫了很多字母,等等 。 當然,如果有很多伺服器,那麼這些信件可能會讓你不知所措。 我們使用標準方法監控照片路由器上的 nginx,硬體監控也沒有消失。 當然,我們也建議兩件事:首先,外部健康檢查和可用性,因為即使一切正常,事實上,用戶也可能由於外部提供者的問題或更複雜的原因而收不到照片。 在亞馬遜或其他地方的另一個網路上保留一台可以從外部 ping 您的伺服器的單獨機器總是值得的,對於那些知道如何進行棘手的機器學習的人來說,也值得使用異常檢測,或者簡單的監控,至少是為了追蹤請求是否急劇下降,或者相反,是否增加。 它也很有用。

讓我們總結一下:事實上,我們用一個相當簡單的系統取代了鐵定的解決方案,該解決方案在某些時候不再適合我們,該系統的所有功能都相同,也就是說,它提供了HTTPS流量的終止和進一步的智慧路由必要的健康檢查。 我們提高了這個系統的穩定性,也就是說,我們仍然對每一層都具有高可用性,而且我們還有一個好處是,在每一層上擴展它都非常容易,因為它是帶有標準軟體的標準硬件,即,我們簡化了可能問題的診斷。

我們最終得到了什麼? 我們在 2018 年 40 月假期期間遇到了問題。 在我們將該方案投入運行的前六個月中,我們將其擴展到所有流量,以消除 LTM 中的所有流量,我們僅將一個資料中心的流量從 60 GB 增長到 2018 GB,同時XNUMX 年全年每秒發送的照片數量幾乎增加了三倍。

Badoo 如何實現每秒渲染 200 萬張照片的能力

來源: www.habr.com

添加評論