當前位置:
首頁 > 知識 > 荔枝架構實踐與演進歷程

荔枝架構實踐與演進歷程

黃全,荔枝APP架構師。擁有10年的互聯網開發經驗,對分散式系統、高並發解決方案有著豐富的實踐經驗,在國內知名互聯網企業擔任過資深工程師、系統架構師等職。曾就職於UC瀏覽器、春筍新科技。現任荔枝資深工程師,負責基礎架構的設計與開發,目前專註於分散式系統、微服務、資料庫中間件等技術的研究與探索。2018年10月18日,黃全 受邀參加了由IT168主辦的《SACC 2018第十屆系統架構師大會》,並發表了精彩演講,以下內容根據 SACC大會實錄整理。

荔枝架構實踐與演進歷程

打開今日頭條,查看更多圖片

如果你對聲音互動平台有所了解,那對於荔枝APP一定不會感到陌生!

荔枝,致力於打造聲音處理平台,幫助人們展現自己的聲音才華。荔枝集錄製、編輯、存儲、收聽、分享於一體,依託聲音底層技術積澱,具有聲音節目錄製功能,可在手機內完成錄音、剪輯、音頻上傳和語音直播。

簡單理解,荔枝APP上有很多主播,主播和用戶之間可以通過聲音互動。目前,荔枝APP月均活躍用戶達到好幾千萬,月均活躍主播達到好幾百萬,全球註冊用戶和音頻節目數量都已過億。

那麼,對於有著大用戶量的社交APP來說,荔枝APP的背後架構該如何設計?一個時間軸可以概括整個架構的演進過程。

架構演進時間軸

  • 2013年:單體架構

這個時候的架構是V1.0版,主要特點是APP 直連伺服器,服務端是單體架構。也就是說,一個服務,一個存儲解決所有問題。這種架構看上去簡單、粗暴,好處是快速上線、快速響應市場需求;但劣勢也非常明顯,APP直連伺服器模式在擴展的時候非常不靈活。項目上線後3個月,用戶數突破 100萬,訪問量上漲,伺服器壓力增大。

  • 2014年:垂直架構

到了2014年,荔枝APP的後台架構演進到V2.0版。這一版架構的特點是:支持水平擴展和功能拆分。首先,APP 與 app server 之間加入app代理層,用於分發請求給多台 app server,分攤壓力。其次,對app server 按功能進行拆分,數據操作及業務邏輯部分由後端服務負責,並採用 netty(http) + json 方式進行交互。

雖然,這個時候已經能做到相對快速交互,但是依然存在很多問題。一個是,後端服務水平擴展時,不能動態化;另外,系統間採用 http 交互時,通訊效率較低,並且數據包較大;還有一個問題是,json 解析速度較慢、體積較大。所以,V3.0版採取了一系列措施,重點解決擴展、交互等問題。比如:引入Linux虛擬伺服器集群系統 LVS,採用 TCP 取代 HTTP,通過定製私有協議取代json。

V3.0版使用 LVS 集群解決了分發請求,但是隨著業務的快速發展,人力資源都投入在業務開發上,對第三方產品了解也不夠深入,導致運維成了最大挑戰。所以,後期考慮採用自己開發代理服務來取代 LVS。

V4.0版架構中,我們開發了代理服務,當時使用 VIP 與其他服務連接,取代LVS分發請求。這時候的整體架構依然比較簡單,app server 與後端服務還是單體架構,沒有做業務拆分,雖然能讓後端服務支持水平擴展功能,但需要重啟代理服務。另外,還有一個挑戰是,隨著用戶量、訪問量的持續上漲,系統訪問壓力依然很大。接下來的目標是,app server 與後端服務需要按業務垂直拆分。

演化到V5.0版架構的時候,所有服務已經能夠按業務拆分,可支持水平擴展,整體架構能抗得住一定的訪問壓力。2014年10月,用戶量曾突破 1千萬。但新的問題又來了:一個是服務的配置不能做到熱更;另外,不同業務的後端服務之間產生了交互需求。還有,微服務化已成為主流發展方向。所以,下一個階段的解決方案是,開發配置中心 config server實現配置熱更;採用開發分散式服務框架 lz-RPC,封裝遠程調用功能。

  • 2015年:分散式架構

