- 論壇徽章:
- 2
|
Apache Hadoop是目前被大家廣泛使用的數(shù)據(jù)分析平臺(tái),它可靠、高效、可伸縮。Percona公司的Alexander Rubin 最近發(fā)表了一篇博客文章介紹了他是如何將一個(gè)表從MySQL導(dǎo)出到Hadoop然后將數(shù)據(jù)加載到Cloudera Impala并在這上面運(yùn)行報(bào)告的。
在Alexander Rubin的這個(gè)測(cè)試示例中他使用的集群包含6個(gè)數(shù)據(jù)節(jié)點(diǎn)。下面是具體的規(guī)格:
用途
| 服務(wù)器規(guī)格
| NameNode、DataNode、Hive 元數(shù)據(jù)存儲(chǔ)等
| 2x PowerEdge 2950, 2x L5335 CPU @ 2.00GHz, 8 cores, 16GB RAM, 使用8個(gè)SAS驅(qū)動(dòng)器的RAID 10
| 僅做數(shù)據(jù)節(jié)點(diǎn)
| 4x PowerEdge SC1425, 2x Xeon CPU @ 3.00GHz, 2 cores, 8GB RAM, 單個(gè)4TB 驅(qū)動(dòng)器
|
數(shù)據(jù)導(dǎo)出
有很多方法可以將數(shù)據(jù)從MySQL導(dǎo)出到Hadoop。在Rubin的這個(gè)示例中,他簡(jiǎn)單地將ontime表導(dǎo)出到了一個(gè)文本文件中:
select * into outfile '/tmp/ontime.psv' FIELDS TERMINATED BY ',' from ontime;
你可以使用“|”或者任何其他的符號(hào)作為分隔符。當(dāng)然,還可以使用下面這段簡(jiǎn)單的腳本直接從 www.transtats.bts.gov上下載數(shù)據(jù)。
for y in {1988..2013} do for i in {1..12} do u="http://www.transtats.bts.gov/Download/On_Time_On_Time_Performance_${y}_${i}.zip" wget $u -o ontime.log unzip On_Time_On_Time_Performance_${y}_${i}.zip done done
載入Hadoop HDFS
Rubin首先將數(shù)據(jù)載入到了HDFS中作為一組文件。Hive或者Impala將會(huì)使用導(dǎo)入數(shù)據(jù)的那個(gè)目錄,連接該目錄下的所有文件。在Rubin的示例中,他在HDFS上創(chuàng)建了/data/ontime/目錄,然后將本地所有匹配On_Time_On_Time_Performance_*.csv模式的文件復(fù)制到了該目錄下。
$ hdfs dfs -mkdir /data/ontime/ $ hdfs -v dfs -copyFromLocal On_Time_On_Time_Performance_*.csv /data/ontime/
在Impala中創(chuàng)建外部表
當(dāng)所有數(shù)據(jù)文件都被載入之后接下來(lái)需要?jiǎng)?chuàng)建一個(gè)外部表:
CREATE EXTERNAL TABLE ontime_csv ( YearD int , Quarter tinyint , MonthD tinyint , DayofMonth tinyint , DayOfWeek tinyint , FlightDate string , UniqueCarrier string , AirlineID int , Carrier string , TailNum string , FlightNum string , OriginAirportID int , OriginAirportSeqID int , OriginCityMarketID int , Origin string , OriginCityName string , OriginState string , OriginStateFips string , OriginStateName string , OriginWac int , DestAirportID int , DestAirportSeqID int , DestCityMarketID int , Dest string , ... ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE LOCATION '/data/ontime';
注意“EXTERNAL”關(guān)鍵詞和LOCATION,后者指向HDFS中的一個(gè)目錄而不是文件。Impala僅會(huì)創(chuàng)建元信息,不會(huì)修改表。創(chuàng)建之后就能立即查詢?cè)摫恚赗ubin的這個(gè)示例中執(zhí)行的SQL是:
> select yeard, count(*) from ontime_psv group by yeard;
該SQL耗時(shí)131.38秒。注意GROUP BY并不會(huì)對(duì)行進(jìn)行排序,這一點(diǎn)不同于MySQL,如果要排序需要添加 ORDER BY yeard語(yǔ)句。另外通過執(zhí)行計(jì)劃我們能夠發(fā)現(xiàn)Impala需要掃描大小約為45.68GB的文件。
Impala使用面向列的格式和壓縮
Impala最大的好處就是它支持面向列的格式和壓縮。Rubin嘗試了新的使用Snappy壓縮算法的Parquet格式。因?yàn)檫@個(gè)例子使用的表非常大,所以最好使用基于列的格式。為了使用Parquet格式,首先需要載入數(shù)據(jù),這在Impala中已經(jīng)有表、HDFS中已經(jīng)有文件的情況下是非常容易實(shí)現(xiàn)的。本示例大約使用了729秒的時(shí)間導(dǎo)入了約1億5千萬(wàn)條記錄,導(dǎo)入之后使用新表再次執(zhí)行同一個(gè)查詢所耗費(fèi)的時(shí)間只有4.17秒,掃描的數(shù)據(jù)量也小了很多,壓縮之后的數(shù)據(jù)只有3.95GB。
Impala復(fù)雜查詢示例
select min(yeard), max(yeard), Carrier, count(*) as cnt, sum(if(ArrDelayMinutes>30, 1, 0)) as flights_delayed, round(sum(if(ArrDelayMinutes>30, 1, 0))/count(*),2) as rate FROM ontime_parquet_snappy WHERE DayOfWeek not in (6,7) and OriginState not in ('AK', 'HI', 'PR', 'VI') and DestState not in ('AK', 'HI', 'PR', 'VI') and flightdate < '2010-01-01' GROUP by carrier HAVING cnt > 100000 and max(yeard) > 1990 ORDER by rate DESC LIMIT 1000;
注意:以上查詢不支持sum(ArrDelayMinutes>30)語(yǔ)法,需要使用sum(if(ArrDelayMinutes>30, 1, 0) 代替。另外查詢故意被設(shè)計(jì)為不使用索引:大部分條件僅會(huì)過濾掉不到30%的數(shù)據(jù)。
該查詢耗時(shí)15.28秒比最初的MySQL結(jié)果(非并行執(zhí)行時(shí)15分56.40秒,并行執(zhí)行時(shí)5分47秒)要快很多。當(dāng)然,它們之間并不是一個(gè)“對(duì)等的比較”:
MySQL將掃描45GB的數(shù)據(jù)而使用Parquet的Impala僅會(huì)掃描3.5GB的數(shù)據(jù)
MySQL運(yùn)行在一臺(tái)服務(wù)器上,而Hadoop和Impala則并行運(yùn)行在6臺(tái)服務(wù)器上
盡管如此,Hadoop和Impala在性能方面的表現(xiàn)依然令人印象深刻,同時(shí)還能夠支持?jǐn)U展,因此在大數(shù)據(jù)分析場(chǎng)景中它能為我們提供很多幫助。
轉(zhuǎn)自 infoQ
本文來(lái)自ChinaUnix新聞?lì)l道,如果查看原文請(qǐng)點(diǎn):http://news.chinaunix.net/opensource/2014/0508/3152509.shtml
|
|