本篇文章內容來自2016年TOP100summit鬥魚數據平臺部總監吳瑞城的案例分享。
編輯:Cynthia
2017年11月9-12日北京國家會議中心第六屆TOP100summit,留言評論有機會得到免費體驗票。緩存
吳瑞誠:鬥魚數據平臺部總監
曾前後就任於淘寶、一號店。
從0到1搭建公司大數據平臺、平臺規劃和團隊建設。
目前負責鬥魚實時/離線數據處理、個性推薦系統、BI&DW和搜索引擎。
背靠開源生態,應用短平快的方式,支撐起一個億級用戶的在線直播平臺。
致力於數據平臺產品化、智能化、雲化。
對高可用高併發的大數據平臺架構和SOA架構有深刻的理解和實踐。安全
導讀:2016年是直播行業的元年,鬥魚在兩年內發展成爲擁有億級用戶和百萬級主播的直播平臺,快速增加的同時也爲技術帶來了高併發請求和海量數據的挑戰。同時公司系統技術棧多、項目迭代週期快、系統規模呈爆炸式增加。在這種背景下,鬥魚網站的架構平臺該如何進行優化,才能支撐起如此迅猛的業務發展?鬥魚的平臺技術會在哪些方面持續革新?
本文詳解鬥魚技術團隊經過對鬥魚基礎架構平臺的不斷改造與優化,造成當前能支撐千萬級用戶同時在線觀看的架構平臺。適用於但願瞭解直播平臺基礎架構、單體應用的服務化改造、直播平臺在支撐大型賽事活動所作的準備。服務器
1、問題的提出網絡
鬥魚網站2014年上線至今,順應直播行業趨勢的發展,完成對交易系統、會員系統、統一登陸系統、彈幕系統、任務系統的重構,並持續對架構進行優化,針對客戶使用體驗拆分系統、提升研發效率、強化系統穩定性和擴展性。優化主要針對如下三個方向:多線程
● 償還技術債--多語言技術棧交互,臨時方案致使版本過多、邏輯錯綜複雜;
● 系統可擴展性--服務與服務、服務與資源之間解耦;
● 服務化--微服務、服務治理、容器化。架構
2、實踐過程併發
2.1 鬥魚架構平臺總體介紹app
2015年初,鬥魚網站系統架構主要分爲兩大功能模塊:Web站和移動端,這兩大模塊最初是從網站的單個工程中拆分出來的,是一個典型意義上的單體應用,也就是Martin Fowler指的monolithic application,這樣的系統主要有如下問題:框架
● 各個業務模塊錯綜複雜,代碼複用率低,臨時方案和功能開關多,致使代碼可維護性較差;
● 功能開發效率較低,容易踩坑,容易傷士氣;
● 網站健壯性較差。運維
鬥魚去年(2015年)系統架構如圖1所示:
圖1:鬥魚2015年系統架構
這個階段的系統會存在諸多瓶頸,隨着網站用戶量的激增,鬥魚全站的DAU超過2000萬,總體架構的服務化改造刻不容緩。
在原應用層中,剝離業務邏輯,只負責應用的流量接入,具體的業務邏輯將由服務層承擔;在服務層中,按照業務功能,完成會員系統、房間系統、交易系統、個性推薦服務、彈幕系統、禮物系統等多個功能單元服務改造。
這樣就造成了當前的系統架構(圖2):
圖二:鬥魚當前(2016.12)系統架構
在大型活動賽事時,每一個功能單元的邏輯複雜度、承擔的訪問量差異巨大,爲了能扛住活動期間的峯值,須要對各個功能單元進行容量預估和擴容,這樣會直接驗證服務化改造的效果。
2.2 鬥魚配置中心
整個服務化進程中,會須要多個核心的基礎組件,先介紹一個核心組件——咱們最早啓動的配置中心。
在沒有配置中心時的狀態是這樣:
● 配置散落在各工程中,盤根錯節,配置改動成本大;
● Dev、Test、Stg、Prod多套配置;
● 資源環境安全隱患;
● 沒法進行服務降級。
梳理出配置中心的痛點,列出配置中心的基本目標是:
● 統一維護配置,方便新增及更改配置;
● 多套環境配置隔離。
圍繞這個目標,經過兩個版本的迭代,實現瞭如下特性:
● 動態配置 ——自動拉取、手動更新、對象動態重構
● 高可用——MySQL主從、本地加密Snapshot
● 數據源——MySQL、Redis、MongoDB等
● 集羣配置——Kafka、HBase、Zookeeper、ES等
● 配置項可繼承
此外,對於中小公司,安全隱患不容樂觀,因此出於安全策略的考量,還實現了:
● 配置中心祕鑰安全認證
● 配置服務添加IP白名單
● 配置服務訪問頻率
在設計階段,針對已開源的Diamond(淘寶)和Disconf(百度),主要從配置存儲、推拉模型、配置讀寫、容災模式、安全性、配置、數據模型、集羣數據同步方面作了詳細對比,對比發現兩套開源系統涉及技術棧較多、二次開發成本較大,與現有系統集成的風險較大。
加之,配置中心並不複雜,風險可控,而且自研的優點還有人員培養,自身對系統全貌能作到足夠熟悉,後續新增功能特性和平常維護比較駕輕就熟。事實證實,自研的選擇徹底符合設計階段的預期。
配置中心架構如圖3:
圖3:配置中心繫統架構
整個配置中心主要分爲四大部分:
● 配置中心UI:配置項內容維護、配置項權限管理、配置項邏輯關係(繼承);
● 服務層:配置服務接口、安全認證、配置項持久化;
● 存儲層:配置內存經過MySQL主從存儲,中間有經過Redis實現緩存;
● 客戶端:應用本地保存配置snapshot加密文件,提高安全性和可用性,經過配置項MD5比對判斷是否更新,拉取配置後動態更新本地對象實例。
在應用代碼中,只需如下代碼便可集成配置中心:
PropertiesConfigClient configClient = new
PropertiesConfigClient(
live/prod, //配置組
project, //配置所屬工程
config-file, //配置文件
refresh-interval); //更新頻率
configClient.getRequiredInt("data.query.page.size");//需使用配置項
當前,配置中心迭代中的版本主要是抽象資源類型,這樣能夠經過配置中心識別出服務依賴的資源,包括接口、緩存、存儲等,並在此基礎上作服務依賴的全監控。
對於配置項修改後的實時推送特性,拉取模式現階段夠用,暫時尚未改造需求。若是須要新增,能夠集成Zookeeper,經過Zookeeper的事件推送機制,並配合改造配置中心客戶端的接收模式便可實現。
2.3 鬥魚統一日誌監控系統
有了配置中心,能夠以此實現服務的開關和降級。可是在賽事活動期間,除了配置中心,還須要監控系統來識別系統狀態。
爲何須要作統一日誌監控系統?初衷包括:
● 技術語言多樣、臨時方案致使版本過多、邏輯錯綜複雜;
● 服務層級很少,可是量大,接口失敗後如何快速定位;
● 開源組件二次開發能力弱;
● 須要短平快的實現方式。
梳理出了最關心的監控指標,主要包括:
● 接口訪問量監控
● HTTP 500監控
● 接口響應時間監控
● 視頻流監控
● 系統錯誤日誌監控
● 資源層監控
● 服務器性能監控
梳理過程當中,咱們發現:
● 接口訪問量監控、HTTP 500監控、接口響應時間監控、視頻流監控能夠經過Nginx或者Web Server的log取到;
● 系統錯誤日誌監控能經過應用日誌取到;
● 資源層監控和服務器性能監控能夠經過Zabbix監控實現。
方案設計階段,主要對比了如下兩個方案:
● 日誌分段處理方案:在日誌本地按時間區間分段切分日誌文件,經過rsync將分段日誌彙總,解析並作聚合計算,結果導入MySQL或者Redis,日誌內容導入HBase,供查詢定位。
● ELK(Elastic Search+Logstash+Kibana)方案:經過Logstash(日誌收集Agent)tail抽取方式收集日誌,寫到ES(Elastic Search,如下簡稱ES)集羣,而後經過Kibana來查詢日誌。
參與方案設計的同事傾向日誌分段處理方案,主要是對各個組件都較熟悉,每一步均可控。可是考慮到實時性得不到保證,而且開發成本高,因此決定搭測試環境小範圍試用,最後發現ELK絕對神器。
當前監控系統架構圖如圖4:
圖4:監控系統架構圖
從架構圖中能夠看到關於統一日誌監控系統相關的數據流,對於CPU敏感的日誌宿主機,使用Rsyslog做爲Agent來實現日誌收集。而且,在Agent中精簡任務,只作最簡單的日誌抽取。快速寫入到Kafka集羣中。日誌數據從Kafka出來後有兩路去向:一路是經由日誌內容解析,按照ES的index mapping解析日誌,而後寫入ES集羣;一路通過實時計算系統(基於Storm實現),作聚合計算,獲得指定粒度Metric的值,一樣寫入ES,須要在Dashboard中展現的指標會寫入Redis。
基於ELK,經過在基礎中間件中改造AOP日誌的格式,還實現了知足基本功能的全調用鏈監控,具體的AOP日誌格式如圖5:
圖5 AOP日誌格式
這套日誌格式主要是參考Google 的Dapper論文,關鍵是trace_id(全局惟一的方法調用ID,一般特定規則生成的UUID)和span_id(方法調用的層級ID),經過這兩個ID串聯起整個RPC調用鏈。在日誌中記錄RPC相關的全部方法調用信息,包括服務名;方法開始時間和結束時間,用以計算方法耗時;方便定位服務進程的host、pid和服務端口;定位問題時須要的入參。沒有記錄出參的主要緣由是出參過大,而且經過入參中的業務字段,能定位是在哪一級出的問題,現階段夠用。
關於ELK的一些使用經驗主要有:
● ELK vs. TSDB
日誌系統最初Metric存儲是使用的基於OpenTSDB實現的一套存儲展示系統,後來在OpenTSDB的使用中碰到一些問題,例如HBase資源衝突、數據壓縮、區間查詢精度等問題,另外一方面ES的使用足夠省心,後來Metric存儲也逐漸以ES爲主。
● 日誌內容的解析
最開始是在Agent中實現,tail抽取後逐條解析,這樣會大大下降日誌的抽取效率。接入Kafka中間層後,改由使用Logstash從Kafka中讀取並解析,Logstash內部存在CPU效率低的問題,再改用Hangout(攜程開源的Java版Logstash,主要是由於Logstash的CPU效率較低)。當前發現吞吐量仍然不理想,正在改用原生Java多線程和Spark Streaming兩種方式來完成日誌解析。
● Elastic Search日誌集羣使用
鬥魚現有6個ES集羣、120個實例,物理機配置32C/128G/6T*12,日均日誌量約10T,使用CMS的GC策略;堆大小使用官方推薦的32G,適當增長-Xmn大小;對於大物理機採用3實例同機部署;爲提高寫入吞吐量,讀寫分離(配置ES截取呢拓撲);儘可能設置成不分詞,即設置成not_analyzed;設置合理refresh時間間隔,index_refresh_interval;多集羣經過搭建Proxy層來實現統一入口和權限控制。
2.4 大型賽事活動的運維保障
每次大型賽事活動的運維保障,就是一次平臺架構的大考。鬥魚是怎樣作賽事運維保障的呢?
首先,識別出最核心的服務。換言之就是要挑出那些不接受不可用的核心功能,主要包括:
● 直播視頻——鬥魚內容輸出的最核心功能;
● 直播間列表——進入直播視頻的關鍵入口;
● 超管功能——保障內容監管的有效執行;
● 彈幕服務——其餘行業不常見,可是是直播中主要互動形式。本質是消息推進,但不一樣點是須要將用戶發佈的彈幕內容廣播給當前同一直播間的全部觀衆,量級放大N級,須要將流量分發,減輕機房網絡帶寬壓力;
● 交易——這個無需解釋。
其次,針對各個核心功能進行容量評估,評估出須要預留的資源規模,主要包括:
● CDN——下文會單獨列出;
● 緩存——業務功能依賴的各級緩存,包括Nginx緩存、OpenResty的ngx.share.DICT、Redis/Memcached、進程內緩存,儘量兜住用戶請求,不穿透到MySQL;
● 資源隔離——儘可能從物理上隔離;
● 降級——主要是各種開關,基於配置中心的網關開關、Web Server開關、接口開關、緩存開關等;
● 監控——監控賽事期間線上全站和賽事直播間的水位狀態;
● 機房——機房網絡狀態、主從災備機房網絡狀態;
● HTTPS——直播行業第一家實現全站HTTPS,保證終端用戶體驗。
第三,CDN是保障的關鍵支撐,主要包括靜態文件CDN和視頻流CDN,視頻流是本文討論的主要內容。主要包括如下準備內容:
● 接入多家CDN廠商,經過統一入口調度,能夠針對不一樣網絡情況實現流量切換;
● 須要預備多條推拉流線路,保障主播推流和用戶拉流可用;
● 創建CDN-SLA,創建包括視頻卡頓率、首屏時間、視頻延遲等監控指標的CDN質量評估體系;
● 與CDN廠商同步全部賽事信息,開通賽事熱線,作好相應值班安排。
3、效果評價和總結
● 通過一年多架構改造,鬥魚擁有能支撐起千萬級用戶同時在線觀看的能力;
● ELK的版本更新快,須要及時跟進官方大版本,並根據業務特色,不斷進行優化和調整。隨着熟悉程度的不斷加深,會考慮更多的二次開發方案,提高日誌系統的總體吞吐能力和性能;
● 持續跟進開源社區優秀組件的發展,例如Flink、Spark Streaming、Elastic Stack等,因地制宜引入合適技術框架提高系統承載能力;
● 現階段系統服務化的能力仍不健全,在服務治理、服務容量預估、服務擴容方向還有很長的路要走,服務化會持續推動,朝着控制技術債雪球、提高系統可擴展性、系統服務化的方向,持續發力。
更多TOP100案例信息及日程請前往[官網]查閱。包含產品、團隊、架構、運維、大數據、人工智能等多個技術專場,4天時間集中分享2017年最值得學習的100個研發案例實踐。本平臺共送出10張開幕式單天免費體驗票,數量有限,先到先得。
免費體驗票申請入口