大眾點評網(wǎng)平臺架構(gòu)組高級工程師 hadoop 應用案例

大眾點評網(wǎng)平臺架構(gòu)組高級工程師 hadoop 應用案例 - 小草君技術(shù)專欄 - 博客頻道 - CSDN.NET http://blog.csdn.net/ldds_520/article/details/41310511

大數(shù)據(jù) hadoop 應用案例 大眾點評===========================================================大眾點評網(wǎng)從2011年中開始使用Hadoop,并專門建立團隊。Hadoop主分析集群共有60多個節(jié)點、700TB的容量,月運行30多萬個Hadoop Job,還有2個HBase線上集群。作者將講述這各個階段的技術(shù)選擇及改進之路。2011年小規(guī)模試水這一階段的主要工作是建立了一個小的集群,并導入了少量用戶進行測試。為了滿足用戶的需求,我們還調(diào)研了任務調(diào)度系統(tǒng)和數(shù)據(jù)交換系統(tǒng)。
我們使用的版本是當時最新的穩(wěn)定版,Hadoop 0.20.203和Hive 0.7.1。此后經(jīng)歷過多次升級與Bugfix?,F(xiàn)在使用的是Hadoop 1.0.3+自有Patch與Hive 0.9+自有Patch??紤]到人手不足及自己的Patch不多等問題,我們采取的策略是,以Apache的穩(wěn)定版本為基礎(chǔ),盡量將自己的修改提交到社區(qū),并且應用這些還沒有被接受的 Patch。因為現(xiàn)在Hadoop生態(tài)圈中還沒有出現(xiàn)一個類似Red Hat地位的公司,我們也不希望被鎖定在某個特定的發(fā)行版上,更重要的是Apache Jira與Maillist依然是獲取Hadoop相關(guān)知識、解決Hadoop相關(guān)問題最好的地方(Cloudera為CDH建立了私有的Jira,但人氣不足),所以沒有采用Cloudera或者Hortonworks的發(fā)行版。目前我們正對Hadoop 2.1.0進行測試。
在前期,我們團隊的主要工作是ops+solution,現(xiàn)在DBA已接手了很大一部分ops的工作,我們正在轉(zhuǎn)向solution+dev的工作。
我們使用Puppet管理整個集群,用Ganglia和Zabbix做監(jiān)控與報警。
集群搭建好,用戶便開始使用,面臨的第一個問題是需要任務級別的調(diào)度、報警和工作流服務。當用戶的任務出現(xiàn)異常或其他情況時,需要以郵件或者短信的方式通知用戶。而且用戶的任務間可能有復雜的依賴關(guān)系,需要工作流系統(tǒng)來描述任務間的依賴關(guān)系。我們首先將目光投向開源項目Apache Oozie。Oozie是Apache開發(fā)的工作流引擎,以XML的方式描述任務及任務間的依賴,功能強大。但在測試后,發(fā)現(xiàn)Oozie并不是一個很好的選擇。
Oozie采用XML作為任務的配置,特別是對于MapReduce Job,需要在XML里配置Map、Reduce類、輸入輸出路徑、Distributed Cache和各種參數(shù)。在運行時,先由Oozie提交一個Map only的Job,在這個Job的Map里,再拼裝用戶的Job,通過JobClient提交給JobTracker。相對于Java編寫的Job Runner,這種XML的方式缺乏靈活性,而且難以調(diào)試和維 護。先提交一個Job,再由這個Job提交真正Job的設(shè)計,我個人認為相當不優(yōu)雅。
另一個問題在于,公司內(nèi)的很多用戶,希望調(diào)度系統(tǒng)不僅可以調(diào)度Hadoop任務,也可以調(diào)度單機任務,甚至spring容器里的任務,而Oozie并不支持Hadoop集群之外的任務。
所以我們轉(zhuǎn)而自行開發(fā)調(diào)度系統(tǒng)Taurus(https://github.com/dianping/taurus)。Taurus是一個調(diào)度系統(tǒng), 通過時間依賴與任務依賴,觸發(fā)任務的執(zhí)行,并通過任務間的依賴管理將任務組織成工作流;支持Hadoop/Hive Job、Spring容器里的任務及一般性任務的調(diào)度/監(jiān)控。
[hadoop 應用案例" title="大數(shù)據(jù) hadoop 應用案例" style="margin:0px; padding:0px; border:none; list-style:none; vertical-align:middle">
圖1 Taurus的結(jié)構(gòu)圖
圖1是Taurus的結(jié)構(gòu)圖,Taurus的主節(jié)點稱為Master,Web 界面與Master在一起。用戶在Web界面上創(chuàng)建任務后,寫入MySQL做持久化存儲,當Master判斷任務觸發(fā)的條件滿足時,則從MySQL中讀出 任務信息,寫入ZooKeeper;Agent部署在用戶的機器上,觀察ZooKeeper上的變化,獲得任務信息,啟動任務。Taurus在2012年 中上線。
另一個迫切需求是數(shù)據(jù)交換系統(tǒng)。用戶需要將MySQL、MongoDB甚至文件中的數(shù)據(jù)導入到HDFS上進行分析。另外一些用戶要將HDFS中生成的數(shù)據(jù)再導入MySQL作為報表展現(xiàn)或者供在線系統(tǒng)使用。
我們首先調(diào)研了Apache Sqoop,它主要用于HDFS與關(guān)系型數(shù)據(jù)庫間的數(shù)據(jù)傳輸。經(jīng)過測試,發(fā)現(xiàn)Sqoop的主要問題在于數(shù)據(jù)的一致性。Sqoop采用 MapReduce Job進行數(shù)據(jù)庫的插入,而Hadoop自帶Task的重試機制,當一個Task失敗,會自動重啟這個Task。這是一個很好的特性,大大提高了Hadoop的容錯能力,但對于數(shù)據(jù)庫插入操作,卻帶來了麻煩。
考慮有10個Map,每個Map插入十分之一的數(shù)據(jù),如果有一個Map插入到一半時failed,再通過Task rerun執(zhí)行成功,那么fail那次插入的一半數(shù)據(jù)就重復了,這在很多應用場景下是不可接受的。 而且Sqoop不支持MongoDB和MySQL之間的數(shù)據(jù)交換,但公司內(nèi)卻有這需求。最終我們參考淘寶的DataX,于2011年底開始設(shè)計并開發(fā)了Wormhole。之所以采用自行開發(fā)而沒有直接使用DataX主要出于維護上的考慮,而且DataX并未形成良好的社區(qū)。
2012年大規(guī)模應用
2012年,出于成本、穩(wěn)定性與源碼級別維護性的考慮,公司的Data Warehouse系統(tǒng)由商業(yè)的OLAP數(shù)據(jù)庫轉(zhuǎn)向Hadoop/Hive。2012年初,Wormhole開發(fā)完成;之后Taurus也上線部署;大量應用接入到Hadoop平臺上。為了保證數(shù)據(jù)的安全性,我們開啟了Hadoop的Security特性。為了提高數(shù)據(jù)的壓縮率,我們將默認存儲格式替換為RCFile,并開發(fā)了Hive Web供公司內(nèi)部使用。2012年底,我們開始調(diào)研Hbase
hadoop 應用案例" title="大數(shù)據(jù) hadoop 應用案例" style="border: none; max-width: 100%; max-height: 100%; margin: 0px; padding: 0px; list-style: none; vertical-align: middle;">
圖2 Wormhole的結(jié)構(gòu)圖
Wormhole(https://github.com /dianping/wormhole)是一個結(jié)構(gòu)化數(shù)據(jù)傳輸工具,用于解決多種異構(gòu)數(shù)據(jù)源間的數(shù)據(jù)交換,具有高效、易擴展等特點,由Reader、 Storage、Writer三部分組成(如圖2所示)。Reader是個線程池,可以啟動多個Reader線程從數(shù)據(jù)源讀出數(shù)據(jù),寫入Storage。 Writer也是線程池,多線程的Writer不僅用于提高吞吐量,還用于寫入多個目的地。Storage是個雙緩沖隊列,如果使用一讀多寫,則每個目的地都擁有自己的Storage。
當寫入過程出錯時,將自動執(zhí)行用戶配置的Rollback方法,消除錯誤狀態(tài),從而保證數(shù)據(jù)的完整性。通過開發(fā)不同的Reader和Writer插件,如MySQL、MongoDB、Hive、HDFS、SFTP和Salesforce,我們就可以支持多種數(shù)據(jù)源間的數(shù)據(jù)交換。Wormhole在大眾點評內(nèi)部得到了大量使用,獲得了廣泛好評。
隨著越來越多的部門接入Hadoop,特別是數(shù)據(jù)倉庫(DW)部門接入后,我們對數(shù)據(jù)的安全性需求變得更為迫切。而Hadoop默認采用Simple的用戶認證模式,具有很大的安全風險。
默認的Simple認證模式,會在Hadoop的客戶端執(zhí)行whoami命令,并以whoami命令的形式返回結(jié)果,作為訪問Hadoop的用戶名(準確地說,是以whoami的形式返回結(jié)果,作為Hadoop RPC的userGroupInformation參數(shù)發(fā)起RPC Call)。這樣會產(chǎn)生以下三個問題。
(1)User Authentication。假設(shè)有賬號A和賬號B,分別在Host1和Host2上。如果惡意用戶在Host2上建立了一個同名的賬號A,那么通過RPC Call獲得的UGI就和真正的賬號A相同,偽造了賬號A的身份。用這種方式,惡意用戶可以訪問/修改其他用戶的數(shù)據(jù)。
(2)Service Authentication。Hadoop采用主從結(jié)構(gòu),如NameNode-DataNode、JobTracker-Tasktracker。Slave節(jié)點啟動時,主動連接Master節(jié)點。Slave到Master的連接過程,沒有經(jīng)過認證。假設(shè)某個用戶在某臺非Hadoop機器上,錯誤地啟動了一個Slave實例,那么也會連接到Master;Master會為它分配任務/數(shù)據(jù),可能會影響任務的執(zhí)行。
(3)可管理性。任何可以連到Master節(jié)點的機器,都可以請求集群的服務,訪問HDFS,運行Hadoop Job,無法對用戶的訪問進行控制。
從Hadoop 0.20.203開始,社區(qū)開發(fā)了Hadoop Security,實現(xiàn)了基于Kerberos的Authentication。任何訪問Hadoop的用戶,都必須持有KDC(Key Distribution Center)發(fā)布的Ticket或者Keytab File(準確地說,是Ticket Granting Ticket),才能調(diào)用Hadoop的服務。用戶通過密碼,獲取Ticket,Hadoop Client在發(fā)起RPC Call時讀取Ticket的內(nèi)容,使用其中的Principal字段,作為RPC Call的UserGroupInformation參數(shù),解決了問題(1)。Hadoop的任何Daemon進程在啟動時,都需要使用Keytab File做Authentication。因為Keytab File的分發(fā)是由管理員控制的,所以解決了問題(2)。最后,不論是Ticket,還是Keytab File,都由KDC管理/生成,而KDC由管理員控制,解決了問題(3)。
在使用了Hadoop Security之后,只有通過了身份認證的用戶才能訪問Hadoop,大大增強了數(shù)據(jù)的安全性和集群的可管理性。之后我們基于Hadoop Secuirty,與DW部門一起開發(fā)了ACL系統(tǒng),用戶可以自助申請Hive上表的權(quán)限。在申請通過審批工作流之后,就可以訪問了。
JDBC是一種很常用的數(shù)據(jù)訪問接口,Hive自帶了Hive Server,可以接受Hive JDBC Driver的連接。實際 上,Hive JDBC Driver是將JDBC的請求轉(zhuǎn)化為Thrift Call發(fā)給Hive Server,再由Hive Server將Job 啟動起來。但Hive自帶的Hive Server并不支持Security,默認會使用啟動Hive Server的用戶作為Job的owner提交到 Hadoop,造成安全漏洞。因此,我們自己開發(fā)了Hive Server的Security,解決了這個問題。
但在Hive Server的使用過程中,我們發(fā)現(xiàn)Hive Server并不穩(wěn)定,而且存在內(nèi)存泄漏。更嚴重的是由于Hive Server自身的設(shè)計缺陷,不能很好地應對并發(fā)訪問的情況,所以我們現(xiàn)在并不推薦使用Hive JDBC的訪問方式。
社區(qū)后來重新開發(fā)了Hive Server 2,解決了并發(fā)的問題,我們正在對Hive Server 2進行測試。
有一些同事,特別是BI的同事,不熟悉以CLI的方式使用Hive,希望Hive可以有個GUI界面。在上線Hive Server之后,我們調(diào)研了開源的SQL GUI Client——Squirrel,可惜使用Squirrel訪問Hive存在一些問題。
辦公網(wǎng)與線上環(huán)境是隔離的,在辦公機器上運行的Squirrel無法連到線上環(huán)境的Hive Server。
Hive會返回大量的數(shù)據(jù),特別是當用戶對于Hive返回的數(shù)據(jù)量沒有預估的情況下,Squirrel會吃掉大量的內(nèi)存,然后Out of Memory掛掉。
Hive JDBC實現(xiàn)的JDBC不完整,導致Squirrel的GUI中只有一部分功能可用,用戶體驗非常差。

基于以上考慮,我們自己開發(fā)了Hive Web,讓用戶通過瀏覽器就可以使用Hive。Hive Web最初是作為大眾點評第一屆Hackathon的一個項目被開發(fā)出來的,技術(shù)上很簡單,但獲得了良好的反響。現(xiàn)在Hive Web已經(jīng)發(fā)展成了一個RESTful的Service,稱為Polestar(https://github.com/dianping /polestar)。
hadoop 應用案例" style="border: none; max-width: 100%; max-height: 100%; margin: 0px; padding: 0px; list-style: none; vertical-align: middle; float: none;">
圖3 Polestar的結(jié)構(gòu)
圖3是Polestar的結(jié)構(gòu)圖。目前Hive Web只是一個GWT的前端,通過HAProxy將RESTfull Call分發(fā)到執(zhí)行引擎Worker執(zhí)行。Worker將自身的狀態(tài)保存在MySQL,將數(shù)據(jù)保存在HDFS,并使用JSON返回數(shù)據(jù)或數(shù)據(jù)在HDFS的 路徑。我們還將Shark與Hive Web集成到了一起,用戶可以選擇以Hive或者Shark執(zhí)行Query。
一開始我們使用LZO作為存儲格式,使大文件可以在MapReduce處理中被切分,提高并行度。但LZO的壓縮比不夠高,按照我們的測試,Lzo壓縮的文件,壓縮比基本只有Gz的一半。
經(jīng)過調(diào)研,我們將默認存儲格式替換成RCFile,在RCFile內(nèi)部再使用Gz壓縮,這樣既可保持文件可切分的特性,同時又可獲得Gz的高壓縮比,而且因 為RCFile是一種列存儲的格式,所以對于不需要的字段就不用從I/O讀入,從而提高了性能。圖4顯示了將Nginx數(shù)據(jù)分別用Lzo、 RCFile+Gz、RCFfile+Lzo壓縮,再不斷增加Select的Column數(shù),在Hive上消耗的CPU時間(越小越好)。
hadoop 應用案例" style="border: none; max-width: 100%; max-height: 100%; margin: 0px; padding: 0px; list-style: none; vertical-align: middle; float: none;">
圖4 幾種壓縮方式在Hive上消耗的CPU時間
但RCFile的讀寫需要知道數(shù)據(jù)的Schema,而且需要熟悉Hive的Ser/De接口。為了讓MapReduce Job能方便地訪問RCFile,我們使用了Apache Hcatalog。
社區(qū)又針對Hive 0.11開發(fā)了ORCFile,我們正在對ORCFile進行測試。
隨著Facebook、淘寶等大公司成功地在生產(chǎn)環(huán)境應用HBase,HBase越來越受到大家的關(guān)注,我們也開始對HBase進行測試。通過測試我們發(fā)現(xiàn) HBase非常依賴參數(shù)的調(diào)整,在默認配置下,HBase能獲得很好的寫性能,但讀性能不是特別出色。通過調(diào)整HBase的參數(shù),在5臺機器的HBase 集群上,對于1KB大小的數(shù)據(jù),也能獲得5萬左右的TPS。在HBase 0.94之后,HBase已經(jīng)優(yōu)化了默認配置。
原來我們希望HBase集群與主Hadoop集群共享HDFS,這樣可以簡化運維成本。但在測試中,發(fā)現(xiàn)即使主Hadoop集群上沒有任何負載,HBase的性能也很糟糕。我們認為,這是由于大量數(shù)據(jù)屬于遠程讀寫所引起的。所以我們現(xiàn)在的HBase集群都是單獨部署的。并且通過封裝HBase Client與Master-Slave Replication,使用2套HBase集群實現(xiàn)了HBase的HA,用來支撐線上業(yè)務。
2013年持續(xù)演進
在建立了公司主要的大數(shù)據(jù)架構(gòu)后,我們上線了HBase的應用,并引入Spark/Shark以提高Ad Hoc Query的執(zhí)行時間,并調(diào)研分布式日志收集系統(tǒng),來取代手工腳本做日志導入。
現(xiàn)在HBase上線的應用主要有OpenAPI和手機團購推薦。OpenAPI類似于HBase的典型應用Click Stream,將開放平臺開發(fā)者的訪問日志記錄在HBase中,通過Scan操作,查詢開發(fā)者在一段時間內(nèi)的Log,但這一功能目前還沒有對外開放。手機 團購推薦是一個典型的KVDB用法,將用戶的歷史訪問行為記錄在HBase中,當用戶使用手機端訪問時,從HBase獲得用戶的歷史行為數(shù)據(jù),做團購推 薦。
當Hive大規(guī)模使用之后,特別是原來使用OLAP數(shù)據(jù)庫的BI部門的同事轉(zhuǎn)入后,一個越來越大的抱怨就是Hive的執(zhí)行速度。對于離 線的ETL任務,Hadoop/Hive是一個良好的選擇,但動輒分鐘級的響應時間,使得Ad Hoc Query的用戶難以忍受。為了提高Ad Hoc Query的響應時間,我們將目光轉(zhuǎn)向了Spark/Shark。
Spark是美國加州大學伯克利分校AMPLab開發(fā)的分布式計算系統(tǒng),基于RDD(Resilient Distributed Dataset),主要使用內(nèi)存而不是硬盤,可以很好地支持迭代計算。因為是一個基于Memory的系統(tǒng),所以在數(shù)據(jù)量能夠放進Memory的情況下,能 夠大幅縮短響應時間。Shark類似于Hive,將SQL解析為Spark任務,并且Shark復用了大量Hive的已有代碼。
在Shark接入之后,大大降低了Ad Hoc Query的執(zhí)行時間。比如SQL語句:
select host, count(1) from HIPPOLOG where dt = '2013-08-28' group by host order by host desc;

在Hive執(zhí)行的時間是352秒,而Shark只需要60~70秒。但對于Memory中放不下的大數(shù)據(jù)量,Shark反而會變慢。
目前用戶需要在Hive Web中選擇使用Hive還是Shark,未來我們會在Hive中添加Semantic-AnalysisHook,通過解析用戶提交的Query,根據(jù) 數(shù)據(jù)量的大小,自動選擇Hive或者Shark。另外,因為我們目前使用的是Hadoop 1,不支持YARN,所以我們單獨部署了一個小集群用于Shark任務的執(zhí)行。
Wormhole解決了結(jié)構(gòu)化數(shù)據(jù)的交換問題,但對于非結(jié)構(gòu)化數(shù)據(jù),例如各種日志,并不適合。我們一直采用腳本或用戶程序直接寫HDFS的方式將用戶的Log導入HDFS。缺點是,需要一定的開發(fā)和維護成本。我們 希望使用Apache Flume解決這個問題,但在測試了Flume之后,發(fā)現(xiàn)了Flume存在一些問題:Flume不能保證端到端的數(shù)據(jù)完整性,數(shù)據(jù)可能丟失,也可能重復。
例如,F(xiàn)lume的HDFSsink在數(shù)據(jù)寫入/讀出Channel時,都有Transcation的保證。當Transaction失敗時,會回滾,然后重試。但由于HDFS不可修改文件的內(nèi)容,假設(shè)有1萬行數(shù)據(jù)要寫入HDFS,而在寫入5000行時,網(wǎng)絡(luò)出現(xiàn)問題導致寫入失敗,Transaction回滾,然后重寫這10000條記錄成功,就會導致第一次寫入的5000行重復。我們試圖修正Flume的這些問題,但由于這些問題是設(shè)計上的,并不能通過簡單的Bugfix來解決,所以我們轉(zhuǎn)而開發(fā)Blackhole系統(tǒng)將數(shù)據(jù)流導入HDFS。目前Blackhole正在開發(fā)中。
總結(jié)
圖5是各系統(tǒng)總體結(jié)構(gòu)圖,深藍部分為自行開發(fā)的系統(tǒng)。
hadoop 應用案例" title="大數(shù)據(jù) hadoop 應用案例" style="border: none; max-width: 100%; max-height: 100%; margin: 0px; padding: 0px; list-style: none; vertical-align: middle;">
圖5 大眾點評各系統(tǒng)總體結(jié)構(gòu)圖
在這2年多的Hadoop實踐中,我們得到了一些寶貴經(jīng)驗。
建設(shè)一支強大的技術(shù)團隊是至關(guān)重要的。Hadoop的生態(tài)系統(tǒng),還處在快速演化中,而且文檔相當匱乏。只有具備足夠強的技術(shù)實力,才能用好開源軟件,并在開源軟件不能滿足需求時,自行開發(fā)解決問題。
要立足于解決用戶的需求。用戶需要的東西,會很容易被用戶接受,并推廣開來;某些東西技術(shù)上很簡單,但可以解決用戶的大問題。
對用戶的培訓,非常重要。

作者房明,大眾點評網(wǎng)平臺架構(gòu)組高級工程師,Apache Contributor。2011年加入點評網(wǎng),目前負責大數(shù)據(jù)處理的基礎(chǔ)架構(gòu)及所有Hadoop相關(guān)技術(shù)的研發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容