1. 日志文件加載案例:
需求描述:在日志文件目錄中,按天建文件夾,并且在每個天文件夾中,每小時有一個日志文件。程序自動每天將這些文件load到hive表對應的天分區(qū)的小時分區(qū)內(nèi)。例如下面的目錄結構:
首先,需要根據(jù)實際文件的情況(查看分隔符)來確定我們建表的分隔符。實際上,在顯示時,TAB和空格十分相似,不好區(qū)分,可以使用UltraEdit工具的功能來查看。使用方法:“視圖 -> 顯示空格/制表符”。
下面是建表DDL:
CREATE TABLE `testdb.dw_web_log`(
`id` string,
`url` string,
`referer` string,
`keyword` string,
`type` string,
`guid` string,
`pageid` string,
`moduleid` string,
`linkid` string,
`attachedinfo` string,
`sessionid` string,
`trackeru` string,
`trackertype` string,
`ip` string,
`trackersrc` string,
`cookie` string,
`ordercode` string,
`tracktime` string,
`enduserid` string,
`firstlink` string,
`sessionviewno` string,
`productid` string,
`curmerchantid` string,
`provinceid` string,
`cityid` string,
`fee` string,
`edmactivity` string,
`edmemail` string,
`edmjobid` string,
`ieversion` string,
`platform` string,
`internalkeyword` string,
`resultsum` string,
`currentpage` string,
`linkposition` string,
`buttonposition` string)
PARTITIONED BY (
`date` string,
`hour` string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
下面使用兩種方式實現(xiàn), hive -e "sql" 和 hive --hiveconf -f 。
1. hive -e方式:
通過shell腳本,可以將變量拼接到sql語句中,并load數(shù)據(jù)到hive表中。下邊腳本供參考load_web_log.sh:
#!/bin/bash
#You must input one parameter;
if [ $# -ne 1 ] ; then
echo "You must provide one parameter (date) unix timestamp !!"
exit 1
fi
date=`date -d @$1 +%Y%m%d`
logdir=/home/natty.ma/bigdata/hive/WebLog
HIVE_HOME=/spark/hive
log_num=`ls ${logdir}/${date}|wc -l`
if [ ${log_num} -lt 1 ]; then
echo "There are no log files this day:"${date}
exit 1
else
for i in `ls ${logdir}/${date}`; do
# cut 2 characters from the 9th location ; get the hour of the file
hour=${i:8:2}
$HIVE_HOME/bin/hive -e "load data local inpath '${logdir}/${date}/${i}' overwrite into table testdb.dw_web_log partition(date='${date}',hour='${hour}')"
done
fi
調(diào)用該腳本,需要傳入unix時間戳作為參數(shù):
$ ./load_web_log.sh `date -d "-1 days" +%s`
2. hive --hiveconf 方式傳參:
參考腳本load_web_log_1.sh :
#!/bin/bash
#You must input one parameter;
if [ $# -ne 1 ] ; then
echo "You must provide one parameter (date) unix timestamp !!"
exit 1
fi
date=`date -d @$1 +%Y%m%d`
logdir=/home/natty.ma/bigdata/hive/WebLog
HIVE_HOME=/spark/hive/
log_num=`ls ${logdir}/${date}|wc -l`
if [ ${log_num} -lt 1 ]; then
echo "There are no log files this day:"${date}
exit 1
else
for i in `ls ${logdir}/${date}`; do
# cut 2 characters from the 9th location ; get the hour of the file
hour=${i:8:2}
fileDir=${logdir}/${date}/${i}
${HIVE_HOME}/bin/hive --hiveconf fileDir=${fileDir} --hiveconf date=${date} --hiveconf hour=${hour} -f load_web_log.sql
done
fi
這里使用了一個sql文件load_web_log.sql,該文件作用很簡單(只有一條load語句),執(zhí)行SQL,并讀取變量即可。讀取變量時,需要注意,在sql文件中,如果要讀取hiveconf傳過來的fileDir變量,需要使用${hiveconf:fileDir}
load data local inpath '${hiveconf:fileDir}' overwrite into table testdb.dw_web_log partition(date='${hiveconf:date}',hour='${hiveconf:hour}')
2. MapReduce和hive中的數(shù)據(jù)壓縮。
1.壓縮特點:
多數(shù)Hadoop作業(yè)在執(zhí)行時,都受限于I/O瓶頸。對數(shù)據(jù)做壓縮,可以大量減少磁盤的存儲空間,同時壓縮后的文件在磁盤間傳輸和I/O也會大大減少;當然壓縮和解壓縮也會帶來額外的CPU開銷,但是卻可以節(jié)省更多的I/O和使用更少的內(nèi)存開銷。Job的性能可能會通過開啟壓縮而提高,但是必須要考慮到 Splittability。
2.壓縮算法:
查看自己的hadoop版本支持的壓縮算法(庫):
$ bin/hadoop checknative
常見的壓縮算法包括:bzip2,gzip,lzo,lz4,snappy等。一般地,評判一個壓縮算法好壞,需要綜合考慮“壓縮比”和“解壓速度”兩個指標。一般情況下,壓縮比越大表明文件壓縮后占用空間越小,但同時,需要的解壓時間也越多。所以,需要綜合考慮。目前,lz4和snappy使用比較廣泛。
壓縮比: bzip2 > gzip > lzo
從上圖發(fā)現(xiàn),可以在3個過程使用壓縮:
- Map階段前壓縮
- Shuffle階段 { Compress Intermediate Data (Map Output) }
- Reduce階段后 { Compress Reducer/Job Output (Reducer Output) }
一般情況下,可能會設置啟用 Shuffle階段壓縮 和 Reduce階段后 壓縮。
(1)Shuffle階段壓縮:
Map輸出需要寫到磁盤,并且需要占用I/O在集群內(nèi)傳輸。壓縮可以減少寫入磁盤I/O和網(wǎng)絡傳輸I/O,提高性能。可以使用Snappy、LZO等壓縮算法。
(2)Reduce階段壓縮:
MapReduce輸出用來歸檔或者chaining Mapreduce作業(yè)。Reduce階段使用壓縮可以節(jié)省磁盤空間。
在hadoop-common-xxx.jar中有定義壓縮算法的類,在包org.apache.hadoop.io.compress下。例如以下幾個類:
org.apache.hadoop.io.compress.SnappyCodec
org.apache.hadoop.io.compress.GzipCodec
org.apache.hadoop.io.compress.Lz4Codec
3.壓縮配置:
在MapReduce和Hive中指定壓縮的方式不一樣。
1.MapReduce指定壓縮:
(1)中間壓縮:
mapreduce.map.output.compress=true
mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
(2)Reduce結果壓縮:
mapreduce.output.fileoutputformat.compress=true
mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
如果需要永久配置,需要修改mapred-site.xml。
2.Hive指定壓縮:
(1)中間壓縮:
set hive.exec.compress.intermediate=true
set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.DefaultCodec
set mapred.map.output.compression.type=(BLOCK/RECORD)
(2)Reduce結果壓縮:
set hive.exec.compress.output=true
set mapred.output.compression.codec=org.apache.hadoop.io.compress.DefaultCodec
set mapred.output.compression.type=(BLOCK/RECORD)
如果需要永久生效,需要配置hive-site.xml。
反序列化用來讀取數(shù)據(jù),序列化用來寫入數(shù)據(jù):
HDFS files --> InputFileFormat --> <key, value> --> Deserializer --> Row object
Row object --> Serializer --> <key, value> --> OutputFileFormat --> HDFS files
反序列化將一個String,或者記錄的二級制表示轉(zhuǎn)化成一個Hive可以處理的java對象。DeSerializer通常用于讀數(shù)據(jù),例如SELECT語句。
序列化是將一個Hive處理的java對象轉(zhuǎn)化成Hive可以寫入HDFS的對象。Serializer通常用于寫數(shù)據(jù),例如INSERT ... SELECT ...語句。
Serde類中 的initialize() 只執(zhí)行一次,獲取表字段和字段類型信息。利用記錄的類型信息,為記錄(row)實例化ObjectInspector對象。ObjectInspector是Hive對象,用來檢查和描述復雜類型的層次結構。
http://blog.cloudera.com/blog/2012/12/how-to-use-a-serde-in-apache-hive/