V6.0版架構開啟了分散式架構新征程,這時候的特點是app server、後端服務、代理層等,都實現了配置熱更,能靈活水平擴展。到2015年9月,用戶量曾突破 5千萬。但是面臨的問題依然很多。比如:mysql、redis 操作的重複代碼太多;mysql、redis 慢操作不能及時報警;各個服務的數據源配置分散,難以管理等。另外,還涉及跨機房數據操作和數據同步問題。而分散式資料庫中間件可以很好地解決這些問題。

  • 2016年:分散式資料庫中間件

從2016年開始,荔枝APP的後台架構走入V7.0版時代。這時,開發團隊自研了分散式資料庫中間件data store服務。data store的特點是:簡單易用,可減少重複代碼。只需要在類上加上註解,就可以實現與資料庫的交互、數據轉換等功能,大大減少了開發的工作量。另外,data store具有自動維護緩存和資料庫表的對應關係、自動維護緩存與資料庫數據的一致性的功能。最重要的是,屏蔽了服務對數據源的管理,便於資料庫的遷移和擴容等操作。

總體來看,V7.0版的最大特點是,已形成一個比較完整的分散式架構。data store 封裝了常見的 mysql、redis 操作,能提供慢操作監控。後期根據業務發展,還引入了 kafka、mongoDB、zookeeper、hbase等多種第三方產品。

隨著應用的增加,V7.0版架構也逐漸暴露出了一些缺陷。一是資源監控、業務監控、分散式跟蹤鏈等功能不完善。另外,隨著訪問量上漲,分散式服務框架的功能也需要進行擴展。

  • ??2017-2018年:監控體系

進入2017年以後,整個架構已趨於完善,重點引入第三方產品,建立監控體系,完善對伺服器資源、業務、跟蹤鏈路等的監控,同時也擴展了分散式服務框架功能。也是從這個時候開始,整個架構迎來了V8.0版。經過完善後,業務監控及基礎監控功能已比較完整,分散式服務框架擴展了介面緩存、熔斷、降級、過載保護等功能。

近兩年踩過的「坑」以及應對措施

1、大主播開直播,訪問量爆漲,影響了其他直播間的直播效果,比如出現卡頓、進入不了直播間、介面超時。舉個例子:李易峰晚上8點在荔枝APP上做直播,那麼從8點前開始,整個系統的訪問量就會比平時要高出很多。有用戶就會出現進入直播間慢、評論出現慢以及其他體驗不好的情況出現。像這樣的問題,應該如何解決呢?第一個方案,也是最簡單的方法,是「隔離」。在 data store 中,針對 redis 存儲開發,按前綴分片的功能,對大主播的直播數據進行隔離,避免影響其他主播的直播效果。

第二個方案是,在高訪問量期間,結合分散式服務框架中開發的熔斷、降級、過載保護等功能,採取對部分非關鍵服務做降級措施,避免伺服器因訪問量過高發生雪崩。

2、在高並發環境下,Mysql 查詢性能成為瓶頸。當數據量呈現爆髮式增長,Mysql 查詢速度變慢。我們對分散式資料庫中間件作了擴展,在操作mysql時,在資料庫上層加入緩存memcached後,大大提高了查詢性能,並且自動維護緩存和資料庫數據的一致性。

