揭祕 Twitter 背後的基礎設施:效率與優化篇

mazdakh發表於2016-10-08

過去我們曾經發布過一些關於 FinagleManhattan 這些專案的文章,還寫過一些針對大型事件活動的架構優化的文章,例如天空之城、超級碗、2014 世界盃、全球新年夜慶祝活動等。在這篇基礎設施系列文章中,我主要聚焦於 Twitter 的一些關鍵設施和元件。我也會寫一些我們在系統的擴充套件性、可靠性、效率方面的做過的改進,例如我們基礎設施的歷史,遇到過的挑戰,學到的教訓,做過的升級,以及我們現在前進的方向等等。

天空之城:2013 年 8 月 2 日,宮崎駿的《天空之城Castle in the Sky》在 NTV 迎來其第 14 次電視重播,劇情發展到高潮之時,Twitter 的 TPS(Tweets Per Second)也被推上了新的高度——143,199 TPS,是平均值的 25 倍,這個記錄保持至今。-- LCTT 譯註

資料中心的效率優化

歷史

當前 Twitter 硬體和資料中心的規模已經超過大多數公司。但達到這樣的規模不是一蹴而就的,系統是隨著軟硬體的升級優化一步步成熟起來的,過程中我們也曾經犯過很多錯誤。

有個一時期我們的系統故障不斷。軟體問題、硬體問題,甚至底層裝置問題不斷爆發,常常導致系統運營中斷。出現故障的地方存在於各個方面,必須綜合考慮才能確定其風險和受到影響的服務。隨著 Twitter 在客戶、服務、媒體上的影響力不斷擴大,構建一個高效、可靠的系統來提供服務成為我們的戰略訴求。

Twitter系統故障的介面被稱為失敗鯨Fail Whale,如下圖 -- LCTT 譯註

Fail Whale

挑戰

一開始,我們的軟體是直接安裝在伺服器,這意味著軟體可靠性依賴硬體,電源、網路以及其他的環境因素都是威脅。這種情況下,如果要增加容錯能力,就需要統籌考慮這些互不關聯的物理裝置因素及在上面執行的服務。

最早採購資料中心方案的時候,我們都還是菜鳥,對於站點選擇、運營和設計都非常不專業。我們先直接託管主機,業務增長後我們改用租賃機房。早期遇到的問題主要是因為裝置故障、資料中心設計問題、維護問題以及人為操作失誤。我們也在持續迭代我們的硬體設計,從而增強硬體和資料中心的容錯性。

服務中斷的原因有很多,其中硬體故障常發生在伺服器、機架交換機、核心交換機這地方。舉一個我們曾經犯過的錯誤,硬體團隊最初在設計伺服器的時候,認為雙路電源對減少供電問題的意義不大 -- 他們真的就移除了一塊電源。然而資料中心一般給機架提供兩路供電來提高冗餘性,防止電網故障傳導到伺服器,而這需要兩塊電源。最終我們不得不在機架上增加了一個 ATS 單元(交流切換開關AC transfer switch)來接入第二路供電。

提高系統的可靠性靠的就是這樣的改進,給網路、供電甚至機房增加冗餘,從而將影響控制到最小範圍。

我們學到的教訓以及技術的升級、遷移和選型

我們學到的第一個教訓就是要先建模,將可能出故障的地方(例如建築的供電和冷卻系統、硬體、光纖網路等)和執行在上面的服務之間的依賴關係弄清楚,這樣才能更好地分析,從而優化設計提升容錯能力。

我們增加了更多的資料中心提升地理容災能力,減少自然災害的影響。而且這種站點隔離也降低了軟體的風險,減少了例如軟體部署升級和系統故障的風險。這種多活的資料中心架構提供了程式碼灰度釋出staged code deployment的能力,減少程式碼首次上線時候的影響。

我們設計新硬體使之能夠在更高溫度下正常執行,資料中心的能源效率因此有所提升。

下一步工作

隨著公司的戰略發展和運營增長,我們在不影響我們的終端使用者的前提下,持續不斷改進我們的資料中心。下一步工作主要是在當前能耗和硬體的基礎上,通過維護和優化來提升效率。

硬體的效率優化

歷史和挑戰

我們的硬體工程師團隊剛成立的時候只能測試市面上現有硬體,而現在我們能自己定製硬體以節省成本並提升效率。

Twitter 是一個很大的公司,它對硬體的要求對任何團隊來說都是一個不小的挑戰。為了滿足整個公司的需求,我們的首要工作是能檢測並保證購買的硬體的品質。團隊重點關注的是效能和可靠性這兩部分。對於硬體我們會做系統性的測試來保證其效能可預測,保證儘量不引入新的問題。

