白玉辛,劉曉燕
(昆明理工大學(xué),云南 昆明 650500)
大數(shù)據(jù)的時(shí)代已經(jīng)悄然來(lái)臨,信息技術(shù)發(fā)展上升到了一個(gè)新的歷史階段,影響著社會(huì)生產(chǎn)模式和人們生活的方方面面。我國(guó)高度重視大數(shù)據(jù)技術(shù)的研究和產(chǎn)業(yè)發(fā)展,把大數(shù)據(jù)技術(shù)研究納入國(guó)家戰(zhàn)略發(fā)展的重要項(xiàng)目,以期在“第三次信息化浪潮中”占得先機(jī)、引領(lǐng)市場(chǎng)。近年來(lái),華為公司提出5G概念并將其投入生產(chǎn)實(shí)踐,使得5G 網(wǎng)絡(luò)逐步取代第四代移動(dòng)通信網(wǎng)絡(luò),峰值理論傳輸速度可達(dá)10 Gb/s,比4G 網(wǎng)絡(luò)的傳輸速度快數(shù)百倍??梢?jiàn),大數(shù)據(jù)正在改變著人們的生活、工作和思想[1-2]。
2004 年Google 的3 篇 論 文MapReduce[3]、GFS[4]和BigTable[5]開(kāi)啟了針對(duì)大數(shù)據(jù)問(wèn)題的關(guān)鍵技術(shù)研究。Cutting 等人根據(jù)論文的描述實(shí)現(xiàn)開(kāi)源的MapReduce 計(jì)算框架,將其和NDFS 結(jié)合在一起,使其成為今天熟知的Hadoop,并在2008 年成為Apache軟件基金會(huì)旗下的頂級(jí)項(xiàng)目,命名為Hadoop[6]。
2008 年,柏林理工大學(xué)開(kāi)發(fā)了一套大數(shù)據(jù)處理平臺(tái),此為Flink 的前身。隨后,在2014 年被Apache 孵化器所接受,然后迅速成為阿帕奇基金會(huì)(Apache Software Foundation,ASF)的頂級(jí)項(xiàng)目之一。Flink 是一個(gè)用于分布式數(shù)據(jù)處理的開(kāi)源平臺(tái),可以用于Google 數(shù)據(jù)流模型[7]。它使用戶能夠編寫(xiě)可以分布在多個(gè)工作節(jié)點(diǎn)的程序,使得可以比單個(gè)計(jì)算機(jī)更快地處理大規(guī)模數(shù)據(jù)集。Flink 核心是一個(gè)流式的數(shù)據(jù)流執(zhí)行引擎,提供抽象層的API,以便用戶編寫(xiě)分布式任務(wù)。目前,互聯(lián)網(wǎng)領(lǐng)域的實(shí)時(shí)搜索、數(shù)據(jù)平臺(tái)整合、數(shù)據(jù)分析和機(jī)器學(xué)習(xí)任務(wù)等,都可以在Flink 平臺(tái)上運(yùn)行。
Flink 和MapReduce 相比較具有各種優(yōu)點(diǎn),但Flink 始終是一款大數(shù)據(jù)的計(jì)算框架,與Hadoop 中的MapReduce 具有類似的數(shù)據(jù)處理功能,都是拿來(lái)做數(shù)據(jù)處理的計(jì)算引擎。所以,在數(shù)據(jù)計(jì)算過(guò)程中Hadoop 的分布式文件系統(tǒng)HDFS 不可或缺。Hadoop一開(kāi)始的設(shè)計(jì)思路是為了用戶不用清楚詳細(xì)了解分布式底層細(xì)節(jié)實(shí)現(xiàn)的情況下開(kāi)發(fā)分布式應(yīng)用程序,使用集群開(kāi)發(fā)環(huán)境使運(yùn)算性能最大化,同時(shí)利用分布式文件系統(tǒng)存儲(chǔ)數(shù)據(jù)處理后的結(jié)果,實(shí)現(xiàn)了大規(guī)模的批處理,是一款真正意義上的大數(shù)據(jù)處理平臺(tái)。Flink 支持?jǐn)?shù)據(jù)流中的迭代,一個(gè)特例是Delta Iterations[8]。對(duì)于Delta 迭代的某些計(jì)算,并非每個(gè)迭代步驟都要更新每個(gè)數(shù)據(jù)項(xiàng)。他們?cè)诠ぷ骷徒鉀Q方案集上工作,工作集是推動(dòng)迭代的動(dòng)力。在每個(gè)步驟中,計(jì)算新的工作集并將其反饋到迭代中。Delta Iteration 在工作集為空或達(dá)到最大迭代次數(shù)時(shí)終止。兩者有著不同的實(shí)際應(yīng)用場(chǎng)景。
Hadoop 中的分布式文件系統(tǒng)(Hadoop Distribute File System,HDFS)較好地滿足了大規(guī)模數(shù)據(jù)存儲(chǔ)需求,通過(guò)網(wǎng)絡(luò)實(shí)現(xiàn)文件在多臺(tái)機(jī)器上的分布式存儲(chǔ)。大數(shù)據(jù)時(shí)代需解決大規(guī)模數(shù)據(jù)的高效存儲(chǔ)問(wèn)題,還需要解決大規(guī)模數(shù)據(jù)的高效處理問(wèn)題。Hadoop中的MapReduce 基于分布式并行編程框架,有利于提高程序性能,實(shí)現(xiàn)高效的批量數(shù)據(jù)處理。隨著hadoop 生態(tài)系統(tǒng)其他組件的不斷豐富,為了使hadoop 可以支持更多的應(yīng)用場(chǎng)景,提供更高的可用性,資源管理調(diào)度框架YARN 脫穎而出。以上3 大模塊共同組成了Hadoop 的基礎(chǔ)架構(gòu)。
1.1.1 HDFS
HDFS[9]是基于谷歌文件系統(tǒng)(Google File System,GFS)的開(kāi)源實(shí)現(xiàn),并與MapReduce 計(jì)算框架一起成為Hadoop 的核心組成部分。HDFS 采用“主-從”節(jié)點(diǎn)的理念,使用名稱節(jié)點(diǎn)(namenode)負(fù)責(zé)文件和目錄的創(chuàng)建、刪除和重命名等,同時(shí)管理數(shù)據(jù)節(jié)點(diǎn)和文件塊的映射關(guān)系;使用數(shù)據(jù)節(jié)點(diǎn)(datanode)負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和讀取。HDFS 兼容廉價(jià)的硬件設(shè)備,支持流數(shù)據(jù)讀寫(xiě),可以處理大規(guī)模數(shù)據(jù)集,遵從“一次寫(xiě)入、多次讀取”的理念,同時(shí)支持跨平臺(tái)。HDFS 的基本架構(gòu)以及數(shù)據(jù)讀寫(xiě)流程,如圖1 所示。
1.1.2 MapReduce
大規(guī)模數(shù)據(jù)集的處理包括分布式存儲(chǔ)和分布式計(jì)算兩個(gè)核心環(huán)節(jié)。整個(gè)MapReduce 的思想可以用“分而治之”來(lái)概括??梢詫⒁粋€(gè)大規(guī)模數(shù)據(jù)集切分為許多個(gè)Map 任務(wù)在多臺(tái)機(jī)器上并行執(zhí)行,每個(gè)Map 任務(wù)通常運(yùn)行在數(shù)據(jù)存儲(chǔ)的結(jié)點(diǎn)上。當(dāng)Map 任務(wù)結(jié)束后,會(huì)生成k-v 鍵值對(duì)形式表示中間的結(jié)果,然后這些中間結(jié)果會(huì)被發(fā)送到Reduce 任務(wù)機(jī)器上進(jìn)行匯總得到最后結(jié)果,最后輸出到分布式文件系統(tǒng)。圖2 是MapReduce 的整個(gè)流程。
1.1.3 YARN
為了克服Hadoop1.0 版本的缺陷,重新設(shè)計(jì)了Hadoop2.0 以后版本的體系結(jié)構(gòu),以MapReduce2.0 與另一種資源協(xié)調(diào)者(Yet Another Resource Negotiator,YARN)[10]全新模式進(jìn)行數(shù)據(jù)處理。重新設(shè)計(jì)后的YARN 包 括ResourceManager、ApplicationMaster 和NodeManager。其中,ResourceManager 負(fù)責(zé)資源管理,由ApplicationMaster 負(fù)責(zé)任務(wù)調(diào)度和監(jiān)控,由NodeManager 負(fù)責(zé)執(zhí)行原TaskTracker 的任務(wù)。通過(guò)這種“放權(quán)”設(shè)計(jì),大大降低了JobTracker 的負(fù)擔(dān),提升了系統(tǒng)運(yùn)行的效率和穩(wěn)定性。它的架構(gòu)設(shè)計(jì)思路如圖3 所示。
圖1 HDFS 的架構(gòu)以及數(shù)據(jù)讀寫(xiě)流程
圖2 MapReduce 的整個(gè)流程
圖3 YARN 架構(gòu)設(shè)計(jì)思路
Hadoop 在不斷完善自身核心組件性能的同時(shí),生態(tài)系統(tǒng)也在不斷豐富發(fā)展。為了應(yīng)對(duì)大數(shù)據(jù)時(shí)代不同應(yīng)用場(chǎng)景的數(shù)據(jù)處理,Hadoop 衍生出許多重要的子項(xiàng)目,共同構(gòu)成了Hadoop 生態(tài)系統(tǒng)[11],如表1 所示。
表1 Hadoop 生態(tài)系統(tǒng)
任何類型的數(shù)據(jù)都是作為事件流產(chǎn)生的。信用卡交易、傳感器測(cè)量、機(jī)器日志、網(wǎng)站或移動(dòng)應(yīng)用程序上的用戶交互,所有這些數(shù)據(jù)都以流的形式生成[12]。Apache Flink 正是為處理這些流而設(shè)計(jì)的。首先,Apache Flink 是一個(gè)框架,其分布式的計(jì)算模式使其成為一個(gè)可伸縮的開(kāi)源流處理平臺(tái),用于無(wú)界數(shù)據(jù)集和有界數(shù)據(jù)集進(jìn)行狀態(tài)計(jì)算。核心模塊是一個(gè)數(shù)據(jù)流引擎,主要通過(guò)Java 代碼實(shí)現(xiàn)。對(duì)時(shí)間和狀態(tài)的精確控制,使Flink 運(yùn)行時(shí)無(wú)界流能運(yùn)行任何類型的應(yīng)用程序。有界流由專門固定大小的數(shù)據(jù)集設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)和算法進(jìn)行內(nèi)部處理,從而獲得優(yōu)異的性能。Flink 常被設(shè)計(jì)應(yīng)用于集群環(huán)境中運(yùn)行,以內(nèi)存中的速度和任何規(guī)模執(zhí)行計(jì)算,使得可以比單個(gè)計(jì)算機(jī)更快地處理大規(guī)模數(shù)據(jù)集。Flink 最近提出了本地閉環(huán)迭代操作符[13]和基于成本的自動(dòng)優(yōu)化器,能夠重新排序操作符,并更好地支持流。
Apache Flink 功能強(qiáng)大,支持開(kāi)發(fā)和運(yùn)行多種不同種類的應(yīng)用程序。它的主要特性包括批流一體化、精密的狀態(tài)管理、事件時(shí)間支持以及精確一次的狀態(tài)一致性保障等。Flink 不僅可以運(yùn)行在包括YARN、Mesos、Kubernetes 在內(nèi)的多種資源管理框架上,還支持在裸機(jī)集群上獨(dú)立部署[14]。在啟用高可用選項(xiàng)的情況下,它不存在單點(diǎn)失效問(wèn)題。事實(shí)證明,F(xiàn)link 已經(jīng)可以擴(kuò)展到數(shù)千核心,其狀態(tài)可以達(dá)到TB 級(jí)別,且仍能保持高吞吐、低延遲的特性。世界各地有很多要求嚴(yán)苛的流處理應(yīng)用運(yùn)行在Flink 上。
Flink 提供3 層API。每個(gè)API 在簡(jiǎn)潔性和表達(dá)性之間提供不同的權(quán)衡,并針對(duì)不同的用例。如圖4 所示,層級(jí)越高,代碼越簡(jiǎn)潔,同時(shí)表達(dá)能力越弱,層級(jí)越低。
圖4 Flink 的3 層API 及各接口內(nèi)容
Process Functions 是Flink 提供的最具表現(xiàn)力的功能接口[15]。Flink 提供Process Function 來(lái)處理來(lái)自窗口中分組的一個(gè)或兩個(gè)輸入流或事件的單個(gè)事件。它提供對(duì)時(shí)間和狀態(tài)的細(xì)粒度控制,還可以任意修改其狀態(tài)并注冊(cè)將在未來(lái)觸發(fā)回調(diào)函數(shù)的定時(shí)器。因此,Process Functions 可以根據(jù)許多有狀態(tài)事件驅(qū)動(dòng)的應(yīng)用程序的需要實(shí)現(xiàn)復(fù)雜的事件業(yè)務(wù)邏輯[16]。
數(shù)據(jù)流API 可用于Java 和Scala 和基于功能,如map()、reduce()和aggregate(),可以通過(guò)擴(kuò)展接口或Java 或Scala lambda 函數(shù)來(lái)定義函數(shù)。Flink 具有兩個(gè)關(guān)系A(chǔ)PI、Table API 和SQL。這兩個(gè)API 都是用于批處理和流處理的統(tǒng)一API,即在無(wú)界的實(shí)時(shí)流或有界的記錄流上以相同的語(yǔ)義執(zhí)行查詢,并產(chǎn)生相同的結(jié)果。Table API 和SQL 利用Apache Calcite 進(jìn)行解析、驗(yàn)證和查詢優(yōu)化。它們可以與DataStream 和DataSet API 無(wú)縫集成,并支持用戶定義的標(biāo)量、聚合和表值函數(shù)。
該引擎同樣可以在獨(dú)立Hadoop YARN 或Apache Mesos 集群模式下運(yùn)行,提供了具有不同抽象級(jí)別的API。最低級(jí)API 為有狀態(tài)流處理提供構(gòu)建塊。核心數(shù)據(jù)集(批處理)和DataStream API 位于最常用的位置,且表和SQL API 位于其頂部[17],提供其他庫(kù)以直接支持各種特定上下文。核心API支持Java 和Scala,數(shù)據(jù)集API 還支持Python??梢允褂抿?qū)動(dòng)程序中的循環(huán)或通過(guò)Iterative Stream 或Iterative data集類實(shí)現(xiàn)迭代。前者在技術(shù)上不是迭代,而是驅(qū)動(dòng)程序根據(jù)需要循環(huán)和擴(kuò)展DAG,這是有限的可約性。在DAG 中,單個(gè)節(jié)點(diǎn)可以迭代地執(zhí)行一組轉(zhuǎn)換,使用最后計(jì)算的值或解決方案集狀態(tài)可以在每次迭代中修改。Flink 還主要利用內(nèi)存計(jì)算來(lái)最小化磁盤通信[17]。
為了實(shí)現(xiàn)穩(wěn)健性,它在JVM 中實(shí)現(xiàn)了自己的內(nèi)存管理,嘗試通過(guò)溢出到磁盤來(lái)防止內(nèi)存錯(cuò)誤,減少垃圾回收壓力等。系統(tǒng)不對(duì)鍵值對(duì)進(jìn)行操作,但對(duì)于某些操作員(如分組)需要“虛擬”鍵。它處理任意數(shù)據(jù)類型,并通過(guò)簡(jiǎn)化鍵控(如基于元組索引或?qū)ο髮傩裕樵M和對(duì)象提供額外支持。它的核心API 支持一組轉(zhuǎn)換,這些轉(zhuǎn)換與Apache Spark 的核心API 大致類似。
社區(qū)正在努力支持catalog、schema registries 以及metadata stores,包括API 和SQL 客戶端的支持,并且正在添加數(shù)據(jù)定義語(yǔ)言(Data Definition Language,DDL)支持,以便能方便地添加表和流到catalog中[18]。還有一個(gè)巨大的工作是集成Flink 與Hive 生態(tài)系統(tǒng)。Flink 和Hadoop、Spark 一樣,是Apache軟件基金會(huì)下的頂級(jí)項(xiàng)目,所以Flink 也有屬于自己的生態(tài)系統(tǒng),基本框架如圖5 所示。
圖5 Flink 生態(tài)系統(tǒng)
Flink 框架圖從下到上有部署層、核心層、庫(kù)和API 接口。其中,接口層提供CEP 復(fù)雜事件處理接口,主要是獲取大量流數(shù)據(jù)中的重要信息。Flink和Sprak 一樣,提供一個(gè)機(jī)器學(xué)習(xí)的庫(kù),里面包含許多數(shù)據(jù)挖掘的算法和機(jī)器學(xué)習(xí)的算法,支持向量機(jī)、回歸問(wèn)題、k-means 等一些常用算法。Gelly 庫(kù)里面的函數(shù)用于解決大量圖形計(jì)算。現(xiàn)在主流的大數(shù)據(jù)處理引擎都支持類SQL 語(yǔ)言,Table API 提供流處理及批處理中使用的SQL 語(yǔ)言,將SQL 嵌入Flink,滿足用戶從數(shù)據(jù)庫(kù)中提取數(shù)據(jù)做分析。核心的兩個(gè)接口是DataStream API 和DataSet API。在流處理場(chǎng)景中,使用DataStream API 接口對(duì)數(shù)據(jù)進(jìn)行有狀態(tài)的計(jì)算,最后輸出到本地文件系統(tǒng)或者分布式文件系統(tǒng)HDFS。而DataSet API 接口應(yīng)用于批處理場(chǎng)景中,將批數(shù)據(jù)作為流數(shù)據(jù)的極限特例進(jìn)行數(shù)據(jù)分析。可以將Flink 部署到云,也可以使用單機(jī)模式。
Hadoop 是一個(gè)能夠?qū)Υ罅繑?shù)據(jù)進(jìn)行分布式處理的軟件框架,且是以一種可靠、高效、可伸縮的方式進(jìn)行處理的[19]。MapReduce 是與Flink 相對(duì)應(yīng)的大數(shù)據(jù)編程框架,因此下面將主要闡述MapReduce的技術(shù)優(yōu)勢(shì)。
3.1.1 可讀性
開(kāi)發(fā)者將整個(gè)MapReduce 非常復(fù)雜的并行計(jì)算過(guò)程高度抽象成兩個(gè)函數(shù),一個(gè)是Map 函數(shù),另一個(gè)是Reduce 函數(shù)。整個(gè)框架核的核心設(shè)計(jì)是這兩個(gè)函數(shù),所以極大地降低了分布式并行編程的難度[19]。
3.1.2 可擴(kuò)展性
整個(gè)集群可以動(dòng)態(tài)地隨意增加或者減少相關(guān)的計(jì)算節(jié)點(diǎn),不需要高端的機(jī)器,只需要普通廉價(jià)的PC 機(jī)即可。
3.1.3 高可靠性
采用典型的非共享式架構(gòu),使得在整個(gè)集群中每個(gè)節(jié)點(diǎn)都擁有自己的內(nèi)存。任何一個(gè)節(jié)點(diǎn)出現(xiàn)問(wèn)題,不會(huì)影響到其他節(jié)點(diǎn)正常運(yùn)行。此外,整個(gè)集群設(shè)計(jì)了冗余和容錯(cuò)機(jī)制。
3.2.1 抽象層次低
實(shí)際開(kāi)發(fā)過(guò)程中,許多的業(yè)務(wù)邏輯沒(méi)有辦法從更高層撰寫(xiě)相關(guān)的邏輯代碼,需要去最底層人工進(jìn)行編碼。即使是完成一個(gè)非常簡(jiǎn)單的任務(wù),都需要編寫(xiě)一個(gè)完整的MapReduce 代碼,然后編譯打包運(yùn)行。
3.2.2 表達(dá)能力有限
現(xiàn)實(shí)中一些實(shí)際的問(wèn)題沒(méi)有辦法用Map 和Reduce 兩個(gè)函數(shù)完成相關(guān)任務(wù)。
3.2.3 執(zhí)行迭代操作效率低
對(duì)于MapReduce 來(lái)說(shuō),它本身將整個(gè)作業(yè)劃分成多個(gè)階段進(jìn)行,每一個(gè)階段完成后將結(jié)果寫(xiě)入分布式文件系統(tǒng)HDFS,供下一個(gè)MapReduce 作業(yè)階段調(diào)用。這樣高代價(jià)的磁盤I/O,造成了執(zhí)行迭代操作效率低[20]。
3.2.4 資源浪費(fèi)
整個(gè)任務(wù)執(zhí)行嚴(yán)格劃分階段(Map 階段和Reduce 階段),要求所有的Map 任務(wù)都處理完成后才能開(kāi)始Reduce 任務(wù)階段。這樣Reduce 任務(wù)的結(jié)點(diǎn)一直處于空閑狀態(tài),導(dǎo)致資源的浪費(fèi)。
3.2.5 實(shí)時(shí)性差
MapReduce 計(jì)算框架是針對(duì)批處理設(shè)計(jì)的,因此在實(shí)時(shí)交互查詢應(yīng)用中一般很難實(shí)現(xiàn)。
Flink 以流數(shù)據(jù)處理為核心,借鑒MapReduce計(jì)算框架存在的諸多問(wèn)題,設(shè)計(jì)彌補(bǔ)了MapReduce不能處理實(shí)時(shí)計(jì)算的局限,因此它的優(yōu)勢(shì)極為明顯。
(1)Flink 擅長(zhǎng)處理無(wú)界和有界數(shù)據(jù)集。精確控制時(shí)間和狀態(tài),使Flink 的運(yùn)行能夠在無(wú)界流上運(yùn)行任何類型的應(yīng)用程序[21]。有界流由算法和數(shù)據(jù)結(jié)構(gòu)內(nèi)部處理,這些算法和數(shù)據(jù)結(jié)構(gòu)專為固定大小的數(shù)據(jù)集而設(shè)計(jì),從而擁有出色的性能。
(2)Flink 最明顯的優(yōu)勢(shì)在于充分利用內(nèi)存中的性能,將任務(wù)狀態(tài)始終保留在內(nèi)存中,如果狀態(tài)大小超過(guò)可用內(nèi)存,則保存在訪問(wèn)高效的磁盤上的數(shù)據(jù)結(jié)構(gòu)中。因此,任務(wù)通過(guò)訪問(wèn)本地(通常是內(nèi)存中)狀態(tài)來(lái)執(zhí)行所有計(jì)算,從而產(chǎn)生非常低的處理延遲。Flink 通過(guò)定期和異步地將本地狀態(tài)檢查點(diǎn)持久存儲(chǔ)來(lái)保證出現(xiàn)故障時(shí)一次性狀態(tài)一致性[22]。
(3)Flink 旨在以任何規(guī)模運(yùn)行有狀態(tài)流應(yīng)用程序。應(yīng)用程序并行化為數(shù)千個(gè)在集群中分布和同時(shí)執(zhí)行的任務(wù),因此應(yīng)用程序可以利用幾乎無(wú)限量的CPU、主內(nèi)存、磁盤和網(wǎng)絡(luò)IO。Flink 很容易保持非常大的應(yīng)用程序狀態(tài),其異步和增量檢查點(diǎn)算法可確保對(duì)處理延遲的影響最小,同時(shí)保證一次性狀態(tài)一致性。
(4)Flink 是一個(gè)分布式系統(tǒng),需要計(jì)算資源才能執(zhí)行應(yīng)用程序。Flink 可與所有常見(jiàn)的集群資源管理器(如Hadoop YARN、Apache Mesos 和Kubernetes)集成,也可以設(shè)置為獨(dú)立集群運(yùn)行[23]。Flink 旨在很好地運(yùn)作以前列出的每個(gè)資源管理器。這是通過(guò)特定于資源管理器的部署模式實(shí)現(xiàn)的,這些模式允許Flink 以其慣用方式與每個(gè)資源管理器進(jìn)行交互。
雖然Flink 處理實(shí)時(shí)數(shù)據(jù)的性能要遠(yuǎn)優(yōu)于MapReduce,但大數(shù)據(jù)時(shí)代下很多的處理數(shù)據(jù)場(chǎng)景是將過(guò)去幾年或者過(guò)去幾十年的數(shù)據(jù)從數(shù)據(jù)倉(cāng)庫(kù)中提取出來(lái)做批處理。如果這些數(shù)據(jù)量超過(guò)內(nèi)存大小,F(xiàn)link 將不再適用,這時(shí)使用MapReduce 做數(shù)據(jù)處理更合適。Flink 近幾年才流行起來(lái),目前尚不成熟,是一款大有前途的軟件,因此目前的一些設(shè)計(jì)使得其在適用性方面存在一定的局限性。
從MapReduce 的所有長(zhǎng)處來(lái)看,它基本上是一個(gè)批處理系統(tǒng),并不適合交互式分析,不可能執(zhí)行一條查詢并在幾秒內(nèi)或更短的時(shí)間內(nèi)得到結(jié)果。典型情況下,執(zhí)行查詢需要幾分鐘或者更久。因此,MapReduce 更適合沒(méi)有用戶在現(xiàn)場(chǎng)等待查詢結(jié)果的離線使用場(chǎng)景。然而,從最初的原型到現(xiàn)在,Hadoop 的發(fā)展已經(jīng)超越了批處理本身。實(shí)際上,“Hadoop”一次有時(shí)被用于指代一個(gè)更大的、多個(gè)項(xiàng)目組成的生態(tài)系統(tǒng),而不僅是HDFS 和MapReduce。這些項(xiàng)目都屬于分布式計(jì)算和大規(guī)模數(shù)據(jù)處理范疇。這些項(xiàng)目中許多都是由Apache 軟件基金會(huì)管理。該基金會(huì)為開(kāi)源軟件項(xiàng)目社區(qū)提供支持,所以大多數(shù)應(yīng)用場(chǎng)景都是用Hadoop 中的分布式文件系統(tǒng)HDFS 或者分布式數(shù)據(jù)庫(kù)HBase存儲(chǔ)數(shù)據(jù),用YARN 做集群資源調(diào)度框架,根據(jù)需求使用不同的計(jì)算框架處理數(shù)據(jù)。例如,針對(duì)大規(guī)模數(shù)據(jù)的批量計(jì)算,使用MapReduce、Spark等;針對(duì)流數(shù)據(jù)的實(shí)時(shí)計(jì)算,使用Storm、Flink、S4、Flume、Streams、Puma、DStream、Super、Mario 以及銀河流數(shù)據(jù)處理平臺(tái)等;針對(duì)大規(guī)模圖結(jié)構(gòu)數(shù)據(jù)的處理,使用Pregel、GraphX、Giraph、PowerGraph、Hama 以及GoldenOrb 等;大規(guī)模數(shù)據(jù)的存儲(chǔ)管理和查詢分析,使用Dremel、Hive、Cassandra 以及Impala 等。
Hadoop 設(shè)計(jì)之初以離線處理大批量的數(shù)據(jù)為主,通過(guò)10 年的發(fā)展,其生態(tài)系統(tǒng)技術(shù)不斷完善,使得Hadoop 在大多數(shù)基于大規(guī)模離線數(shù)據(jù)處理場(chǎng)景中得到了廣泛應(yīng)用,主要包括ETL、日志分析、數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)等場(chǎng)景。
4.1.1 ETL
要想使MapReduce 處理得數(shù)據(jù)更加準(zhǔn)確,首先得保證其處理的數(shù)據(jù)不是“臟數(shù)據(jù)”。大型企業(yè)使用數(shù)據(jù)倉(cāng)庫(kù)存放歷史數(shù)據(jù),在實(shí)際開(kāi)發(fā)中這些原始數(shù)據(jù)不能達(dá)到存儲(chǔ)規(guī)范,所以需要對(duì)存入數(shù)據(jù)倉(cāng)庫(kù)數(shù)據(jù)進(jìn)行預(yù)處理,即數(shù)據(jù)的抽取、轉(zhuǎn)換和裝載(Extract-Transform-Load,ETL)[24]。當(dāng)前主流的ETL 抽取方式是基于MapReduce 的并行ETL。由Bala[25]帶頭開(kāi)發(fā)一套與傳統(tǒng)ETL 工具相比性能更好的且基于MapReduce 并行計(jì)算框架的數(shù)據(jù)倉(cāng)庫(kù)ETL 平臺(tái);而Zhang[26]等人實(shí)現(xiàn)了ETL 處理Web頁(yè)面也是基于MapReduce 框架;Li[27]率先將基于MapReduce 思想的ETL 應(yīng)用在種子篩選的生活實(shí)際問(wèn)題上,取得了不錯(cuò)的結(jié)果;Priya[28]的團(tuán)隊(duì)開(kāi)發(fā)了基于MapReduce 的ETL 工具進(jìn)行識(shí)別,成績(jī)斐然??偠灾?,MapReduce 在ETL 場(chǎng)景中優(yōu)勢(shì)明顯。
4.1.2 日志分析
日志分析是大數(shù)據(jù)處理場(chǎng)景中的典型案例之一。2009 年谷歌計(jì)算機(jī)工程師通過(guò)分析海量的用戶查詢?nèi)罩荆瑢?duì)冬季流感的傳播趨勢(shì)進(jìn)行了準(zhǔn)確預(yù)測(cè),其中MapReduce 起著決定性作用。Dewangan 的團(tuán)隊(duì)[29]利用MapReduce 編程模型對(duì)事物日志文件進(jìn)行分析,證明了事物日志系統(tǒng)上應(yīng)用MapReduce計(jì)算的優(yōu)勢(shì)。MaRAOS 是Chen 團(tuán)隊(duì)[30]開(kāi)發(fā)的新框架,框架是Web 日志分析下的離線流數(shù)據(jù)的處理。Xhafa[31]利用MapReduce,通過(guò)對(duì)諸多類型日志的分析,揭示了Hadoop 處理海量日志數(shù)據(jù)的潛力。簡(jiǎn)而言之,日志分析是大數(shù)據(jù)分析不可或缺的部分,充分利用MapReduce 對(duì)離線日志進(jìn)行有效的分析,為企業(yè)決策提供參考。
4.1.3 數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)
因?yàn)镠adoop 是針對(duì)大規(guī)模批量數(shù)據(jù)處理,所以在數(shù)據(jù)挖掘或者是統(tǒng)計(jì)機(jī)器學(xué)習(xí)的應(yīng)用場(chǎng)景下占有一席之地。因?yàn)槊看味家獙⒅虚g結(jié)果寫(xiě)入本地磁盤,所以迭代效率低下。Hadoop 下的機(jī)器學(xué)習(xí)Mahout 組件在Spark 提出了其機(jī)器學(xué)習(xí)算法庫(kù)MLIib 停止更新,所以機(jī)器學(xué)習(xí)的應(yīng)用場(chǎng)景更多使用的是Spark中的MLlib 組件。Flink 中也有自己的機(jī)器學(xué)習(xí)組件FLinkML,所以數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)的場(chǎng)景不建議使用Mahout,建議使用Spark 中的MLib。
4.1.4 數(shù)據(jù)采集與處理場(chǎng)景
MapReduce 能夠有效支持爬蟲(chóng)技術(shù),包括增量爬蟲(chóng)的實(shí)現(xiàn)。所以,Cafarella 的團(tuán)隊(duì)[32]實(shí)現(xiàn)了MapReduce 主要算法對(duì)Nutch 提供計(jì)算支持,成為Nutch 的標(biāo)準(zhǔn)計(jì)算引擎。Li 團(tuán)隊(duì)[33]利用MapReduce框架進(jìn)行網(wǎng)頁(yè)評(píng)分的計(jì)算,得到用戶偏好音樂(lè)的推薦;Zhang 等人[34]通過(guò)收集微博數(shù)據(jù),在Nutch 框架下利用MapRedcue 分析微博站點(diǎn)的特色??梢?jiàn),MapReduce適合應(yīng)用于大規(guī)模數(shù)據(jù)采集的應(yīng)用場(chǎng)景。
Flink 因其豐富的功能集而成為開(kāi)發(fā)和運(yùn)行多種不同類型應(yīng)用程序的絕佳選擇。Flink 的功能包括支持流和批處理、復(fù)雜的狀態(tài)管理、事件時(shí)處理語(yǔ)義以及狀態(tài)的一次性一致性保證[35]。此外,F(xiàn)link可以部署在各種資源提供者(如YARN、Apache Mesos 和Kubernetes)上,也可以作為裸機(jī)硬件上的獨(dú)立群集。配置為高可用性,F(xiàn)link 沒(méi)有單點(diǎn)故障。Flink 已被證明可擴(kuò)展到數(shù)千個(gè)核心和太字節(jié)的應(yīng)用程序狀態(tài),提供高吞吐量和低延遲,并為世界上最苛刻的流處理應(yīng)用程序提供支持。Flink 將數(shù)據(jù)產(chǎn)生當(dāng)做流處理,擅長(zhǎng)處理有界流和無(wú)界流。
4.2.1 流數(shù)據(jù)處理場(chǎng)景
Flink 將流數(shù)據(jù)[36]定義成無(wú)界流。無(wú)界流有一個(gè)開(kāi)始但沒(méi)有定義的結(jié)束。它們不會(huì)在生成時(shí)終止并提供數(shù)據(jù)。必須連續(xù)處理無(wú)界流,即必須在攝取事件后立即處理事件。無(wú)法等待所有輸入數(shù)據(jù)到達(dá),因?yàn)檩斎胧菬o(wú)界的,且在任何時(shí)間點(diǎn)都不會(huì)完成。處理無(wú)界數(shù)據(jù)通常要求以特定順序攝取事件,如事件發(fā)生的順序,以便能夠推斷結(jié)果完整性。Flink 中的DataStream程序是實(shí)現(xiàn)數(shù)據(jù)流轉(zhuǎn)換的常規(guī)程序(如過(guò)濾、更新?tīng)顟B(tài)、定義窗口以及聚合)[37],最初從各種源(如消息隊(duì)列、套接字流、文件)創(chuàng)建數(shù)據(jù)流,結(jié)果通過(guò)接收器返回,接收器可以將數(shù)據(jù)寫(xiě)入文件或標(biāo)準(zhǔn)輸出(如命令行終端)。DataStream 程序可以在各種環(huán)境中運(yùn)行,或獨(dú)立運(yùn)行或嵌入其他程序中[38]。執(zhí)行可以在本地JVM 中執(zhí)行,也可以在許多計(jì)算機(jī)的集群上執(zhí)行。
4.2.2 批數(shù)據(jù)處理場(chǎng)景
Flink 將批數(shù)據(jù)[39]定義成有界流,具有定義的開(kāi)始和結(jié)束。Flink 建立在DataSets(特定類型的元素集合,其上定義了隱式類型參數(shù)的操作)、作業(yè)圖和Con-tracts(PACTs)。作業(yè)圖表示具有任意任務(wù)的并行數(shù)據(jù),消耗和產(chǎn)生數(shù)據(jù)流。PACT 是二階函數(shù),用于定義其相關(guān)用戶定義(一階)函數(shù)(User-Defined Function,UDF)的輸入/輸出數(shù)據(jù)的屬性。這些屬性進(jìn)一步用于并行化UDF 的執(zhí)行并應(yīng)用優(yōu)化規(guī)則[40],可以在執(zhí)行任何計(jì)算前通過(guò)攝取所有數(shù)據(jù)來(lái)處理有界流。處理有界流不需要有序攝取,因?yàn)榭梢允冀K對(duì)有界數(shù)據(jù)集進(jìn)行排序。Flink中的DataSet 程序是實(shí)現(xiàn)數(shù)據(jù)集轉(zhuǎn)換的常規(guī)程序,如過(guò)濾、映射、連接以及分組等。數(shù)據(jù)集最初是從某些來(lái)源創(chuàng)建的,如通過(guò)讀取文件或從本地集合創(chuàng)建,結(jié)果通過(guò)接收器返回,接收器可以將數(shù)據(jù)寫(xiě)入(分布式)文件系統(tǒng)或標(biāo)準(zhǔn)輸出(如命令行終端)。DataSet 程序可以在各種環(huán)境中運(yùn)行,或獨(dú)立運(yùn)行或嵌入其他程序。執(zhí)行可以在本地JVM 中執(zhí)行,也可以在許多計(jì)算機(jī)的集群上執(zhí)行。
4.2.3 數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)
Flink 在2014 年才成為Apache 基金會(huì)的頂級(jí)項(xiàng)目,社區(qū)正在為其開(kāi)發(fā)適合自己的FLinkML 的機(jī)器學(xué)習(xí)組件。所以,F(xiàn)linkML 相對(duì)于Hadoop 中的Mhout 組件和Spark 中MLlib 不是很成熟,在數(shù)據(jù)挖掘、機(jī)器學(xué)習(xí)場(chǎng)景中還是使用成熟的Spark MLlib或者Hadoop 的Mhout 組件。Flink 在Terasort 算法和KMeans 上表現(xiàn)良好,編碼工作量最小,而在更復(fù)雜的MDS 算法上表現(xiàn)不佳[41]。大量的機(jī)器學(xué)習(xí)算法屬于K-Means 和Terabyte 排序復(fù)雜度,并且可以在這些平臺(tái)中有效實(shí)現(xiàn)它們。對(duì)于更復(fù)雜的算法,需要改進(jìn)這些框架以支持算法要求。例如,F(xiàn)link需要高效的通信算法擴(kuò)展需要緊密同步和集體通信的復(fù)雜機(jī)器學(xué)習(xí)算法。目前,F(xiàn)link 主要是做流處理和批處理[42]。
4.2.4 圖計(jì)算
從大類來(lái)看,根據(jù)圖是否有方向,可以將圖分為有向圖(Directed Graph)和無(wú)向圖(Undirected Graph)[43]。Gelly 是Flink 的Graph API[44],包 含一組方法和實(shí)用程序,旨在簡(jiǎn)化Flink 中圖形分析應(yīng)用程序的開(kāi)發(fā)。在Gelly 中,可以使用與批處理API 提供的類似的高級(jí)函數(shù)轉(zhuǎn)換和修改圖形。Gelly 提供了創(chuàng)建、轉(zhuǎn)換和修改圖形的方法以及圖形算法庫(kù)[45]。
針對(duì)以上應(yīng)用場(chǎng)景對(duì)比分析,得出Hadoop 與Flink 并不能適應(yīng)所有的應(yīng)用場(chǎng)景。所以,表2 給出了Hadoop 與Flink 的適用場(chǎng)景總結(jié)。
表2 Hadoop 與Flink 場(chǎng)景適用性總結(jié)
本文從Hadoop 與Flink 的技術(shù)原理及其生態(tài)系統(tǒng)出發(fā),重點(diǎn)分析Flink 與MapReduce 各自適用的應(yīng)用場(chǎng)景特性,通過(guò)對(duì)比分析兩種不能完全適用所有的大數(shù)據(jù)處理應(yīng)用場(chǎng)景。所以,面對(duì)大數(shù)據(jù)環(huán)境下日益增長(zhǎng)的數(shù)據(jù)處理需求,實(shí)際應(yīng)用場(chǎng)景中數(shù)據(jù)處理非常復(fù)雜。為了解決實(shí)際問(wèn)題,需要將Hadoop與Flink 聯(lián)合使用,這是當(dāng)前大數(shù)據(jù)解決方案的發(fā)展趨勢(shì)。