11.Hive压缩,文件格式及优化

1. 日志文件加载案例:

需求描述:在日志文件目录中,按天建文件夹,并且在每个天文件夹中,每小时有一个日志文件。程序自动每天将这些文件load到hive表对应的天分区的小时分区内。例如下面的目录结构:


文件目录结构.png

首先,需要根据实际文件的情况(查看分隔符)来确定我们建表的分隔符。实际上,在显示时,TAB和空格十分相似,不好区分,可以使用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' 

下面使用两种方式实现, hive -e "sql" 和 hive --hiveconf -f 。

1. hive -e方式:

通过shell脚本,可以将变量拼接到sql语句中,并load数据到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

调用该脚本,需要传入unix时间戳作为参数:

$ ./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语句),执行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中的数据压缩。

1.压缩特点:

多数Hadoop作业在执行时,都受限于I/O瓶颈。对数据做压缩,可以大量减少磁盘的存储空间,同时压缩后的文件在磁盘间传输和I/O也会大大减少;当然压缩和解压缩也会带来额外的CPU开销,但是却可以节省更多的I/O和使用更少的内存开销。Job的性能可能会通过开启压缩而提高,但是必须要考虑到 Splittability。

2.压缩算法:

查看自己的hadoop版本支持的压缩算法(库):

$ bin/hadoop checknative

常见的压缩算法包括:bzip2,gzip,lzo,lz4,snappy等。一般地,评判一个压缩算法好坏,需要综合考虑“压缩比”和“解压速度”两个指标。一般情况下,压缩比越大表明文件压缩后占用空间越小,但同时,需要的解压时间也越多。所以,需要综合考虑。目前,lz4和snappy使用比较广泛。
压缩比: bzip2 > gzip > lzo

MapReduce中的压缩.png

从上图发现,可以在3个过程使用压缩:

  • Map阶段前压缩
  • Shuffle阶段 { Compress Intermediate Data (Map Output) }
  • Reduce阶段后 { Compress Reducer/Job Output (Reducer Output) }

一般情况下,可能会设置启用 Shuffle阶段压缩 和 Reduce阶段后 压缩。
(1)Shuffle阶段压缩:
Map输出需要写到磁盘,并且需要占用I/O在集群内传输。压缩可以减少写入磁盘I/O和网络传输I/O,提高性能。可以使用Snappy、LZO等压缩算法。
(2)Reduce阶段压缩:
MapReduce输出用来归档或者chaining Mapreduce作业。Reduce阶段使用压缩可以节省磁盘空间。

在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。

反序列化用来读取数据,序列化用来写入数据:
HDFS files --> InputFileFormat --> <key, value> --> Deserializer --> Row object
Row object --> Serializer --> <key, value> --> OutputFileFormat --> HDFS files
反序列化将一个String,或者记录的二级制表示转化成一个Hive可以处理的java对象。DeSerializer通常用于读数据,例如SELECT语句。
序列化是将一个Hive处理的java对象转化成Hive可以写入HDFS的对象。Serializer通常用于写数据,例如INSERT ... SELECT ...语句。
Serde类中 的initialize() 只执行一次,获取表字段和字段类型信息。利用记录的类型信息,为记录(row)实例化ObjectInspector对象。ObjectInspector是Hive对象,用来检查和描述复杂类型的层次结构。

http://blog.cloudera.com/blog/2012/12/how-to-use-a-serde-in-apache-hive/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容