隨著我們一些關鍵元件的負荷越來越大(如 Mesos、Hadoop、Manhattan、MySQL 等),市面上的產品已經無法滿足我們的需求。同時供應商提供的一些高階伺服器功能,例如 Raid 管理或者電源熱切換等,可靠性提升很小,反而會拖累系統效能而且價格高昂,例如一些 Raid 控制器價格高達系統總報價的三分之一,還拖累了 SSD 的效能。

那時,我們也是 MySQL 資料庫的一個大型使用者。SAS(序列連線 SCSI Serial Attached SCSI)裝置的供應和效能都有很大的問題。我們大量使用 1U 規格的伺服器,它的磁碟和回寫快取一起也只能支撐每秒 2000 次的順序 IO。為了獲得更好的效果,我們只得不斷增加 CPU 核心數並加強磁碟能力。我們那時候找不到更節省成本的方案。

後來隨著我們對硬體需求越來越大,我們成立了一個硬體團隊,從而自己來設計更便宜更高效的硬體。

關鍵技術變更與選擇

我們不斷的優化硬體相關的技術,下面是我們採用的新技術和自研平臺的時間軸。

  • 2012 - 採用 SSD 作為我們 MySQL 和 Key-Value 資料庫的主要儲存。
  • 2013 - 我們開發了第一個定製版 Hadoop 工作站,它現在是我們主要的大容量儲存方案。
  • 2013 - 我們定製的解決方案應用在 Mesos、TFE( Twitter Front-End )以及快取裝置上。
  • 2014 - 我們定製的 SSD Key-Value 伺服器完成開發。
  • 2015 - 我們定製的資料庫解決方案完成開發。
  • 2016 - 我們開發了一個 GPU 系統來做模糊推理和訓練機器學習。

學到的教訓

硬體團隊的工作本質是通過做取捨來優化 TCO(總體擁有成本),最終達到達到降低 CAPEX(資本支出)和 OPEX(運營支出)的目的。概括來說,伺服器降成本就是:

  1. 刪除無用的功能和元件
  2. 提升利用率

Twitter 的裝置總體來說有這四大類:儲存裝置、計算裝置、資料庫和 GPU 。 Twitter 對每一類都定義了詳細的需求,讓硬體工程師更針對性地設計產品,從而優化掉那些用不到或者極少用的冗餘部分。例如,我們的儲存裝置就專門為 Hadoop 優化過,裝置的購買和運營成本相比於 OEM 產品降低了 20% 。同時,這樣做減法還提高了裝置的效能和可靠性。同樣的,對於計算裝置,硬體工程師們也通過移除無用的特性獲得了效率提升。

一個伺服器可以移除的元件總是有限的,我們很快就把能移除的都扔掉了。於是我們想出了其他辦法,例如在儲存裝置裡,我們認為降低成本最好的辦法是用一個節點替換多個節點,並通過 Aurora/Mesos 來管理任務負載。這就是我們現在正在做的東西。

對於這個我們自己新設計的伺服器,首先要通過一系列的標準測試,然後會再做一系列負載測試,我們的目標是一臺新裝置至少能替換兩臺舊裝置。最大的效能提升來自增加 CPU 的執行緒數,我們的測試結果表示新 CPU 的 單執行緒能力提高了 20~50% 。同時由於整個伺服器的執行緒數增加,我們看到單執行緒能效提升了 25%。

這個新裝置首次部署的時候,監控發現新裝置只能替換 1.5 臺舊裝置,這比我們的目標低了很多。對效能資料檢查後發現,我們之前對負載特性的一些假定是有問題的,而這正是我們在做效能測試需要發現的問題。

對此我們硬體團隊開發了一個模型,用來預測在不同的硬體配置下當前 Aurora 任務的填充效率。這個模型正確的預測了新舊硬體的效能比例。模型還指出了我們一開始沒有考慮到的儲存需求,並因此建議我們增加 CPU 核心數。另外,它還預測,如果我們修改記憶體的配置,那系統的效能還會有較大提高。

硬體配置的改變都需要花時間去操作,所以我們的硬體工程師們就首先找出幾個關鍵痛點。例如我們和 SRE(網站可靠性工程師Site Reliability Engineer)團隊一起調整任務順序來降低儲存需求,這種修改很簡單也很有效,新裝置可以代替 1.85 箇舊裝置了。

