新用戶登錄后自動(dòng)創(chuàng)建賬號
登錄概述
互聯(lián)網(wǎng)公司同質(zhì)應(yīng)用服務(wù)競爭日益激烈,業(yè)務(wù)部門亟需利用線上實(shí)時(shí)反饋數(shù)據(jù)輔助決策支持以提高服務(wù)水平。Alluxio(前Tachyon)作為一個(gè)以內(nèi)存為中心的虛擬分布式存儲(chǔ)系統(tǒng),在大數(shù)據(jù)系統(tǒng)性能提升以及生態(tài)系統(tǒng)多組件整合的進(jìn)程中扮演著重要角色。本文將介紹去哪兒網(wǎng)(Qunar)的一個(gè)基于Alluxio的實(shí)時(shí)日志流的處理系統(tǒng),Alluxio在此系統(tǒng)中重點(diǎn)解決了異地?cái)?shù)據(jù)存儲(chǔ)和訪問慢的問題,從而將生產(chǎn)環(huán)境中整個(gè)流處理流水線的性能總體提高了近10倍,而峰值時(shí)甚至達(dá)到300倍左右。
目前,去哪兒網(wǎng)的流處理流水線每天需要處理的業(yè)務(wù)日志量大約60億條,總計(jì)約4.5TB的數(shù)據(jù)量。其中許多任務(wù)都需要保證在穩(wěn)定的低延時(shí)情況下工作,快速迭代計(jì)算出結(jié)果并反饋到線上業(yè)務(wù)系統(tǒng)中。例如,無線應(yīng)用的用戶點(diǎn)擊、搜索等行為產(chǎn)生的日志,會(huì)被實(shí)時(shí)抓取并寫入到流水線中分析出對應(yīng)的推薦信息,然后反饋給業(yè)務(wù)系統(tǒng)并展示在應(yīng)用中。如何保證數(shù)據(jù)的可靠性以及低延時(shí),就成了整個(gè)系統(tǒng)開發(fā)和運(yùn)維工作中的重中之重。
Alluxio大數(shù)據(jù)存儲(chǔ)系統(tǒng)源自于UC Berkeley AMPLab,目前由Alluxio公司在開源社區(qū)主導(dǎo)開發(fā)。它是世界上第一個(gè)以內(nèi)存為中心的虛擬的分布式存儲(chǔ)系統(tǒng),并將多樣化的上層計(jì)算框架和底層存儲(chǔ)系統(tǒng)連接起來,統(tǒng)一數(shù)據(jù)訪問方式。Alluxio以內(nèi)存為中心的存儲(chǔ)特性使得上層應(yīng)用的數(shù)據(jù)訪問速度比現(xiàn)有常規(guī)方案快幾個(gè)數(shù)量級。此外,Alluxio提供的層次化存儲(chǔ)、統(tǒng)一命名空間、世系關(guān)系、靈活的文件API、網(wǎng)頁UI以及命令行工具等特性也方便了用戶在不同實(shí)際應(yīng)用場景下的使用。在本文中,我們將結(jié)合具體案例做進(jìn)一步地闡述。
在我們的案例中,整個(gè)流處理計(jì)算系統(tǒng)部署在一個(gè)物理集群上,Mesos負(fù)責(zé)資源的管理和分配,Spark Streaming和Flink是主要的流計(jì)算引擎;存儲(chǔ)系統(tǒng)HDFS位于另外一個(gè)遠(yuǎn)端機(jī)房,用于備份存儲(chǔ)整個(gè)公司的日志信息;Alluxio則是作為核心存儲(chǔ)層,與計(jì)算系統(tǒng)部署在一起。業(yè)務(wù)流水線每天會(huì)產(chǎn)生4.5TB左右的數(shù)據(jù)寫入存儲(chǔ)層,同時(shí)通過Kafka消費(fèi)大約60億條日志與存儲(chǔ)層中的數(shù)據(jù)進(jìn)行碰撞分析。Alluxio對整個(gè)流處理系統(tǒng)帶來的價(jià)值主要包括:
利用Alluxio的分層存儲(chǔ)特性,綜合使用了內(nèi)存、SSD和磁盤多種存儲(chǔ)資源。通過Alluxio提供的LRU、LFU等緩存策略可以保證熱數(shù)據(jù)一直保留在內(nèi)存中,冷數(shù)據(jù)則被持久化到level 2甚至level 3的存儲(chǔ)設(shè)備上;而HDFS作為長期的文件備份系統(tǒng)。
利用Alluxio支持多個(gè)計(jì)算框架的特性,通過Alluxio實(shí)現(xiàn)Spark以及Zeppelin等計(jì)算框架之間的數(shù)據(jù)共享,并且達(dá)到內(nèi)存級的文件傳輸速率;此外,我們計(jì)劃將Flink和Presto業(yè)務(wù)遷移到Alluxio上。
利用Alluxio的統(tǒng)一命名空間特性,便捷地管理遠(yuǎn)程的HDFS底層存儲(chǔ)系統(tǒng),并向上層提供統(tǒng)一的命名空間,計(jì)算框架和應(yīng)用能夠通過Alluxio統(tǒng)一訪問不同的數(shù)據(jù)源的數(shù)據(jù);
利用Alluxio提供的多種易于使用的API,降低了用戶的學(xué)習(xí)成本,方便將原先的整個(gè)系統(tǒng)遷移至Alluxio,同時(shí)也使得調(diào)整的驗(yàn)證過程變得輕松許多;
利用Alluxio解決了原有系統(tǒng)中“Spark任務(wù)無法完成”的問題:原系統(tǒng)中當(dāng)某個(gè)Spark executor失敗退出后,會(huì)被Mesos重新調(diào)度到集群的任何一個(gè)節(jié)點(diǎn)上,即使設(shè)置了保留上下文,也會(huì)因?yàn)閑xecutor的“漂泊”而導(dǎo)致任務(wù)無法完成。新系統(tǒng)中Alluxio將數(shù)據(jù)的計(jì)算與存儲(chǔ)隔離開來,計(jì)算數(shù)據(jù)不會(huì)因executor的“漂泊”而丟失,從而解決了這一問題。
本文剩余部分將詳細(xì)對比分析Qunar原有流處理系統(tǒng)以及引入Alluxio改進(jìn)后的流處理系統(tǒng),最后簡述我們下一步的規(guī)劃和對Alluxio未來方向的期待。
原有系統(tǒng)架構(gòu)以及相關(guān)問題分析
我們的實(shí)時(shí)流處理系統(tǒng)選擇了Mesos作為基礎(chǔ)架構(gòu)層(Infrastructure Layer)。在原先的系統(tǒng)中,其余組件都運(yùn)行在Mesos之上,包括Spark、Flink、Logstash以及Kibana等。其中主要用于流式計(jì)算的組件為Spark Streaming,在運(yùn)行時(shí)Spark Streaming向Mesos申請資源,成為一個(gè)Mesos Framework,并通過Mesos調(diào)度任務(wù)。
如上圖所示,在該流處理系統(tǒng)中,待處理的日志數(shù)據(jù)來自于多個(gè)數(shù)據(jù)源,由Kafka進(jìn)行匯總,數(shù)據(jù)流在經(jīng)過了Logstash集群清洗后再次寫入Kafka暫存,后續(xù)由Spark Streaming和Flink等流式計(jì)算框架消費(fèi)這些數(shù)據(jù),計(jì)算的結(jié)果寫入HDFS。在原先的數(shù)據(jù)處理過程中,主要存在著以下性能瓶頸:
用于存放輸入和輸出數(shù)據(jù)的HDFS位于一個(gè)遠(yuǎn)程存儲(chǔ)集群中(物理位置上位于另一個(gè)機(jī)房)。本地計(jì)算集群與遠(yuǎn)程存儲(chǔ)集群存在較高的網(wǎng)絡(luò)延遲,頻繁的遠(yuǎn)程數(shù)據(jù)交換成為整個(gè)流處理過程的一大瓶頸;
HDFS的設(shè)計(jì)是基于磁盤的,其I/O性能,尤其是寫數(shù)據(jù)性能難以滿足流式計(jì)算所要求的延時(shí);Spark Streaming在進(jìn)行計(jì)算時(shí),每個(gè)Spark executor都要從HDFS中讀取數(shù)據(jù),重復(fù)的跨機(jī)房讀文件操作進(jìn)一步地的拖慢了流式計(jì)算的整體效率;
由于Spark Streaming被部署在Mesos之上,當(dāng)某個(gè)executor失效時(shí),Mesos可能會(huì)在另一個(gè)節(jié)點(diǎn)重啟這個(gè)executor,但是之前失效節(jié)點(diǎn)的checkpoint信息不能再被重復(fù)利用,計(jì)算任務(wù)無法順利完成。而即便executor被重啟在同一節(jié)點(diǎn)上,任務(wù)可以完成時(shí),完成的速度也無法滿足流式計(jì)算的要求。
在Spark Streaming中,若使用MEMORY_ONLY方式管理數(shù)據(jù)塊,則會(huì)有大量甚至重復(fù)的數(shù)據(jù)位于Spark executor的JVM中,不僅增大了GC開銷,還可能導(dǎo)致內(nèi)存溢出;而如果采用MEMORY_TO_DISK或者DISK_ONLY的方式,則整體的流處理速度會(huì)受限于緩慢的磁盤I/O。
改進(jìn)后的系統(tǒng)架構(gòu)及解決方案
在引入Alluxio之后,我們很好地解決上述問題。在新的系統(tǒng)架構(gòu)中,整個(gè)流式處理的邏輯基本不變。唯一變化的地方在于使用Alluxio代替原先的HDFS作為核心存儲(chǔ)系統(tǒng),而將原來的HDFS作為Alluxio的底層存儲(chǔ)系統(tǒng),用于備份。Alluxio同樣運(yùn)行在Mesos之上,各個(gè)計(jì)算框架和應(yīng)用都通過Alluxio進(jìn)行數(shù)據(jù)交換,由Alluxio提供高速的數(shù)據(jù)訪問服務(wù)并維護(hù)數(shù)據(jù)的可靠性,僅將最終輸出結(jié)果備份至遠(yuǎn)程HDFS存儲(chǔ)集群中。
在新的系統(tǒng)架構(gòu)中,最初的輸入數(shù)據(jù)仍然經(jīng)過Kafka過濾,交由Spark Streaming消費(fèi),不同的是,Spark Streaming在計(jì)算時(shí)產(chǎn)生的大量中間結(jié)果以及最終的輸出都存放在Alluxio中,避免與較慢的遠(yuǎn)程HDFS集群進(jìn)行交互,同時(shí),存放在Alluxio中的數(shù)據(jù)也能夠很方便地與上層組件,如Flink、Zeppelin進(jìn)行共享。在整個(gè)過程中,Alluxio的一些重要特性對整個(gè)流水線的性能提升起到了重要的作用:
支持分層存儲(chǔ)——我們在每個(gè)計(jì)算節(jié)點(diǎn)上都部署了Alluxio Worker,管理了本地的存儲(chǔ)介質(zhì),包括內(nèi)存、SSD和磁盤,構(gòu)成了層次化的存儲(chǔ)層。每個(gè)節(jié)點(diǎn)上流計(jì)算相關(guān)的數(shù)據(jù)會(huì)被盡可能的存放在本地,避免消耗網(wǎng)絡(luò)資源。同時(shí),Alluxio自身提供了LRU、LFU等高效的替換策略,能夠保證熱數(shù)據(jù)位于速度較快的內(nèi)存層中,提高了數(shù)據(jù)訪問速率;即便是冷數(shù)據(jù)也是存放在本地磁盤中,不會(huì)直接輸出到遠(yuǎn)程HDFS存儲(chǔ)集群;
跨計(jì)算框架數(shù)據(jù)共享——在新的系統(tǒng)架構(gòu)中,除了Spark Streaming本身以外,其他組件如Zeppelin等也需要使用Alluxio中存放的數(shù)據(jù)。另外,Spark Streaming和Spark batch job可以通過Alluxio相連并從中讀取或?qū)懭霐?shù)據(jù),來實(shí)現(xiàn)內(nèi)存級別的數(shù)據(jù)傳輸。另外,我們還在將Flink相關(guān)的業(yè)務(wù)與邏輯遷移到Alluxio上,來實(shí)現(xiàn)計(jì)算框架間的高效數(shù)據(jù)共享;
統(tǒng)一命名空間——通過使用Alluxio分層存儲(chǔ)中HDD層,來管理計(jì)算集群本地的持久存儲(chǔ),同時(shí)使用Alluxio的mount功能來管理遠(yuǎn)程的HDFS存儲(chǔ)集群。Alluxio很自然地將HDFS以及Alluxio自身的存儲(chǔ)空間統(tǒng)一管理起來。這些存儲(chǔ)資源對于上層應(yīng)用和計(jì)算框架透明的,只呈現(xiàn)了一個(gè)統(tǒng)一的命名空間,避免了復(fù)雜的輸入輸出邏輯;
簡潔易用的API——Alluxio提供了多套易用的API,它的原生API是一套類似java.io的文件輸入輸出接口,使用其開發(fā)應(yīng)用不需要繁雜的用戶學(xué)習(xí)曲線;Alluxio提供了一套HDFS兼容的接口,即原先以HDFS作為目標(biāo)存儲(chǔ)的應(yīng)用程序能夠直接遷移至Alluxio,應(yīng)用程序僅僅需要將原有的hdfs://替換成alluxio://就能正常工作,遷移的成本幾乎是零。此外,Alluxio的命令行工具以及網(wǎng)頁UI方便了開發(fā)過程中的驗(yàn)證和調(diào)試步驟,縮短了整個(gè)系統(tǒng)的開發(fā)周期。例如我們使用Chronos(一個(gè)Mesos的Framework,用來執(zhí)行定時(shí)任務(wù))在每天的凌晨通過Alluxio loadufs命令提前加載前一天由MapReduce計(jì)算好的數(shù)據(jù)到Alluxio中,以便后續(xù)的操作可以直接讀取這些文件。
Alluxio與Spark有著緊密的結(jié)合,我們在Spark Streaming將主要數(shù)據(jù)存放在Alluxio中而不是Spark executor的JVM中,由于存儲(chǔ)位置同樣是本地內(nèi)存,因此不會(huì)拖慢數(shù)據(jù)處理的性能,反而能夠降低Java GC的開銷。同時(shí),這一做法也避免了因同一節(jié)點(diǎn)上數(shù)據(jù)塊的冗余而造成的內(nèi)存溢出。我們還將SparkSteaming計(jì)算的中間結(jié)果即對RDD的checkpoint存儲(chǔ)在Alluxio上。
通過利用Alluxio眾多特性以及將數(shù)據(jù)從遠(yuǎn)程HDFS存儲(chǔ)集群預(yù)取至本地Alluxio等優(yōu)化方式,整個(gè)流處理流水線中的數(shù)據(jù)交互過程大量轉(zhuǎn)移到本地集群的內(nèi)存中,從而極大地提升了數(shù)據(jù)處理的整體吞吐率,降低了響應(yīng)延時(shí),滿足了流處理的需求。從我們的線上實(shí)時(shí)監(jiān)控的每次micro batch(間隔10分鐘)的監(jiān)控圖中,可以看到平均處理吞吐量從由以前單個(gè)mirco batch周期內(nèi)20至300的eps,提升到較為穩(wěn)定的7800eps,平均的處理時(shí)間從8分鐘左右降低到30至40秒以內(nèi),整個(gè)流處理加速16-300倍。尤其是在網(wǎng)絡(luò)繁忙擁擠時(shí),上百倍的加速效果尤為明顯。
而對Kafka的消費(fèi)指標(biāo)來看,消費(fèi)速度也從以前的200K條消息穩(wěn)定提升到將近1200K。
此外,我們利用Alluxio自帶的metrics組件將監(jiān)控?cái)?shù)據(jù)發(fā)送到graphite,以方便來監(jiān)控Alluxio的JVM以及Alluxio的FileSystem狀態(tài)??梢钥吹紸lluxio Master對Heap內(nèi)存占用率維持在低水平。
同期的文件數(shù)量和操作統(tǒng)計(jì)為下圖所示。
未來展望
本文介紹的優(yōu)化方法主要是針對利用Alluxio來解決異地存儲(chǔ)訪問慢的問題。性能提升的工作是永無止境的,最后我們也總結(jié)了一些未來的工作:
我們線上環(huán)境中目前使用的Alluxio的版本是0.8.2,Spark Streaming計(jì)算的結(jié)果目前只能同步寫入底層存儲(chǔ)系統(tǒng)(在我們的案例中即為HDFS),我們已經(jīng)測試了Alluxio 1.0.1 并準(zhǔn)備上線新版本,得益于Alluxio社區(qū)活躍的開發(fā),新版本的性能在很多方面都有更大的提升。
我們計(jì)劃將Flink的計(jì)算任務(wù)也遷移至Alluxio,同時(shí)我們也在計(jì)劃修改Presto,令其可以同樣享受Alluxio帶來的跨計(jì)算引擎高速數(shù)據(jù)共享的功能;
由于Alluxio能夠很容易于現(xiàn)有存儲(chǔ)系統(tǒng)進(jìn)行整合并提升上層業(yè)務(wù)的性能,因此我們也將推廣Alluxio到更多的業(yè)務(wù)線中,例如用于分析日志數(shù)據(jù)的批處理任務(wù)等。
【號外】以“融合·新生態(tài)”為主題的《執(zhí)惠·2016中國旅游大消費(fèi)創(chuàng)新峰會(huì)》將于6月16日在國家會(huì)議中心舉行,屆時(shí)國內(nèi)旅游、投資、體育、營銷、娛樂、媒體、戶外等近千名各界精英將齊聚一堂,直擊旅游大消費(fèi)產(chǎn)業(yè)前沿,探索廣闊未來,分享最具創(chuàng)新性的產(chǎn)品體驗(yàn),聚合最優(yōu)質(zhì)的投資與營銷資源,積聚能量,共創(chuàng)價(jià)值。歡迎點(diǎn)擊鏈接查看詳情并報(bào)名:http://www.souny.com.cn/activity/new-eco#join
找回密碼
注冊賬號