大眾點評網平臺架構組高級工程師 hadoop 應用案例 - 小草君技術專欄 - 博客頻道 - CSDN.NET http://blog.csdn.net/ldds_520/article/details/41310511
大數據 hadoop 應用案例 大眾點評===========================================================大眾點評網從2011年中開始使用Hadoop,并專門建立團隊。Hadoop主分析集群共有60多個節點、700TB的容量,月運行30多萬個Hadoop Job,還有2個HBase線上集群。作者將講述這各個階段的技術選擇及改進之路。2011年小規模試水這一階段的主要工作是建立了一個小的集群,并導入了少量用戶進行測試。為了滿足用戶的需求,我們還調研了任務調度系統和數據交換系統。
我們使用的版本是當時最新的穩定版,Hadoop 0.20.203和Hive 0.7.1。此后經歷過多次升級與Bugfix。現在使用的是Hadoop 1.0.3+自有Patch與Hive 0.9+自有Patch。考慮到人手不足及自己的Patch不多等問題,我們采取的策略是,以Apache的穩定版本為基礎,盡量將自己的修改提交到社區,并且應用這些還沒有被接受的 Patch。因為現在Hadoop生態圈中還沒有出現一個類似Red Hat地位的公司,我們也不希望被鎖定在某個特定的發行版上,更重要的是Apache Jira與Maillist依然是獲取Hadoop相關知識、解決Hadoop相關問題最好的地方(Cloudera為CDH建立了私有的Jira,但人氣不足),所以沒有采用Cloudera或者Hortonworks的發行版。目前我們正對Hadoop 2.1.0進行測試。
在前期,我們團隊的主要工作是ops+solution,現在DBA已接手了很大一部分ops的工作,我們正在轉向solution+dev的工作。
我們使用Puppet管理整個集群,用Ganglia和Zabbix做監控與報警。
集群搭建好,用戶便開始使用,面臨的第一個問題是需要任務級別的調度、報警和工作流服務。當用戶的任務出現異常或其他情況時,需要以郵件或者短信的方式通知用戶。而且用戶的任務間可能有復雜的依賴關系,需要工作流系統來描述任務間的依賴關系。我們首先將目光投向開源項目Apache Oozie。Oozie是Apache開發的工作流引擎,以XML的方式描述任務及任務間的依賴,功能強大。但在測試后,發現Oozie并不是一個很好的選擇。
Oozie采用XML作為任務的配置,特別是對于MapReduce Job,需要在XML里配置Map、Reduce類、輸入輸出路徑、Distributed Cache和各種參數。在運行時,先由Oozie提交一個Map only的Job,在這個Job的Map里,再拼裝用戶的Job,通過JobClient提交給JobTracker。相對于Java編寫的Job Runner,這種XML的方式缺乏靈活性,而且難以調試和維 護。先提交一個Job,再由這個Job提交真正Job的設計,我個人認為相當不優雅。
另一個問題在于,公司內的很多用戶,希望調度系統不僅可以調度Hadoop任務,也可以調度單機任務,甚至spring容器里的任務,而Oozie并不支持Hadoop集群之外的任務。
所以我們轉而自行開發調度系統Taurus(https://github.com/dianping/taurus)。Taurus是一個調度系統, 通過時間依賴與任務依賴,觸發任務的執行,并通過任務間的依賴管理將任務組織成工作流;支持Hadoop/Hive Job、Spring容器里的任務及一般性任務的調度/監控。
[hadoop 應用案例" title="大數據 hadoop 應用案例" style="margin:0px; padding:0px; border:none; list-style:none; vertical-align:middle">
圖1 Taurus的結構圖
圖1是Taurus的結構圖,Taurus的主節點稱為Master,Web 界面與Master在一起。用戶在Web界面上創建任務后,寫入MySQL做持久化存儲,當Master判斷任務觸發的條件滿足時,則從MySQL中讀出 任務信息,寫入ZooKeeper;Agent部署在用戶的機器上,觀察ZooKeeper上的變化,獲得任務信息,啟動任務。Taurus在2012年 中上線。
另一個迫切需求是數據交換系統。用戶需要將MySQL、MongoDB甚至文件中的數據導入到HDFS上進行分析。另外一些用戶要將HDFS中生成的數據再導入MySQL作為報表展現或者供在線系統使用。
我們首先調研了Apache Sqoop,它主要用于HDFS與關系型數據庫間的數據傳輸。經過測試,發現Sqoop的主要問題在于數據的一致性。Sqoop采用 MapReduce Job進行數據庫的插入,而Hadoop自帶Task的重試機制,當一個Task失敗,會自動重啟這個Task。這是一個很好的特性,大大提高了Hadoop的容錯能力,但對于數據庫插入操作,卻帶來了麻煩。
考慮有10個Map,每個Map插入十分之一的數據,如果有一個Map插入到一半時failed,再通過Task rerun執行成功,那么fail那次插入的一半數據就重復了,這在很多應用場景下是不可接受的。 而且Sqoop不支持MongoDB和MySQL之間的數據交換,但公司內卻有這需求。最終我們參考淘寶的DataX,于2011年底開始設計并開發了Wormhole。之所以采用自行開發而沒有直接使用DataX主要出于維護上的考慮,而且DataX并未形成良好的社區。
2012年大規模應用
2012年,出于成本、穩定性與源碼級別維護性的考慮,公司的Data Warehouse系統由商業的OLAP數據庫轉向Hadoop/Hive。2012年初,Wormhole開發完成;之后Taurus也上線部署;大量應用接入到Hadoop平臺上。為了保證數據的安全性,我們開啟了Hadoop的Security特性。為了提高數據的壓縮率,我們將默認存儲格式替換為RCFile,并開發了Hive Web供公司內部使用。2012年底,我們開始調研Hbase。
hadoop 應用案例" title="大數據 hadoop 應用案例" style="border: none; max-width: 100%; max-height: 100%; margin: 0px; padding: 0px; list-style: none; vertical-align: middle;">
圖2 Wormhole的結構圖
Wormhole(https://github.com /dianping/wormhole)是一個結構化數據傳輸工具,用于解決多種異構數據源間的數據交換,具有高效、易擴展等特點,由Reader、 Storage、Writer三部分組成(如圖2所示)。Reader是個線程池,可以啟動多個Reader線程從數據源讀出數據,寫入Storage。 Writer也是線程池,多線程的Writer不僅用于提高吞吐量,還用于寫入多個目的地。Storage是個雙緩沖隊列,如果使用一讀多寫,則每個目的地都擁有自己的Storage。
當寫入過程出錯時,將自動執行用戶配置的Rollback方法,消除錯誤狀態,從而保證數據的完整性。通過開發不同的Reader和Writer插件,如MySQL、MongoDB、Hive、HDFS、SFTP和Salesforce,我們就可以支持多種數據源間的數據交換。Wormhole在大眾點評內部得到了大量使用,獲得了廣泛好評。
隨著越來越多的部門接入Hadoop,特別是數據倉庫(DW)部門接入后,我們對數據的安全性需求變得更為迫切。而Hadoop默認采用Simple的用戶認證模式,具有很大的安全風險。
默認的Simple認證模式,會在Hadoop的客戶端執行whoami命令,并以whoami命令的形式返回結果,作為訪問Hadoop的用戶名(準確地說,是以whoami的形式返回結果,作為Hadoop RPC的userGroupInformation參數發起RPC Call)。這樣會產生以下三個問題。
(1)User Authentication。假設有賬號A和賬號B,分別在Host1和Host2上。如果惡意用戶在Host2上建立了一個同名的賬號A,那么通過RPC Call獲得的UGI就和真正的賬號A相同,偽造了賬號A的身份。用這種方式,惡意用戶可以訪問/修改其他用戶的數據。
(2)Service Authentication。Hadoop采用主從結構,如NameNode-DataNode、JobTracker-Tasktracker。Slave節點啟動時,主動連接Master節點。Slave到Master的連接過程,沒有經過認證。假設某個用戶在某臺非Hadoop機器上,錯誤地啟動了一個Slave實例,那么也會連接到Master;Master會為它分配任務/數據,可能會影響任務的執行。
(3)可管理性。任何可以連到Master節點的機器,都可以請求集群的服務,訪問HDFS,運行Hadoop Job,無法對用戶的訪問進行控制。
從Hadoop 0.20.203開始,社區開發了Hadoop Security,實現了基于Kerberos的Authentication。任何訪問Hadoop的用戶,都必須持有KDC(Key Distribution Center)發布的Ticket或者Keytab File(準確地說,是Ticket Granting Ticket),才能調用Hadoop的服務。用戶通過密碼,獲取Ticket,Hadoop Client在發起RPC Call時讀取Ticket的內容,使用其中的Principal字段,作為RPC Call的UserGroupInformation參數,解決了問題(1)。Hadoop的任何Daemon進程在啟動時,都需要使用Keytab File做Authentication。因為Keytab File的分發是由管理員控制的,所以解決了問題(2)。最后,不論是Ticket,還是Keytab File,都由KDC管理/生成,而KDC由管理員控制,解決了問題(3)。
在使用了Hadoop Security之后,只有通過了身份認證的用戶才能訪問Hadoop,大大增強了數據的安全性和集群的可管理性。之后我們基于Hadoop Secuirty,與DW部門一起開發了ACL系統,用戶可以自助申請Hive上表的權限。在申請通過審批工作流之后,就可以訪問了。
JDBC是一種很常用的數據訪問接口,Hive自帶了Hive Server,可以接受Hive JDBC Driver的連接。實際 上,Hive JDBC Driver是將JDBC的請求轉化為Thrift Call發給Hive Server,再由Hive Server將Job 啟動起來。但Hive自帶的Hive Server并不支持Security,默認會使用啟動Hive Server的用戶作為Job的owner提交到 Hadoop,造成安全漏洞。因此,我們自己開發了Hive Server的Security,解決了這個問題。
但在Hive Server的使用過程中,我們發現Hive Server并不穩定,而且存在內存泄漏。更嚴重的是由于Hive Server自身的設計缺陷,不能很好地應對并發訪問的情況,所以我們現在并不推薦使用Hive JDBC的訪問方式。
社區后來重新開發了Hive Server 2,解決了并發的問題,我們正在對Hive Server 2進行測試。
有一些同事,特別是BI的同事,不熟悉以CLI的方式使用Hive,希望Hive可以有個GUI界面。在上線Hive Server之后,我們調研了開源的SQL GUI Client——Squirrel,可惜使用Squirrel訪問Hive存在一些問題。
辦公網與線上環境是隔離的,在辦公機器上運行的Squirrel無法連到線上環境的Hive Server。
Hive會返回大量的數據,特別是當用戶對于Hive返回的數據量沒有預估的情況下,Squirrel會吃掉大量的內存,然后Out of Memory掛掉。
Hive JDBC實現的JDBC不完整,導致Squirrel的GUI中只有一部分功能可用,用戶體驗非常差。
基于以上考慮,我們自己開發了Hive Web,讓用戶通過瀏覽器就可以使用Hive。Hive Web最初是作為大眾點評第一屆Hackathon的一個項目被開發出來的,技術上很簡單,但獲得了良好的反響。現在Hive Web已經發展成了一個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的結構
圖3是Polestar的結構圖。目前Hive Web只是一個GWT的前端,通過HAProxy將RESTfull Call分發到執行引擎Worker執行。Worker將自身的狀態保存在MySQL,將數據保存在HDFS,并使用JSON返回數據或數據在HDFS的 路徑。我們還將Shark與Hive Web集成到了一起,用戶可以選擇以Hive或者Shark執行Query。
一開始我們使用LZO作為存儲格式,使大文件可以在MapReduce處理中被切分,提高并行度。但LZO的壓縮比不夠高,按照我們的測試,Lzo壓縮的文件,壓縮比基本只有Gz的一半。
經過調研,我們將默認存儲格式替換成RCFile,在RCFile內部再使用Gz壓縮,這樣既可保持文件可切分的特性,同時又可獲得Gz的高壓縮比,而且因 為RCFile是一種列存儲的格式,所以對于不需要的字段就不用從I/O讀入,從而提高了性能。圖4顯示了將Nginx數據分別用Lzo、 RCFile+Gz、RCFfile+Lzo壓縮,再不斷增加Select的Column數,在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的讀寫需要知道數據的Schema,而且需要熟悉Hive的Ser/De接口。為了讓MapReduce Job能方便地訪問RCFile,我們使用了Apache Hcatalog。
社區又針對Hive 0.11開發了ORCFile,我們正在對ORCFile進行測試。
隨著Facebook、淘寶等大公司成功地在生產環境應用HBase,HBase越來越受到大家的關注,我們也開始對HBase進行測試。通過測試我們發現 HBase非常依賴參數的調整,在默認配置下,HBase能獲得很好的寫性能,但讀性能不是特別出色。通過調整HBase的參數,在5臺機器的HBase 集群上,對于1KB大小的數據,也能獲得5萬左右的TPS。在HBase 0.94之后,HBase已經優化了默認配置。
原來我們希望HBase集群與主Hadoop集群共享HDFS,這樣可以簡化運維成本。但在測試中,發現即使主Hadoop集群上沒有任何負載,HBase的性能也很糟糕。我們認為,這是由于大量數據屬于遠程讀寫所引起的。所以我們現在的HBase集群都是單獨部署的。并且通過封裝HBase Client與Master-Slave Replication,使用2套HBase集群實現了HBase的HA,用來支撐線上業務。
2013年持續演進
在建立了公司主要的大數據架構后,我們上線了HBase的應用,并引入Spark/Shark以提高Ad Hoc Query的執行時間,并調研分布式日志收集系統,來取代手工腳本做日志導入。
現在HBase上線的應用主要有OpenAPI和手機團購推薦。OpenAPI類似于HBase的典型應用Click Stream,將開放平臺開發者的訪問日志記錄在HBase中,通過Scan操作,查詢開發者在一段時間內的Log,但這一功能目前還沒有對外開放。手機 團購推薦是一個典型的KVDB用法,將用戶的歷史訪問行為記錄在HBase中,當用戶使用手機端訪問時,從HBase獲得用戶的歷史行為數據,做團購推 薦。
當Hive大規模使用之后,特別是原來使用OLAP數據庫的BI部門的同事轉入后,一個越來越大的抱怨就是Hive的執行速度。對于離 線的ETL任務,Hadoop/Hive是一個良好的選擇,但動輒分鐘級的響應時間,使得Ad Hoc Query的用戶難以忍受。為了提高Ad Hoc Query的響應時間,我們將目光轉向了Spark/Shark。
Spark是美國加州大學伯克利分校AMPLab開發的分布式計算系統,基于RDD(Resilient Distributed Dataset),主要使用內存而不是硬盤,可以很好地支持迭代計算。因為是一個基于Memory的系統,所以在數據量能夠放進Memory的情況下,能 夠大幅縮短響應時間。Shark類似于Hive,將SQL解析為Spark任務,并且Shark復用了大量Hive的已有代碼。
在Shark接入之后,大大降低了Ad Hoc Query的執行時間。比如SQL語句:
select host, count(1) from HIPPOLOG where dt = '2013-08-28' group by host order by host desc;
在Hive執行的時間是352秒,而Shark只需要60~70秒。但對于Memory中放不下的大數據量,Shark反而會變慢。
目前用戶需要在Hive Web中選擇使用Hive還是Shark,未來我們會在Hive中添加Semantic-AnalysisHook,通過解析用戶提交的Query,根據 數據量的大小,自動選擇Hive或者Shark。另外,因為我們目前使用的是Hadoop 1,不支持YARN,所以我們單獨部署了一個小集群用于Shark任務的執行。
Wormhole解決了結構化數據的交換問題,但對于非結構化數據,例如各種日志,并不適合。我們一直采用腳本或用戶程序直接寫HDFS的方式將用戶的Log導入HDFS。缺點是,需要一定的開發和維護成本。我們 希望使用Apache Flume解決這個問題,但在測試了Flume之后,發現了Flume存在一些問題:Flume不能保證端到端的數據完整性,數據可能丟失,也可能重復。
例如,Flume的HDFSsink在數據寫入/讀出Channel時,都有Transcation的保證。當Transaction失敗時,會回滾,然后重試。但由于HDFS不可修改文件的內容,假設有1萬行數據要寫入HDFS,而在寫入5000行時,網絡出現問題導致寫入失敗,Transaction回滾,然后重寫這10000條記錄成功,就會導致第一次寫入的5000行重復。我們試圖修正Flume的這些問題,但由于這些問題是設計上的,并不能通過簡單的Bugfix來解決,所以我們轉而開發Blackhole系統將數據流導入HDFS。目前Blackhole正在開發中。
總結
圖5是各系統總體結構圖,深藍部分為自行開發的系統。
hadoop 應用案例" title="大數據 hadoop 應用案例" style="border: none; max-width: 100%; max-height: 100%; margin: 0px; padding: 0px; list-style: none; vertical-align: middle;">
圖5 大眾點評各系統總體結構圖
在這2年多的Hadoop實踐中,我們得到了一些寶貴經驗。
建設一支強大的技術團隊是至關重要的。Hadoop的生態系統,還處在快速演化中,而且文檔相當匱乏。只有具備足夠強的技術實力,才能用好開源軟件,并在開源軟件不能滿足需求時,自行開發解決問題。
要立足于解決用戶的需求。用戶需要的東西,會很容易被用戶接受,并推廣開來;某些東西技術上很簡單,但可以解決用戶的大問題。
對用戶的培訓,非常重要。
作者房明,大眾點評網平臺架構組高級工程師,Apache Contributor。2011年加入點評網,目前負責大數據處理的基礎架構及所有Hadoop相關技術的研發。