1. 程式人生 > >HIVE數倉ETL之MongoDB

HIVE數倉ETL之MongoDB

前狀: 平臺目前還沒有完善的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 切分完後,再次做對映查詢,速度明顯得到提升。