為了更好的優化效率,我們對新硬體的配置做了修改,只是擴大了記憶體和磁碟容量就將 CPU 利用率提高了20% ,而這隻增加了非常小的成本。同時我們的硬體工程師也和合作生產廠商一起為那些伺服器的最初出貨調整了物料清單。後續的觀察發現我們的自己的新裝置實際上可以代替 2.4 臺舊裝置,這個超出了預定的目標。

從裸裝置遷移到 mesos 叢集

直到 2012 年為止,軟體團隊在 Twitter 開通一個新服務還需要自己操心硬體:配置硬體的規格需求,研究機架尺寸,開發部署指令碼以及處理硬體故障。同時,系統中沒有所謂的“服務發現”機制,當一個服務需要呼叫一個另一個服務時候,需要讀取一個 YAML 配置檔案,這個配置檔案中有目標服務對應的主機 IP 和埠資訊(預留的埠資訊是由一個公共 wiki 頁面維護的)。隨著硬體的替換和更新,YAML 配置檔案裡的內容也會不斷的編輯更新。在快取層做修改意味著我們可以按小時或按天做很多次部署,每次新增少量主機並按階段部署。我們經常遇到在部署過程中 cache 不一致導致的問題,因為有的主機在使用舊的配置有的主機在用新的。有時候一臺主機的異常(例如在部署過程中它臨時當機了)會導致整個站點都無法正常工作。

在 2012/2013 年的時候,Twitter 開始嘗試兩個新事物:服務發現(來自 ZooKeeper 叢集和 Finagle 核心模組中的一個庫)和 Mesos(包括基於 Mesos 的一個自研的計劃任務框架 Aurora ,它現在也是 Apache 基金會的一個專案)。

服務發現功能意味著不需要再維護一個靜態 YAML 主機列表了。服務或者在啟動後主動註冊,或者自動被 mesos 接入到一個“服務集”(就是一個 ZooKeeper 中的 znode 列表,包含角色、環境和服務名資訊)中。任何想要訪問這個服務的元件都只需要監控這個路徑就可以實時獲取到一個正在工作的服務列表。

現在我們通過 Mesos/Aurora ,而不是使用指令碼(我們曾經是 Capistrano 的重度使用者)來獲取一個主機列表、分發程式碼並規劃重啟任務。現在軟體團隊如果想部署一個新服務,只需要將軟體包上傳到一個叫 Packer 的工具上(它是一個基於 HDFS 的服務),再在 Aurora 配置上描述檔案(需要多少 CPU ,多少記憶體,多少個例項,啟動的命令列程式碼),然後 Aurora 就會自動完成整個部署過程。 Aurora 先找到可用的主機,從 Packer 下載程式碼,註冊到“服務發現”,最後啟動這個服務。如果整個過程中遇到失敗(硬體故障、網路中斷等等), Mesos/Aurora 會自動重選一個新主機並將服務部署上去。

Twitter 的私有 PaaS 雲平臺

Mesos/Aurora 和服務發現這兩個功能給我們帶了革命性的變化。雖然在接下來幾年裡,我們碰到了無數 bug ,傷透了無數腦筋,學到了分散式系統裡的無數教訓,但是這套架還是非常讚的。以前大家一直忙於處理硬體搭配和管理,而現在,大家只需要考慮如何優化業務以及需要多少系統能力就可以了。同時,我們也從根本上解決了 Twitter 之前經歷過的 CPU 利用率低的問題,以前服務直接安裝在伺服器上,這種方式無法充分利用伺服器資源,任務協調能力也很差。現在 Mesos 允許我們把多個服務打包成一個服務包,增加一個新服務只需要修改配額,再改一行配置就可以了。

在兩年時間裡,多數“無狀態”服務遷移到了 Mesos 平臺。一些大型且重要的服務(包括我們的使用者服務和廣告服務系統)是最先遷移上去的。因為它們的體量巨大,所以它們從這些服務裡獲得的好處也最多,這也降低了它們的服務壓力。

我們一直在不斷追求效率提升和架構優化的最佳實踐。我們會定期去測試公有云的產品,和我們自己產品的 TCO 以及效能做對比。我們也擁抱公有云的服務,事實上我們現在正在使用公有云產品。最後,這個系列的下一篇將會主要聚焦於我們基礎設施的體量方面。

特別感謝 Jennifer FraserDavid BarrGeoff PapilionMatt SingerLam Dong 對這篇文章的貢獻。


via: https://blog.twitter.com/2016/the-infrastructure-behind-twitter-efficiency-and-optimization

作者:mazdakh 譯者:eriwoon 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關文章