融云QCon上海站深度解析:超大規模即時通訊系統性能優化探索及實踐
10月17日至19日,QCon全球軟件開發大會上海站如約而至。來自 Google、Facebook、LinkedIn、Twitter、騰訊、百度、青云、融云等國內外知名企業的百余位技術專家受邀參會,針對人工智能、編程語言、業務安全、軟件性能等熱點話題進行深入探討,并為與會嘉賓分享各自領域的技術干貨。
會議首日,融云展位便被眾多參會嘉賓圍住,分別就融云的IM技術、產品方案及業務合作方式等各內容進行全面的溝通交流,融云的公有云客戶汽車之家、滬江網校及私有云客戶陸金所等知名企業的技術人員也來到展位交流,紛紛對融云的技術產品及服務表達了高度的肯定。
18日上午,融云***架構師李淼為大家分享了《超大規模即時通訊系統性能優化探索及實踐》主題演講,就龐大復雜的系統性能問題該如何定位、分析以及工具排查;高并發系統的技術要點、難點、重點把控及措施、技巧;特定場景下系統性能問題優化可行性解決方案等內容進入深度解析。雖然臨近午飯時間,但大量的技術干貨及精彩的案例分享,讓現場一度爆滿,很多嘉賓即使站著也一直堅持聽完整場演講;即便會議結束,還有很多人與李淼進一步交流。
會議結束后參會嘉賓與李淼繼續溝通
以下為演講實錄摘要,希望在適用場景下,對開發者有所脾益。
各位好,臨近中午了,感謝還有這么多同學和我一起分享。今天的主題是超大規模即時通訊系統性能優化探索及實踐,介紹即時通訊模式下性能優化如何完成。通過今天介紹的模型,大家如果有所得的話可以在系統當中做一些應用實踐。
性能問題定位及關注點
首先說性能問題的關注點,對于程序首先最直觀的關注點就是程序的響應時長。前提是響應包括你的應答必須是正確的,如果說性能優化完成之后結果不正確,那可以說整個優化失敗。
除了程序響應時長以外我們還會關注系統、數據存儲以及數據通訊。系統有一些直觀指標可以衡量系統的健康性和系統性能。先說CPU,我們主要關注CPU的負載及使用率;接下來是內存,內存主要關注正常的內存利用率,是否使用了虛擬內存,以及內存碎片問題;I/O問題則關注磁盤和網絡I/O問題,I/O是整個系統優化過程中特別需要關注的點,I/O如果做的好,對于整個平臺的性能提升幫助是***的,有可能會比前面的CPU和內存還要大。
數據存儲方面,在即時通訊保證消息可靠性的情況下,優先進行消息存儲,通過這種方式保證消息不丟失、不亂序、不重復。對于數據存儲而言,其實和I/O有點類似,對于一般的業務來講,如果數據存儲優化的好,平臺優化方面就完成了60%左右的工作。
一般做系統時都會遇到網絡相關問題,這就會涉及到網絡通訊問題,怎么想辦法降低你的數據傳輸量,或者說降低你和網絡之間的交互次數,也是數據通訊里面需要完成的一個優化。
下面通過三個階段介紹一下融云關于性能問題的定位。***個階段融云剛剛成立,那個時候性能問題的定位主要是通過系統監控,配合著系統日志以及診斷工具,主要監控服務器里面的CPU、內存及I/O指標。
對于監控來講,我們有一個類似業務監控系統,定時對每個節點進行相關性的單元測試,以此來衡量當前服務的健康狀況,以及每個系統的響應速度。當線上出現了系統告警時,配合日志來查看業務是否正常。
第二個階段,我們嘗試過用一些開源的APM工具。在整個系統當中通訊模型是基于Actor模型做的,所以沒辦法整個構建服務監控網絡,只能看一些相關數據。但在座各位如果開發系統,用APM是一個非常好的工具,可以幫助你進行服務治理,系統監控相關的工作,同時APM也有很多商業解決方案。
第三個階段,我們在對APM調研以及試用出現問題之后,只能想辦法自研Monitor監控系統,我們會記錄每個信令的調用時間和調用鏈路,后臺有一個數據分析平臺,我們查看一些信令前一天和今天的比值,看是不是有幅度變化;同時我們也會配合業務數據量觀測數據。一旦某個信令出現異常,我們就會進行線上的服務排查。
實際上對于性能問題的定位來講,***個階段是最有效的,后面的手段都是輔助研發人員對于線上問題的定位,這些都是相輔相成的:你判斷問題、定位問題需要工具,工具也可以提高你判斷問題、定位問題的速度。
高并發系統技術要點
對于高并發系統來講,其實技術要點很多,我羅列了四條:異步通訊、緩存策略、數據結構及算法、數據存儲。對于性能優化來講,這四點僅僅是一部分,但如果把這四點做好,平臺就能得到一個很大的提升。
首先是異步通訊,對于現在的分布式系統來講,都需要對服務進行拆分,服務拆分以后我們需要通過一種方式將服務串聯起來,現在有很多開源的解決方案或框架,但是對于RPC來講,一般都是同步調用,有點類似于訪問數據庫,當前的工作線程需要等待調用端反饋結果。
如果說某個服務的響應時長十毫秒,對于調用端來講就需要等待十毫秒,為了解決這個問題,現在很多RPC都支持異步RPC的方式,通過回調的方式解決同步RPC工作線程占用以及等待的問題。
***一個是Actor模型,Actor模型實際上在整個軟件系統上是一個屬于多線程數據協調的模型。所有的請求以及返回結果會以消息的方式進行傳遞,融云也是使用了Actor模式作為服務間調用。
第二個是緩存策略,我們對于數據分為四層:首先是原始數據,這個數據是保存在數據庫里面的;第二個是分布式緩存,對于很多無狀態的服務而言,性能優化大部分依賴于分布式緩存來完成;第三個為了對數據訪問進行加速,可能會使用一些本地進程內緩存,由于沒有網絡訪問,同時直接的內存訪問速度更快,所以本地緩存策略也會作為服務加速的方式;***就是客戶端緩存了,現在無論是App開發,PC客戶開發都可以使用用戶側的數據存儲,Web上的H5也可以使用類似local storage解決方案,但是一旦使用了客戶端存儲,我們就需要設計一個健壯的數據同步模型。刨除客戶端緩存的問題,為了盡可能達到使熱數據離用戶近一些這個目的,我們就需要想盡一切辦法提高緩存的***率。
第三個是數據結構及算法,適合場景的高效數據結構,首先我們要明確一個事情,適合的場景一定要對整個系統以及業務有充分的了解,根據這個方式再選擇合適的數據結構。有的時候我們需要在時間復雜度和空間復雜度之間做權衡,什么時候拿空間換時間,什么時候拿時間換空間。另外就是算法,在開發過程當中,一定要明確算法的時間復雜度。由于系統里的需求,你需要提高算法復雜度,這個時候開發人員要和產品人員進行協調溝通。算法復雜度太高時,就要想辦法優化業務,甚至說優化場景。
第四數據存儲,我們依然要提場景的問題。對于一般系統開發來講,一個關系型數據庫基本上就可以滿足業務需求開發了,但實際上如果僅僅通過關系型數據庫來做的話,即使能滿足業務需求也不一定可以滿足性能需求。所以說要熟知你的業務場景,根據業務場景選擇合適的數據存儲。除此之外,還需要了解這些存儲的原理。
性能優化案例
下面分享一下融云做的優化案例,融云系統上線過程當中沒有出現太多的性能問題,實際上我們更多處理的是線上的BUG,或者說由于一些低級失誤產生的故障。
首先***個案例,字典樹在我們優化之后變成了雙數組字典樹,場景主要應用于敏感詞過濾。當時我們字典樹的實現都是以哈希多叉樹來做的,有幾個考慮:***,敏感詞添加過程當中不需要字典樹重建,另外算法復雜度很低。有次通過監控,我們發了線上用于審核的系統出現了一些性能問題,排查后發現有大量用戶錄入了很多業務上的關鍵敏感詞,這時我們將哈希樹調整為了雙數組字典樹,場景我們也做了一些優化,敏感詞讓用戶進行批量添加,防止每次都會重構。另外就是延遲,我們降低了字典樹重構的時間。***,對于審核服務來講,優化效果直接將CPU的使用率降低了30%。
另外一個就是跳表,轉換成環形隊列,場景是做一些消息存儲。消息有一個時間遞增的特性,每個消息都會有一個時間遞增的方式,用于跳表方式來講復雜度很低,同時可以進行定向掃描,但是由于我們需要做內存保護,要對跳表進行流量控制,插入的過程當中需要對老數據進行淘汰,這時就需要一個特別大的鎖把內存鎖住,保證線程安全和防止內存溢出。但由于業務量不斷增大,我們換了一個思路,使用環形隊列,主要底線實現都是以數組的方式組織,同時改變之前對于消息的定位模式。之前是通過一個用戶請求的時間點開始往后獲取***數據,改變模式之后我們通過***的數據往前進行迭代,查到時間點為止,通過這樣的方式整個降低了占用時間,同時針對這塊業務吞吐量大概提高了***。
性能優化案例內存優化篇。這個場景對于key縮短問題,對于系統當中的用戶ID本身來講長度不可控。我們通過一個哈希算法轉變進制,變成64進制,這樣對于超過22個字節的數據進行壓縮,最終優化效果把內存的利用率降低了大概10%。
第二個內存優化主要是LRU緩存優化,如果有大量冷數據訪問到系統中之后,會把熱數據沖掉,這對于系統的吞吐量有很大影響。我們優化的方式是做了一個二級LRU緩存,將冷熱數據按照配比進行隔離,冷數據40%,熱數據60%,這樣系統里熱數據被淘汰的問題便得以緩解了。
性能優化案例。數據狀態的延遲寫入,這個場景中消息里會記錄每個用戶的狀態。如果用戶收了一千條消息,數據就要被寫入一千次,我們通過另外一種模式,消息狀態數據一直是在本地內存當中進行寫入,待多次寫入直到數據不活躍后,我們才將數據寫入真實的存儲里。通過這種優化,將之前的多次數據寫入變成了一次數據寫入。
之前監控數據每天有幾千億次需要存儲和寫入,通過添加緩存區,讓將監控數據傳輸量降低了兩個數量級。
數據存儲。首先對于消息來講,他的寫入和讀取場景是比較特殊,通過自研的存儲引擎,將存儲的設備降低了一半的數據量,同時保證了整個系統的響應速度。另外,調整了數據庫的業務引擎,對于業務數據占用磁盤比較高的問題,優化之后的結果大概只有之前的30%左右,即存儲降低了70%。
系統設計把控
系統設計把控是一個總結性的內容,對于性能優化來講首先應該關注的是系統設計,需要充分理解你的需求以及業務場景,根據業務場景來設計你的整個系統,系統設計完成之后,我們要開始進行架構設計,現在很多人做架構分享,例如現在比較火的微服務。但是這些架構設計大家不要拿過來直接引用,需要充分的消化,通過架構設計帶入系統設計,進行整個架構的演進和迭代。
另外,技術選型需要充分考慮團隊對技術的接受能力,同時一定要對每個你所選東西的原理有充分認識,這樣的話才能做出一個比較好的選擇。
***是程序實現,是在開發過程當中要不停進行迭代、改進和分享。技術沒有好壞之分,只有適合你的場景才是***的。謝謝大家!