3、訪問量上漲,受日誌文件的IO影響,服務出現長GC(stop the world,阻塞業務線程)。類似服務出現長GC的問題,很多互聯網公司都會遇到。在GC的整個回收過程中,會有兩個步驟涉及到IO操作。第一個操作就是寫 perf 文件;第二個是寫 gc log的時候。一台伺服器一般會部署多個服務,這些服務在運行的過程中,會不斷輸出日誌,這時容易出現與其他服務的GC線程發生搶佔IO資源的衝突,而導致GC線程阻塞等待,最終導致整個GC過程耗時較長,影響了服務的響應和穩定。為了解決這些問題,可以採取了兩個方案來解決:第一,不生成 perf 文件,在服務啟動腳本里,加上參數 -XX:+PerfDisableSharedMem就可以了;第二,將 GC日誌保存到內存檔中( tmpfs 或 ramfs ),在服務啟動腳本里加上 -Xloggc:/dev/shm/lz-app-gc.log參數就可以解決了。

4、隨著業務的發展,系統的整體訪問量越來越大,後端服務介面調用耗時越來越長,導致經常超時。經過分析和統計發現,整個平台實際上以「讀多寫少」的場景居多。有沒有一個兼顧全局的解決方案呢?在分散式服務框架中開發「緩存介面」功能,解決了這個問題。其實有很多場景,我們是不需要實時看到最新數據的,即使新數據晚了30秒或者1分鐘用戶才看到,也是可以接受的。

5、系統間非同步消息通知功能不完善。之前,是通過redis來做非同步消息通知,好處是比較輕量化,但是隨著數據量增加,大數據傳輸增多,出現多個消費方需要消費相同消息的時候,redis 就不是很適用了。這時,使用 kafka可以滿足系統間消息通知、大數據量傳輸、多個消費者消費相同消息的場景。

6、當服務框架中的各種功能都比較完善後,卻發現缺少一個報警功能。比如在請求失敗/超時/異常等,如果有監控機制,就可以找到具體的問題點。藉助監控系統,我們可以看到伺服器負載、物理內存、swap、磁碟等信息,也能監控到GC信息的回收時間、次數以及JVM堆信息等,還可以對異常請求進行統計。

7、隨著服務的增多,每個服務都有很多實例,導致整個架構的調用鏈路不清晰,也不能預知整體架構存在的瓶頸。引入skywalking 實現調用鏈跟蹤功能後,能快速定位到線上故障和整個架構的性能瓶頸。

8、主要是更新服務的問題,上線/重啟服務操作很原始,之前都是人工在本地打包,再上傳到伺服器。服務不多的時候還能支撐,但是服務實例數量開始增多的情況下,這種方式就需要改進。荔枝的做法是開發一個自動發布平台,一鍵式操作。另外,就是通過jenkins + gitlab,接入自動發布平台,實現自動打包、一鍵發布。

9、服務發布流程不夠規範。過去的部署流程很簡單,先是在本地測試,測試通過後,打包部署到線上,再觀察服務的運行日誌。但是隨著團隊人員和系統越來越多後,這種做法是不合適的。要想保證整個業務順利上線,必須把服務發布流程規範化。從預發布測試到影響評估,到回滾步驟,再到灰度發布、線上驗證,每一個環節都要標準化。預發布測試包含業務流程測試、新功能測試、SQL 驗證、代碼審查;影響評估包含對業務系統的影響和對交互系統的影響;回滾方案包含回滾步驟和回滾版本號,灰度發布則要按照按流量百分比、按設備類型和按 app 版本號等來操作;線上驗證要做功能回歸測試,以及觀察異常日誌、報警信息等。

10、研發規範不夠標準。一個技術團隊從10幾個人發展到幾百人甚至上千人的時候,規範很重要。為了提高效率,公司制定了各種標準的開發/操作規範,包括客戶端開發規範、服務端開發規範、測試規範、運維規範、mysql、redis、kafka、mongoDB 等的使用規範。

未來對整個架構會有多個優化的目標,例如通過「微服務+容器化」實現服務實例的動態擴容與縮容、Service Mesh架構改造、業務級別的調用鏈跟蹤功能等等。

最後,引用大家常說的一句話:好的系統不是設計出來的,而是演進出來的。未來,荔枝的系統架構會更加完善,在不斷探索中更加精進。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT168企業級 的精彩文章:

是什麼在推動/制約著企業雲存儲市場發展?
夏軍:小米大數據集成架構演化之路

TAG:IT168企業級 |