如何使用火焰圖來降低伺服器負載
LucidChart 提供在線編輯流程圖、網路拓撲圖、ER 圖、 UML 圖以及腦圖等多種圖表服務,有超過 7 百萬的用戶,因其簡單直觀的交互體驗和強大的多人協作功能,是可以替代 Visio 的最佳選擇。
在 Lucid,我們使用面向服務的架構來建設我們的系統。其中字體服務(font service)就是其中之一,它負責根據字體族名稱和 unicode 編碼範圍來提供相應的字體服務,同時也對用戶上傳的字體進行校驗和檢查。在生產環境中,該服務的負載一直很高,這一點超出我們的預期(使用或等待 CPU 的平均線程數)。特別從去年開始,我們注意到字體服務的負載高的驚人,特別是在晚上這樣的流量低峰時期。
幸運的是最終我們找到了根本原因,並通過改進大大提高了服務的整體性能和穩定性。通過下面的內容,您將了解到我們是如何做到的。
圖1: 字體服務在變更前後伺服器平均負載對比
通過火焰圖來調試和發現問題我們從 Netflix 找到了一個非常棒的火焰圖工具[1][2],並部署到生產環境。 此工具可以將多個不同調試分析工具的數據組合在一起並生成火焰圖,以可視化的方式展示伺服器和 JVM 的資源使用情況。
如下圖所示,每個矩形表示一個棧幀,同時矩形的寬度代表了資源(比如 CPU 時間)的使用情況,Y 軸表示調用棧。通過識別那些寬的矩形塊,就能快速縮小問題範圍。在調試和排查字體服務時,它極大地幫助了我們。
圖2: 高負載時字體服務中一台伺服器的火焰圖
在高負載狀態下,我們對字體服務收集數據並生成了幾個火焰圖。下圖是其中之一,並且特別展示了 JVM 相關棧的部分。可以分析得出,大部分時間都花在了 libz.so
這一步(gzip 使用該庫進行壓縮/解壓縮操作),剩下大部分時間都花在了 XML 轉義和 UTF-8 編碼上。
圖3: JVM 相關棧活動的局部火焰圖
找到慢的原因
首先多啰嗦幾句這個字體服務的一些背景情況。我們將所有字體相關數據存儲在 Amazon S3 中,具體來說是將每個字體的每個 unicode 範圍分別存為一個 S3 object
。當其他服務請求為了獲取字體族,一組 unicode 範圍,或者是用戶自定義字體時會向字體服務請求字體數據,接著字體服務將字體數據包裹在 XML 中返回。
功能非常簡單,並沒有什麼明顯的密集型計算。但是對於出現的高負載問題,火焰圖幫助我們識別出了問題所在—— libz
,XML 轉義和 UTF-8編碼都使用了大量的 CPU。
但是為什麼會產生這麼多編碼和壓縮的消耗?記得前面提到晚上時間的負載反而是最高的嗎?我們的晚上(美國山區時間)正好是亞洲地區的白天,該地區很多用戶都使用中文、日文或韓文等亞洲語言。會進行大量的 gzip 解壓縮 → UTF-8解碼 → XML 轉義 → UTF-8編碼 → gzip 壓縮。相比於拉丁語系,單個 CJK 的 unicode 範圍比拉丁語系的 unicode 範圍大2個數量級(1MB:60KB)。所以上述的轉換過程都壓到了 CPU 上,特別壓縮和解壓縮,以及 XML 轉義這類操作。
如何改進?字體服務對請求的響應本質上只是 S3 上原始數據的集合。它確實需要執行一些重要的附加任務,如許可權檢查和從字體族中檢索名稱。但是,字體服務根本沒必要擋在 S3 前面來代理那些字體數據!所以解決辦法很簡單, 直接用包含 S3 object 的鏈接(就是那些字體數據)的列表作為響應返回,字體服務不再從 S3 下載並重新編碼字體數據。所以從圖1中可以看出負載幾乎降低到可忽略的程度。
總結通過調試分析生產環境,我們能夠找到並消除那些不必要的任務和工作,進而降低伺服器負載。
使用例如火焰圖之類的分析工具(profiling tool)來幫助識別 CPU 高佔用的操作。
壓縮/解壓縮和各種編碼/解碼的操作都是昂貴的。
如果客戶端可以直接訪問數據,那麼相比代理(客戶端去請求)數據,直接返回鏈接是最好的選擇,可以顯著提高整體性能。
參考鏈接
[1] Brendan D. Gregg的個人網站 http://www.brendangregg.com
[2] Flame graphs http://www.brendangregg.com/flamegraphs.html
[3] 白話火焰圖 https://huoding.com/2016/08/18/531
[4] Java Flame graphs http://www.brendangregg.com/blog/2014-06-12/java-flame-graphs.html
[5] OpenRestry 關於火焰圖在 Lua 中的使用 https://moonbingbing.gitbooks.io/openresty-best-practices/flame_graph.html
[6] 在 Netflix 中的應用 http://techblog.netflix.com/2015/07/java-in-flames.html
[7] 在 Netflix 中的應用 http://techblog.netflix.com/2016/04/saving-13-million-computational-minutes.html
※被忽視的點陣圖資料庫:Pilosa查詢十億級計程車搭乘數據案例
※架構未來怎麼寫,Facebook、Uber、Airbnb、Yahoo!給你這些答案
※分布式服務框架選型:面對Dubbo,阿里巴巴為什麼選擇了HSF?
※是的,為了更好的支持微服務,我們從PHP遷移到了Go
TAG:高可用架構 |
※混凝土泵車使用過程中如何降低爆管事故?
※如何降低糖尿病可能帶來的風險?
※如何降低酒精對肝臟的危害?
※如何降低白斑擴散帶來的影響
※巨頭髮力場景應用,AI門檻如何降低?
※消音器並不會降低子彈動能,為什麼狙擊手還很少使用?不怕暴露?
※有飛機能不靠彈射起飛嗎?沒了彈射技術艦載機會停飛嗎?效率降低
※甘油三酯升高對身體有哪些危害,如何才能降低
※現代武器操作難度大,如果降低到開汽車的水平怎麼樣?褒貶不一
※喝茶能使血壓降低嗎?高血壓患者應該注意些什麼?
※高血糖如何降下來,天然「降糖葯」是它們,多吃降低血糖身體好
※喝黑茶可以降低尿酸,效果如何?
※巧拿雨傘可降低血壓?不信你試一試
※如何運動來降低血脂和心臟病發病風險?
※「油煙」吸多了會導致肺癌,如何才能降低危害?
※如何飲食才能降低血脂?告訴你真相
※如何降低汽車噪音,瀟洒車告訴您
※如何降低輻射對眼睛的傷害?
※如何預防快速減肥導致的免疫力降低快?
※網路遊戲是如何降低你的戒色恢復質量