LinkedIn如何通過合并50萬QPS身份服務將延遲降低10%?

來源: InfoQ
作者:張翔等
時間:2020-12-04
16991
在LinkedIn,為用戶資料和會員設置提供數據的身份服務是一個非常關鍵的系統(tǒng)。在本文中,我們將分享我們如何通過合并身份服務(每秒處理超過50萬個查詢請求)將延遲減少了10%,并極大降低了年度服務成本。

在LinkedIn,為用戶資料和會員設置提供數據的身份服務是一個非常關鍵的系統(tǒng)。在本文中,我們將分享我們如何通過合并身份服務(每秒處理超過50萬個查詢請求)將延遲減少了10%,并極大降低了年度服務成本。內容將涉及我們所使用的基于數據驅動的架構、用到的工具以及從舊架構總結出的經驗教訓。

1 背景

LinkedIn的會員系統(tǒng)采用了面向服務架構,以此來提供各種不同的體驗。服務隱藏了內部領域模型的復雜性,并通過定義良好的服務API把功能暴露出來。這種抽象保證了系統(tǒng)的可演化性和可組合性。

下圖是合并之前的身份服務的總體架構圖,包括服務、客戶端和下游服務??蛻舳苏{用中間層服務獲取資料和設置信息,中間層服務依賴數據服務,數據服務對Espresso(LinkedIn的分布式NoSQL數據庫)數據存儲執(zhí)行CRUD操作。數據服務只實現了有限的邏輯,比如數據驗證(例如數據類型驗證、字符串長度驗證等)。中間層服務還調用了其他服務,這些服務由LinkedIn的其他團隊負責開發(fā),提供了重要的領域數據。這些下游服務提供了垃圾信息過濾和阻塞、會員邀請、會員連接等功能。中間層服務基于這些信息實現業(yè)務邏輯,確保用戶可以自由設置自己的資料以及與LinkedIn和其他第三方應用程序交互。

640.png

2 動機

隨著應用程序規(guī)模的增長和系統(tǒng)功能不斷增加,開發(fā)團隊開始把關注點放在了性能、服務成本和運維開銷上。另外,我們也開始重新評估和思考之前的一些設計和開發(fā)方式。

我們發(fā)現,繼續(xù)讓數據服務和中間層服務獨立運行存在一些問題:

·將數據服務和中間層服務分離,這樣的設計可能沒有當初想象得那么有價值。我們發(fā)現,大部分伸縮性方面的問題都可以在存儲層解決,也就是在Espresso數據存儲端。況且,對Espresso讀寫操作實際上都是來自數據服務。

·將數據服務作為單獨的服務增加了運維開銷和代碼復雜性。為此,我們分配了1000個應用程序實例。另外,我們需要單獨為中間層提供API,涉及數據建模、API演化和安全等方面的工作。

·數據服務里只有很少的業(yè)務邏輯,大部分都與數據驗證有關。

·對于客戶端來說,中間層服務和數據服務的分離增加了網絡跳數。

基于以上這些考慮,我們打算在保持API不變的情況下把中間層服務和數據服務合并成一個服務。從面相服務架構的角度來看,這樣做有點違反直覺,因為面相服務架構的意義在于將大系統(tǒng)拆分成小系統(tǒng),以此來解決復雜性問題。不過,我們相信可以找到一個平衡點,合并服務從性能、服務成本和運維開銷方面得到的好處比合并服務帶來的復雜性要大得多。

3 實現

得益于微服務架構,我們可以在不影響客戶端的情況下把兩個服務合并成一個。我們保持中間層接口不變,把數據服務的代碼合并到中間層,讓中間層直接操作數據存儲層。我們的一個重要的目標是盡量讓新舊架構的功能和性能保持不變。另外,我們也要注意在合并兩個重要系統(tǒng)時可能會遇到的風險,并最小化合并的開發(fā)成本。

我們分四步實現服務的合并。

第一步:我們有兩種方式來合并代碼庫。最直接的方式是把數據服務的代碼拷貝到中間層,這樣就可以執(zhí)行數據驗證和調用數據存儲。不過,雖然這種方式最為直接,但在確定可行之前需要做很多前期的開發(fā)工作。于是,我們選擇了另外一種“取巧”的方式,我們直接將數據服務的REST API作為中間層的一個本地庫。

第二步:我們逐步執(zhí)行在第一步中定下的方案。LinkedIn有一個非常厲害的AB測試框架,叫作T-REX,我們用它生成統(tǒng)計報告,基于風險等級和變更影響范圍來安排進度。我們可以邊觀察邊做出修改,在必要的情況下可以進行快速回滾(在幾分鐘內)。因為我們合并的是兩個非常關鍵的系統(tǒng),風險較高,影響較大,所以在安排進度時也非常謹慎。我們一個數據中心接一個數據中心地遷移,在每一個數據中心里也是先從小比例開始,再逐漸加大,確保有足夠的時間生成統(tǒng)計報告。

https://engineering.linkedin.com/teams/data/analytics-platform-apps/data-applications/t-rex

第三步:下線數據服務的主機。

第四步:因為第一步的方案走了捷徑,直接將REST API作為本地庫調用,所以現在需要清理這些代碼。在LinkedIn,工匠精神是我們文化的一個重要組成部分。我們把暴露REST服務需要的類和接口移除掉,只保留訪問數據存儲需要的類。

下圖顯示了架構變更前后的區(qū)別。

640 (1).png

4 性能分析

為了比較合并前和合并后的性能,我們采用了一種叫作“Dark Canary”的機制。我們以一種可控的方式把真實的生產環(huán)境的只讀流量導給測試主機。例如,我們可以把一臺生產主機的流量加倍并導給一臺測試主機,這些是在不影響生產主機的情況下進行的。也就是說,我們可以在不影響業(yè)務的情況下使用生產流量進行性能測試。下面是我們的Dark Canary架構。

640 (2).png

下面的兩張圖顯示了常規(guī)生產流量和測試流量的p90延遲區(qū)別。p90延遲平均從26.67毫秒下降到24.84毫秒(6.9%的下降幅度)。

1607064399(1).png

通常,因為影響因素太多,p99指標是很難提升的。不過,我們確實做到了??傮w來說,合并后的服務分別將p50、p90、p99提升了14%、6.9%和9.6%。

5 內存分配

為了了解性能的特征,我們基于GC日志分析了內存分配情況。這些日志來自三種主機:中間層服務所在的測試主機、中間層所在的生產主機和數據服務主機。GC日志提供了非常有價值的有關對象分配模式的信息,這些信息通常可以說明應用程序的性能情況以及它們是如何使用內存的。下圖顯示了中間層所在的生產主機的內存分配情況,平均內存分配率是每秒350MB。

640.webp (1).jpg

在合并之后,中間層服務的內存分配率比之前每秒減少了100MB左右(28.6%)。這不僅改進了性能,也降低了服務成本。

6 服務成本

服務成本是業(yè)務決策的一個參考因素。在LinkedIn,我們使用了一種內部框架,基于硬件和運維成本來計算服務成本。我們的團隊也使用這個框架對合并后的服務進行了分析統(tǒng)計,在將數據服務所在的主機移除之后,在物理資源方面節(jié)省了超過12000個核心和13000GB的內存,相當于每年節(jié)省了相當大一筆費用。

參考閱讀:

https://engineering.linkedin.com/blog/2020/reducing-latency-and-cost-for-identity-services

作者 | 張翔等

譯者 | 無名

策劃 | 小智

立即登錄,閱讀全文
版權說明:
本文內容來自于InfoQ,本站不擁有所有權,不承擔相關法律責任。文章內容系作者個人觀點,不代表快出海對觀點贊同或支持。如有侵權,請聯系管理員(zzx@kchuhai.com)刪除!
掃碼登錄
打開掃一掃, 關注公眾號后即可登錄/注冊
加載中
二維碼已失效 請重試
刷新
賬號登錄/注冊
個人VIP
小程序
快出海小程序
公眾號
快出海公眾號
商務合作
商務合作
投稿采訪
投稿采訪
出海管家
出海管家