HIVE數倉ETL之MongoDB
阿新 • • 發佈:2019-01-26
前狀:
平臺目前還沒有完善的mongodb資料同步方式,在拉取公司埋點系統countly資料時,起初通過編寫MapReduce讀取mongodb資料轉化成BSONObject寫入到HDFS,在hive中建立對映表,使得BSON格式資料可以通過hive sql方式進行查詢
通過這種方式存在弊端:
1.執行MapReduce耗時太長,這裡一部分是網路原因,還有一部分是起了太多的map 任務,也就是將任務切分的過細,每個map只處理很少的任務,耗費太多資源
2.MongoDB與Hadoop部署在不同的伺服器上,伺服器的頻寬改變了,經常在MapReduce執行的過程中中斷,報SocketTimeout錯誤,增大連線超時引數timeout值得到一些緩解,但還是存在次此問題
改善方式:
在資料拉取過程使用mongodb自有dump方式
mongodump 是MongoDB備份的一種方式,可以dump下整個資料庫,也可以指定dump某個collection,dump下來的每個collection 都是BSON檔案
執行指令碼如下:
mongodump -h $host -u $user -p $password -d $db -c $collection -o $output -q $querySql
可按照查詢條件querySql將dump下來的BSON檔案輸出到output路徑下;
再將BSON檔案上傳到指定hdfs目錄中:
hadoop fs -put $output/*.bson $hdfsPath
這時可以和之前的方式一樣,建立hive對映表,示例程式碼
add jar mongo-hadoop-core-2.0.2.jar;
add jar mongo-hadoop-hive-2.0.0.jar;
add mongo-java-driver-3.2.2.jar;"
create external table `sfim_logs_dump` (
`id` string
,`ts` bigint
,`reqts` string
) comment 'countly hht6 logs'
partitioned by (`inc_day` string)
row format serde 'com.mongodb.hadoop.hive.bsonserde'
with serdeproperties(
'mongo.columns.mapping' = '{
\n \"id\":\"_id\"
, \n \"ts\":\"ts\"
, \n \"reqts\":\"reqts\"
}')
stored as inputformat 'com.mongodb.hadoop.mapred.bsonfileinputformat'
outputformat 'com.mongodb.hadoop.hive.output.hivebsonfileoutputformat'
location '$hdfspath'
但由於dump方式的檔案是單個大檔案,在countly中dump下來的最大檔案可達80G左右,非常不利於分散式處理
這時考慮對大檔案進行切分:
利用mongo-hadoop-core-2.0.2.jar包中提供的split方式處理
hadoop jar mongo-hadoop-core-2.0.2.jar com.mongodb.hadoop.splitter.BSONSplitter $hdfsPath/*.bson -[-c compressionCodec] [-o outputDirectory]
預設分割大小由輸入檔案的檔案系統的預設塊大小確定,如果不可用,則為64 MB
可以通過為mapreduce.input.fileinputformat.split .minsize,mapreduce.input.fileinputformat.split.maxsize設定值(以位元組為單位)為分割大小設定下限和上限
完成分割後,如不設定檔案輸出路徑,則需刪除原有BSON檔案
hadoop fs -rm $hdfspath/*.bson
切分完後,再次做對映查詢,速度明顯得到提升。