大數(shù)據(jù)時(shí)代給傳統(tǒng)數(shù)據(jù)倉(cāng)庫(kù)架構(gòu)帶來(lái)了一系列的沖擊和挑戰(zhàn),僅從源數(shù)據(jù)采集和存儲(chǔ)層面,就讓倉(cāng)儲(chǔ)的構(gòu)建者不得不重新認(rèn)真地思考:數(shù)據(jù)在哪里?這個(gè)問(wèn)題的答案改寫(xiě)了企業(yè)數(shù)據(jù)倉(cāng)庫(kù)對(duì)數(shù)據(jù)源的既有定義,同時(shí)也傳遞了兩方面的焦慮,一是數(shù)據(jù)規(guī)模急速增長(zhǎng),現(xiàn)有的單節(jié)點(diǎn)或者共享磁盤(pán)架構(gòu)能否適應(yīng)海量數(shù)據(jù)的存儲(chǔ);二是數(shù)據(jù)結(jié)構(gòu)復(fù)雜多樣,現(xiàn)有的基于結(jié)構(gòu)化數(shù)據(jù)為主體的存儲(chǔ)方案能否兼容無(wú)模式的非結(jié)構(gòu)化數(shù)據(jù)。
面對(duì)企業(yè)大數(shù)據(jù)的挑戰(zhàn),用友華表作為一家提供商業(yè)分析產(chǎn)品的供應(yīng)商,在技術(shù)上我們將如何解決大數(shù)據(jù)的問(wèn)題呢?目前面對(duì)大數(shù)據(jù)給現(xiàn)有倉(cāng)庫(kù)存儲(chǔ)架構(gòu)帶來(lái)的量的沖擊和數(shù)據(jù)種類增加的挑戰(zhàn),不同的公司會(huì)選擇不同的技術(shù)路線,我們最初試圖通過(guò)一個(gè)大而全的存儲(chǔ)架構(gòu)來(lái)解決海量數(shù)據(jù)和多種數(shù)據(jù)類型的問(wèn)題。但結(jié)過(guò)一段時(shí)間反復(fù)研究,我們認(rèn)為大而全的存儲(chǔ)架構(gòu)不是解決大數(shù)據(jù)的最佳方案,我們目前決定采用的技術(shù)路線是讓不同種類的數(shù)據(jù)存儲(chǔ)在最適合他們的存儲(chǔ)系統(tǒng)里,然后再將不同的數(shù)據(jù)類型進(jìn)行融合,企業(yè)在融合的數(shù)據(jù)基礎(chǔ)上做商業(yè)分析。
本文我將從用友華表的技術(shù)思路、存儲(chǔ)方案、存儲(chǔ)之后的數(shù)據(jù)如何融合三個(gè)層次來(lái)闡述我們?nèi)绾螒?yīng)對(duì)大數(shù)據(jù)的挑戰(zhàn)。
分而治之 三面突圍
第一,有“容”乃大。“容”,即有足夠的容量來(lái)存儲(chǔ)數(shù)據(jù)。對(duì)于大規(guī)模數(shù)據(jù),我們將采用分而治之的思想,構(gòu)建分布式存儲(chǔ)系統(tǒng),并且做到易擴(kuò)展。保證系統(tǒng)可以方便的增加節(jié)點(diǎn),當(dāng)企業(yè)的數(shù)據(jù)快速增加時(shí),可以使數(shù)據(jù)分布始終保持在平衡狀態(tài);
第二,有“榮”乃大。即兼用多種存儲(chǔ)引擎。大數(shù)據(jù)因結(jié)構(gòu)復(fù)雜多樣使得數(shù)據(jù)倉(cāng)庫(kù)要采集的源數(shù)據(jù)種類無(wú)比“繁榮”,因此新的倉(cāng)儲(chǔ)架構(gòu)也要改變目前以結(jié)構(gòu)化為主體的單一存儲(chǔ)方案的現(xiàn)狀,針對(duì)每種數(shù)據(jù)的存儲(chǔ)特點(diǎn)選擇最合適的解決方案:對(duì)非結(jié)構(gòu)化數(shù)據(jù)采用分布式文件系統(tǒng)進(jìn)行存儲(chǔ),對(duì)結(jié)構(gòu)松散無(wú)模式的半結(jié)構(gòu)化數(shù)據(jù)采用面向文檔的分布式key/value存儲(chǔ)引擎,對(duì)海量的結(jié)構(gòu)化數(shù)據(jù)采用shared-nothing的分布式并行數(shù)據(jù)庫(kù)系統(tǒng)存儲(chǔ);
第三,有“融”乃大。如上所述可以兼用多種分布式存儲(chǔ)引擎來(lái)解決“容”和“榮”的挑戰(zhàn),但企業(yè)存儲(chǔ)多元化數(shù)據(jù)的一個(gè)重要目標(biāo)是集成分析,而多種類型數(shù)據(jù)孤立存儲(chǔ)對(duì)后續(xù)的集成分析會(huì)帶來(lái)極大不便。因此我們還需要構(gòu)建分布式數(shù)據(jù)庫(kù)系統(tǒng)和分布式文件系統(tǒng)之間的連接器,使得非結(jié)構(gòu)化數(shù)據(jù)在處理成結(jié)構(gòu)化信息后,能方便的和分布式數(shù)據(jù)庫(kù)中的關(guān)系型數(shù)據(jù)快速融通,保證大數(shù)據(jù)分析的敏捷性。
存儲(chǔ)方案各不同
上面提到針對(duì)大數(shù)據(jù)規(guī)模大、種類多的特點(diǎn),我們可以采用“容”、“榮”的方案,兼用多種分布式存儲(chǔ)引擎分而治之。那么我們就拿非結(jié)構(gòu)化、半結(jié)構(gòu)化和結(jié)構(gòu)化這三大類數(shù)據(jù)的存儲(chǔ)方案分別舉例說(shuō)明,以便讓大家更清楚的了解到不同類型的海量數(shù)據(jù)通常都是通過(guò)哪些方式來(lái)進(jìn)行存儲(chǔ)的。由于談到的都是業(yè)界普遍使用的開(kāi)源或商業(yè)方案,因此不做深入討論。
首先,適合存儲(chǔ)海量非結(jié)構(gòu)化數(shù)據(jù)的分布式文件系統(tǒng)。
HDFS(Hadoop Distributed File System),是鼎鼎大名的開(kāi)源項(xiàng)目Hadoop的家族成員,是谷歌文件系統(tǒng)GFS(Google File System)的開(kāi)源實(shí)現(xiàn)。HDFS將大規(guī)模數(shù)據(jù)分割為多個(gè)64兆字節(jié)的數(shù)據(jù)塊,存儲(chǔ)在多個(gè)數(shù)據(jù)節(jié)點(diǎn)組成的分布式集群中,隨著數(shù)據(jù)規(guī)模的不斷增長(zhǎng),只需要在集群中增加更多的數(shù)據(jù)節(jié)點(diǎn)即可,因此具有很強(qiáng)的可擴(kuò)展性;同時(shí)每個(gè)數(shù)據(jù)塊會(huì)在不同的節(jié)點(diǎn)中存儲(chǔ)3個(gè)副本,因此具有高容錯(cuò)性;因?yàn)閿?shù)據(jù)是分布式存儲(chǔ)的,因此可以提供高吞吐量的數(shù)據(jù)訪問(wèn)能力,在海量數(shù)據(jù)批處理方面有很強(qiáng)的性能表現(xiàn)。
其次,適合存儲(chǔ)海量無(wú)模式的半結(jié)構(gòu)化數(shù)據(jù)的分布式Key/Value存儲(chǔ)引擎。
HBase(Hadoop Database),也是開(kāi)源項(xiàng)目Hadoop的家族成員,是谷歌大表Bigtable的開(kāi)源實(shí)現(xiàn)。HBase是一個(gè)高可靠性、高性能、面向列、可伸縮的分布式存儲(chǔ)系統(tǒng),它不同于一般的有模式的關(guān)系型數(shù)據(jù)庫(kù),HBase存儲(chǔ)的數(shù)據(jù)表是無(wú)模式的,特別適合結(jié)構(gòu)復(fù)雜多樣的半結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)。此外,HBase利用HDFS作為其文件存儲(chǔ)系統(tǒng),利用MapReduce技術(shù)來(lái)處理HBase中的海量數(shù)據(jù)。
第三,適合存儲(chǔ)海量結(jié)構(gòu)化數(shù)據(jù)的分布式并行數(shù)據(jù)庫(kù)系統(tǒng)。
Greenplum是基于PostgreSQL開(kāi)發(fā)的一款MPP(海量并行處理)架構(gòu)的、shared-nothing無(wú)共享的分布式并行數(shù)據(jù)庫(kù)系統(tǒng)。采用Master/Slave架構(gòu),Master只存儲(chǔ)元數(shù)據(jù),真正的用戶數(shù)據(jù)被散列存儲(chǔ)在多臺(tái)Slave服務(wù)器上,并且所有的數(shù)據(jù)都在其它Slave節(jié)點(diǎn)上存有副本,從而提高了系統(tǒng)可用性。
Greenplum最核心的技術(shù)就是,大表數(shù)據(jù)分片存儲(chǔ),可以應(yīng)對(duì)海量數(shù)據(jù);基于大表的查詢語(yǔ)句在經(jīng)過(guò)Master分析后可以分片發(fā)送到Slave節(jié)點(diǎn)進(jìn)行并行運(yùn)行,所有節(jié)點(diǎn)將中間結(jié)果返回給Master節(jié)點(diǎn),由Master進(jìn)行匯總后返回給客戶端,大大提高了SQL的運(yùn)行速度。
“三融合一”——Xnet數(shù)據(jù)交換網(wǎng)絡(luò)
各種復(fù)雜而大量的數(shù)據(jù)猶如一張立體的大網(wǎng),三類數(shù)據(jù)是網(wǎng)里三種不同的結(jié)點(diǎn),前面提到的三類分布式存儲(chǔ)引擎可以將不同的結(jié)點(diǎn)有序的安排在網(wǎng)上,并且每種相同的結(jié)點(diǎn)都可以直接用線相互連接起來(lái)。但此時(shí)只是三個(gè)孤立的面,就如同三類數(shù)據(jù)間存在的孤島。若要把這三個(gè)面也相互連接起來(lái),形成一張可以從點(diǎn)到面,從點(diǎn)到點(diǎn),從面到面的大網(wǎng),則需要構(gòu)建一個(gè)方便、快速的數(shù)據(jù)交換組件,它是一個(gè)連接器,可以實(shí)現(xiàn)“三融合一”,滿足大數(shù)據(jù)存儲(chǔ)有“融”乃大的特性。
下面先介紹一下數(shù)據(jù)交換網(wǎng)絡(luò)Xnet(Exchange Net)的一些基本構(gòu)思,它是一個(gè)可以完成分布式文件系統(tǒng)和分布式數(shù)據(jù)庫(kù)之間海量數(shù)據(jù)快速交換的組件。
上圖僅是一個(gè)簡(jiǎn)化的邏輯圖,在實(shí)際的物理部署中,HDFS集群和并行數(shù)據(jù)庫(kù)集群共用一個(gè)服務(wù)器集群,即在服務(wù)器集群的每個(gè)節(jié)點(diǎn)上既有HDFS數(shù)據(jù)節(jié)點(diǎn)也有并行數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)單實(shí)例。處于中間融通兩方數(shù)據(jù)的藍(lán)色部分就是我們本節(jié)要探討的分布式、可并行運(yùn)行的高速連接器Xnet。
Xnet實(shí)際就是運(yùn)行在Hadoop集群上的一系列Mapreduce任務(wù),它要完成從HDFS讀取源數(shù)據(jù)、處理中間結(jié)果集、最后寫(xiě)入分布式數(shù)據(jù)庫(kù)的若干作業(yè),這些作業(yè)對(duì)調(diào)用者而言是完全透明的,僅需要配置簡(jiǎn)單的業(yè)務(wù)信息,調(diào)用Xnet就可自動(dòng)完成:
源數(shù)據(jù)文件:需要同步至分布式數(shù)據(jù)庫(kù)的HDFS文件
文件頭:源數(shù)據(jù)的列分隔符、以及與目標(biāo)表列名的映射
目標(biāo)表:要寫(xiě)入的數(shù)據(jù)庫(kù)表
過(guò)濾條件:選擇寫(xiě)入的數(shù)據(jù)行條件
散列鍵:根據(jù)散列鍵的值和哈希算法確定數(shù)據(jù)要寫(xiě)入分布式數(shù)據(jù)庫(kù)的節(jié)點(diǎn),對(duì)數(shù)據(jù)進(jìn)行分片保證數(shù)據(jù)均衡分布
Xnet組件的主要功能設(shè)計(jì)如下:
第一, 拆分列表。將源數(shù)據(jù)文件符合過(guò)濾條件的面向行的記錄拆分為多個(gè)列表,并存入如下的目錄結(jié)構(gòu)中:
一級(jí)目錄為表名,二級(jí)目錄為列名,這樣方便后續(xù)的基于列的數(shù)據(jù)傳輸、裝載以及基于列的統(tǒng)計(jì)信息采集,其Mapreduce過(guò)程可以模擬如下:
Map階段:
a、源數(shù)據(jù)文件被splitable接口分割為多個(gè)數(shù)據(jù)段,對(duì)每個(gè)段Jobtracker會(huì)啟動(dòng)一個(gè)Mapper檢索每一行記錄,根據(jù)Xnet的配置信息得到符合過(guò)濾條件的記錄
b、根據(jù)Xnet配置信息得到每條記錄的散列鍵,結(jié)合哈希算法計(jì)算出該記錄的散列值HK
c、根據(jù)Mapper處理的數(shù)據(jù)段號(hào)和當(dāng)前處理的行號(hào)產(chǎn)生一個(gè)行標(biāo)識(shí)RID
d、Mapper結(jié)合Xnet的配置信息對(duì)當(dāng)前記錄的每一列都產(chǎn)生輸出,數(shù)據(jù)格式為HK:(Cn;RID;Cv),其中HK為散列值,Cn為列名,RID為行標(biāo)識(shí),Cv為列值
Reduce階段:
a、Reducer遠(yuǎn)程讀取Mapper產(chǎn)生的中間數(shù)據(jù)集,通過(guò)實(shí)現(xiàn)定制化的MultipleOutputFormat接口并根據(jù)記錄中Cn即列名,將記錄寫(xiě)入如上的樹(shù)結(jié)構(gòu)目錄中,數(shù)據(jù)格式為HK:(RID;Cv)。
第二,散列列表。將拆分得到的列表數(shù)據(jù)文件根據(jù)每條記錄的散列值HK匯聚到相應(yīng)的數(shù)據(jù)庫(kù)實(shí)例節(jié)點(diǎn),進(jìn)行排序等操作,并行加載入分布式數(shù)據(jù)庫(kù)中,其Mapreduce過(guò)程模擬如下:
Map階段:
a、Mapper從對(duì)應(yīng)的二級(jí)目錄結(jié)構(gòu)中讀取每個(gè)列表的數(shù)據(jù)文件
Reduce階段:
a、Mapper產(chǎn)生的中間數(shù)據(jù)集根據(jù)散列值HK進(jìn)行Partition匯聚到不同的Reducer進(jìn)程
b、Reducer對(duì)數(shù)據(jù)集按照列值即Cv進(jìn)行排序操作,并通過(guò)實(shí)現(xiàn)定制化的MultipleOutputFormat接口將數(shù)據(jù)通過(guò)分布式數(shù)據(jù)庫(kù)的裝載接口寫(xiě)入相應(yīng)的數(shù)據(jù)庫(kù)實(shí)例中
第三,統(tǒng)計(jì)信息。該功能主要是以單位列表為對(duì)象進(jìn)行全量或者抽樣計(jì)算,產(chǎn)生列級(jí)統(tǒng)計(jì)信息,利用Xnet的數(shù)據(jù)交換過(guò)程進(jìn)行統(tǒng)計(jì)信息采集,減輕分布式數(shù)據(jù)庫(kù)后續(xù)分析表的相關(guān)運(yùn)算。這些統(tǒng)計(jì)信息有助于分布式數(shù)據(jù)庫(kù)的查詢引擎做出最合理的執(zhí)行計(jì)劃,提高用戶的數(shù)據(jù)分析效率。
我們將統(tǒng)計(jì)信息采集的操作實(shí)現(xiàn)為獨(dú)立的算子,嵌入到Xnet的數(shù)據(jù)交換過(guò)程中,保證代碼的獨(dú)立性,可以方便的控制何時(shí)進(jìn)行統(tǒng)計(jì)信息的采集。主要算子描述如下:
StatisticsGather
簡(jiǎn)單的聚集統(tǒng)計(jì)采集,如空值數(shù)、記錄數(shù),最大最小值等
HistogramGather
等高直方圖、常用值統(tǒng)計(jì)等
SampleGather
數(shù)據(jù)采樣算子,在采樣統(tǒng)計(jì)情景下,將命中的記錄傳給其它兩個(gè)算子進(jìn)行統(tǒng)計(jì)
下面通過(guò)舉例看看統(tǒng)計(jì)信息采集的處理過(guò)程。
首先,準(zhǔn)備階段。Mapreduce過(guò)程要對(duì)輸入的數(shù)據(jù)進(jìn)行分割split操作,在統(tǒng)計(jì)信息的采集過(guò)程中不用對(duì)所有的splits都進(jìn)行統(tǒng)計(jì)分析,每次采集任務(wù)只選擇指定數(shù)量的split進(jìn)行。這些數(shù)量值需要在統(tǒng)計(jì)信息任務(wù)里進(jìn)行配置,如采樣的splits數(shù)量num_sample_splits,采樣的記錄數(shù)num_sample_records。
采樣的選擇方法:
如果num_sample_splits大于splits總數(shù),那么所有splits都需要進(jìn)行采樣,每個(gè)split采樣的記錄數(shù)為num_sample_records / total_splits
如果num_sample_splits小于splits總數(shù),計(jì)算splits挑選的間隔sample_step = total_splits / num_sample_splits,按照sample_step的間隔從splits列表中選出
num_sample_splits個(gè)split,每個(gè)split需要采樣的任務(wù)數(shù)為num_sample_records / num_sample_splits
其次,采樣算子。在海量數(shù)據(jù)中,對(duì)每個(gè)字段統(tǒng)計(jì)一個(gè)精確的直方圖信息的代價(jià)太大,而且也沒(méi)有意義。因此采用采樣的手段來(lái)統(tǒng)計(jì)每個(gè)字段的直方圖信息比較可取,下面描述兩種采樣方式,如果能清楚知道每個(gè)分割文件的記錄數(shù)目那么直接采用采樣算法Algorithm S或者Algorithm R是最好的,具體采樣算法這里不做討論。
順序讀取:SampleGather接收需要處理的記錄,如果達(dá)到配置的采樣數(shù)目則跳過(guò)不做任何操作;如果沒(méi)有達(dá)到則傳遞給HistogramGather進(jìn)行統(tǒng)計(jì)分析
估值讀?。篠ampleGather統(tǒng)計(jì)前n條記錄的平均長(zhǎng)度,根據(jù)平均長(zhǎng)度和當(dāng)前分割文件的總長(zhǎng)度,估算當(dāng)前包含的總記錄數(shù)。有了總記錄數(shù)N就可進(jìn)行采樣算法如Algorithm S或者Algorithm R,將采樣命中的記錄傳遞給HistogramGather進(jìn)行統(tǒng)計(jì)分析
第三,MR流程。在此模擬統(tǒng)計(jì)信息采集的Mapreduce過(guò)程,包括字段記錄總數(shù)、空值記錄比例、常用值統(tǒng)計(jì)和等高直方圖統(tǒng)計(jì)。
Map階段:
a、Mapper從文本文件中解析得到的一行記錄,并傳遞給StatisticsGather和SampleGather
b、StatisticsGather的處理:統(tǒng)計(jì)記錄數(shù)num_all加1,如果該字段同時(shí)為空則num_null加1
c、SampleGather進(jìn)行采樣后,將采樣的記錄傳遞給HistogramGather進(jìn)行直方圖統(tǒng)計(jì)(在Map階段直方圖統(tǒng)計(jì)包括常用值統(tǒng)計(jì)和等高直方圖統(tǒng)計(jì))
d、常用值統(tǒng)計(jì):將該字段放入HashTable進(jìn)行去重操作,統(tǒng)計(jì)該字段的重復(fù)類;HashTable中按照值出現(xiàn)的次數(shù)排序,并且保證HashTable的大小在指定的范圍內(nèi),比如250個(gè)Key
e、等高直方圖統(tǒng)計(jì):直接將所有采樣到的所有記錄輸出到Reduce階段,因?yàn)榈雀咧狈綀D需要一個(gè)全局的采樣統(tǒng)計(jì)
Map階段輸出:
a、StatisticsGather輸出:該split中包含的總記錄數(shù)num_all,該字段的空值數(shù)量num_null
b、HistogramGather輸出:常用值(MCV)統(tǒng)計(jì)輸出,HashTable中key的數(shù)目,key的列表,以及每個(gè)key在split中占有的數(shù)量;等高直方圖統(tǒng)計(jì)輸出,采樣得到的所有記錄
Reduce階段:
a、StatisticsGather輸出:累加每個(gè)Map輸出的num_all,得到總記錄數(shù);累加每個(gè)Map輸出的字段的空值數(shù)量,并與總記錄數(shù)相除,得到空值比例
b、HistogramGather的常用值統(tǒng)計(jì)輸出:利用Mapper和Reducer的Sort機(jī)制,對(duì)常用值出現(xiàn)次數(shù)進(jìn)行累加統(tǒng)計(jì)。基于常用值統(tǒng)計(jì)可以進(jìn)一步產(chǎn)生更多的統(tǒng)計(jì)信息,如遍歷常用值的HashTable,統(tǒng)計(jì)出現(xiàn)次數(shù)大于1的鍵值,如果該值為0,則說(shuō)明該字段具有唯一性。還可以利用常用值輸出計(jì)算該列的離散度等,這里不再贅述。
c、HistogramGather的等高直方圖統(tǒng)計(jì)輸出:利用Mapper和Reducer的Sort機(jī)制,將每個(gè)Mapper輸出的采樣記錄進(jìn)行排序。根據(jù)配置的直方圖箱個(gè)數(shù),將這些值分到不同的bin中,記錄每個(gè)bin的起始值和結(jié)束值。輸出等高的直方圖。(如下圖所示,得到等高直方圖的例子)
上圖中的直方圖(根據(jù)紅線分割bin)可以記錄為:0 - B;1-C;2 - C;3 - E;