LinkedIn的架構演進之路
自2003年創立至今,LinkedIn全球用戶數已經從第一周的2700增長到了現在的3個多億。它每天每秒都要提供成千上萬的網頁請求,而且移動賬戶已經占據了全球50%的流量。所有這些請求都是從他們的后臺系統獲取數據,而這個后臺系統每秒需要處理數以百萬計的查詢。LinkedIn高級工程經理Josh Clemm撰文介紹了LinkedIn架構10多年來的演進。
Leo最開始的時候,LinkedIn是一個他們稱之為“Leo”的單體應用。該應用托管著所有各種頁面的Web Servlet,處理業務邏輯,并連接到少量的LinkedIn數據庫。
“會員圖(Member Graph)”
作為一個社交網絡,他們做的第一件事是管理會員之間的連接關系。他們需要一個系統,使用圖遍歷的方式查詢連接數據,并且要常駐內存,以保證效率和性能。同時,它還需要能夠獨立于Leo進行擴展。因此,他們為實現 會員圖 創建了一個單獨的系統Cloud。LinkedIn的第一個服務就此誕生。為了實現圖服務與Leo的分離,他們使用了Java RPC通信。大約正是這個時候,他們產生了搜索功能需求。他們的會員圖服務開始向一個新的運行Lucene的搜索服務提供數據。
只讀副本數據庫隨著網站的發展,Leo的功能越來越多,復雜性也越來越高。負載均衡可以幫助啟動多個Leo實例。但新增的負載使LinkedIn最關鍵的系統不堪負重—— 會員資料數據庫 。
這個問題可以通過簡單地增加CPU和內存來解決。他們這么做了,但還是不夠。資料數據庫需要同時處理讀寫流量,所以為了擴展,他們引入了從屬副本數據庫。該庫是會員數據庫的一個副本,二者之間使用databus(現已開源)的早期版本保持同步。副本數據庫負責處理所有的讀流量,而且他們構建了一個邏輯,用于確定什么時候從副本讀取是安全的。
但隨著流量越來越大,作為單體應用的Leo經常宕掉,而且很難診斷和恢復,新代碼也不容易發布。對LinkedIn而言,高可用性非常關鍵。顯然,他們需要需要將Leo分解成許多小功能和無狀態服務。
面向服務的架構他們抽取微服務和業務邏輯,然后按領域抽取展示層。對于新產品,他們會在Leo之外創建全新的服務。他們構建了前端服務器,用于從不同的域中獲取數據、處理展示邏輯以及通過JSP構建HTML。他們構建了中間層服務,提供訪問數據模型和后端數據服務的API,實現對數據庫的一致性訪問。到2010年,他們已經有超過150個單獨的服務。現在,他們有超過750個服務。
至此,他們已可以針對單個服務進行擴展。期間,他們還構建了早期的配置和性能監控功能。
緩存由于發展迅猛,LinkedIn需要進一步擴展。他們通過增加更多的緩存層來減少整體負載。比如,引入類似memcache或couchbase的中間層緩存,向數據層添加緩存,并在必要的時候使用Voldemort進行預計算。但實際上,隨著時間推移,考慮到緩存失效增加了系統復雜性,而“調用圖(call graph)”難以管理,他們又去掉了許多中間層緩存,而只保留了離數據存儲最近的緩存,在保證低延遲和橫向擴展能力的同時,降低了認知負荷。
Kafka為了收集日益增長的數據量,LinkedIn開發了許多自定義的數據管道,用于對數據進行流式處理。例如,他們需要讓數據流入數據倉庫,需要將數據批量發送給Hadoop工作流用于分析,需要收集和匯總每個服務的日志信息,等等。隨著網站的發展,這樣的自定義管道越來越多。如果網站需要擴展,每個管道都需要擴展。因此,他們基于提交日志的概念開發了一個分布式的發布訂閱消息平臺Kafka,作為通用的數據管道。該平臺支持對任何數據源的準實時訪問,有效地支撐了Hadoop作業和實時分析,極大了提升了站點監控和預警功能,使他們可以可視化和跟蹤調用圖。現在,Kafka每天處理超過5000億事件。
Inversion2011年底,LinkedIn啟動一個名為Inversion的內部項目,暫停了所有的功能開發,整個工程組織全部致力于改進工具、部署基礎設施和開發效率。
Rest.li在從Leo轉換到面向服務的架構的過程中,抽取出來的API采用了基于Java的RPC技術,不僅各團隊不一致,而且與展示層緊耦合。為了解決這個問題,他們構建了一個新的API模型Rest.li。這是一種以數據模型為中心的架構,可以確保整個公司使用同一個無狀態的Restful API模型,而且非Java客戶端也可以輕松地使用。這一措施不僅實現了API與展示層的解耦,而且解決了許多向后兼容的問題。此外,借助動態發現(D2),他們還針對每個服務API實現了基于客戶端的負載均衡、服務發現和擴展。現在,LinkedIn有超過975個Rest.li資源和每天超過1000億次的Rest.li調用。
超塊(Super Blocks)面向服務的架構可以解耦域及實現服務的獨立擴展,但它也有缺點。他們的許多應用程序都需要獲取許多類型的不同數據,發起數以百計的調用。所有的調用就構成了上文提到的“調用圖”。該調用圖非常難以管理,而且管理難度越來越大。為此,他們引入了“超塊”的概念,為一組后端服務提供一個可以獨立訪問的API。這樣,他們就可以有一個專門的團隊對塊進行優化,并控制每個客戶端的調用圖。
多數據中心他們不僅要避免單個服務成為單點故障點,而且要避免整個站點成為單點故障點,因此多數據中心非常重要。現在LinkedIn主要通過三個數據中心提供服務,并在全球范圍內提供PoPs服務。
</article>