当前位置:首页 > 开发 > 开源软件 > 正文

hive默认分隔符引起的日志分割问题

发表于: 2015-01-10   作者:brandNewUser   来源:转载   浏览次数:
摘要: Hive中的外部表 对于Hive中的外部表来说,因为表是外部的,Hive认为其并不拥有这份数据,删除该表并不会真正删除其中的数据,其中的表描述元信息会被删除掉。   对数据进行分区后,对于管理表,可以将其显示在hdfs目录中,但是外部表目录中不会真正存在数据,只能通过show partitions命令来显示外部表的分区信息。   我们的外部表是通过dateid

Hive中的外部表

对于Hive中的外部表来说,因为表是外部的,Hive认为其并不拥有这份数据,删除该表并不会真正删除其中的数据,其中的表描述元信息会被删除掉。
 
对数据进行分区后,对于管理表,可以将其显示在hdfs目录中,但是外部表目录中不会真正存在数据,只能通过show partitions命令来显示外部表的分区信息。
 
我们的外部表是通过dateid进行的partition,如何显示某个partition外部表对应的location:
 
hive -e "describe extended xxx partition (dateid=20141230)"
 
显示出来的信息大致如下:
field1 string
dateid string

# Partition Information
# col_name data_type comment

dateid string

Detailed Partition Information Partition(values:[20141230], dbName:logbase_db, tableName:logbase, createTime:1419984079, lastAccessTime:0, sd:StorageDescriptor(cols:[FieldSchema(name:doc, type:string, comment:null), FieldSchema(name:dateid, type:string, comment:null)], location:hdfs://ns1/xxx/20141230, inputFormat:com.inputformat.XXXInputFormat, outputFormat:org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat, compressed:false, numBuckets:-1, serdeInfo:SerDeInfo(name:null, serializationLib:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, parameters:{serialization.format=1}), bucketCols:[], sortCols:[], parameters:{}, skewedInfo:SkewedInfo(skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}), storedAsSubDirectories:false), parameters:{numFiles=129, transient_lastDdlTime=1419984079, COLUMN_STATS_ACCURATE=false, numRows=-1, totalSize=170482370617, rawDataSize=-1})
Time taken: 0.994 seconds, Fetched: 9 row(s)
 
显示出来某个partition对应的hdfs地址等,使用的InputFormat等详细信息。
 
关于外部表创建的语句,完整内容大概如下:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
(col_name data_type, ...)
[PARTITIONED BY (col_name data_type, ...)]
[CLUSTERED BY (col_name, col_name, ...)]
[SORTED BY (col_name, col_name, ...)]
[ROW FORMAT row_formart]
[STORED AS file_format]
[LOCATION hdfs_path]
[AS select_statement]
 
当然,也可以通过使用Like复制一个已经存在的表定义:
 
CREATE [EXTERNAL] TABLE [IF NOT EXIST] table_name LIKE existing_table name
[LOCATION hdfs_path]
 
其中各个语句的含义如下:
 
  • CREATE TABLE:创建一个指定名字的表名。如果已经存在,使用IF NOT EXIST来忽略抛出的异常
  • EXTERNAL:创建一个外部表,也就是说在创建一个表的同时指定一个指向实际数据的路径。
  • LIKE:允许复制一个已经存在的表的定义,而不复制表中已经存在的内容。
  • PARTITIONED BY:建立带有分区的表。
  • CLUSTERED:对表和分区进行类聚操作。
  • SORT BY:根据某个字段进行排序,可以提高数据的查询效率。
 
如果要使用特定的InputFormat,还需要加入下面的语句:
 
INPUTFORMAT 'xxxHiveInputFormat'
     OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
     LOCATION '/aaa/hive-table'
 
 
这样就指定InputFormat和OutputFormat,以及外部表的Location。其中InputFormat与Hadoop中的略有不同,其中的RecordReader需要特殊继承Hive中的
 
org.apache.hadoop.hive.ql.io.HiveContextAwareRecordReader
 
 
可以做一个Adaptor来将原有的RecordReader进行适配以满足Hive查询的要求。
 

Hive中的分隔符

 
hive 默认的字段分隔符为ascii码的控制符\001,建表的时候用fields terminated by '\001',如果要测试的话,造数据在vi 打开文件里面,用ctrl+v然后再ctrl+a可以输入这个控制符\001。按顺序,\002的输入方式为ctrl+v,ctrl+b。以此类推。
 
当前我们新建的Hive表中,默认fields terminated by没有设置,那么就使用'\001'。
 
比如我们的一条日志,表面上看起来没有问题:
cat a.log 
tp=imp^ti=1419076654^md=iPhone3,1^__tid=5zKN0REAy8M%253D^mh=640.00x960.00^me=7.1.2^mf=84fef4314602f88b90dad8f2a9d4b23dv1.1t1419076650kcom.qiyi.iphone^mk=1^plt=1^mn=iphone^m9=128f0ab5^os=i^mm=31.892004x119.898267x50.000000^mp=com.qiyi.iphone^e=i___m^mo=1^m5=9920F2E3-4BDB-430F-BCC3-6ACF6EC6F155^kt=mma^mt=1419076649529^a=UoNVX034P723^rawIp=222.185.12.59^mw=1^j=zh^k=2001515^av=11^ip=222.185.12.59^m0=604a45ed52a06f1535711e3c68a130f2edc^pf=c1^p=101324851^pu=m^pn=iphone^rt=2^uuid=9920f2e3-4bdb-430f-bcc3-6acf6ec6f155^po=http%3a%2f%2fmlt01.com%2fo.htm%3fpv%3d0%26sp%3d0%2c1195912%2c1199754%2c2213157%2c0%2c1%2c1^ag=34

 

 

但是通过cat -A(--show-all),就可以看出所有的隐藏字符:

 

 

cat -A a.log
tp=imp^ti=1419076654^md=iPhone3,1^__tid=5zKN0REAy8M%253D^mh=640.00x960.00^me=7.1.2^mf=84fef4314602f88b90dad8f2a9d4b23dv1.1t1419076650kcom.qiyi.iphone^mk=1^plt=1^mn=iphone^m9=128f0ab5^os=i^mm=31.892004x119.898267x50.000000^mp=com.qiyi.iphone^e=i___m^mo=1^m5=9920F2E3-4BDB-430F-BCC3-6ACF6EC6F155^kt=mma^mt=1419076649529^a=UoNVX034P723^rawIp=222.185.12.59^mw=1^j=zh^k=2001515^av=11^ip=222.185.12.59^m0=604a45ed52a06f15357^A11e^@^@^@^@3c68a130f2edc^pf=c1^p=101324851^pu=m^pn=iphone^rt=2^uuid=9920f2e3-4bdb-430f-bcc3-6acf6ec6f155^po=http%3a%2f%2fmlt01.com%2fo.htm%3fpv%3d0%26sp%3d0%2c1195912%2c1199754%2c2213157%2c0%2c1%2c1^ag=34$

 

 
而其中看到的^A就是'\001'的表示(实际上是一个字符),这样外部表中该行数据^A前面的字符被截断导致该行数据只能显示前半部分。
 
最终的简单解决方法便是重写InputFormat,替换掉可能会导致问题的字符串特殊字符。
 
 
 
 
 

hive默认分隔符引起的日志分割问题

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
在用控制台学习hive和spark的时候,总是打印出来的各种日志烦得不行(对我而言)。所以就想把着写我
PIG中输入输出分隔符默认是制表符\t,而到了hive中,默认变成了八进制的\001, 也就是ASCII: ctrl
获取hive日志比较麻烦,通常的做法是执行shell命令获取日志,但是这样有一些问题,比如:输出的结果
作者:zhanhailiang 日期:2014-01-06 默认nginx只会生成一个access.log和一个error.log,并且每天不
最近在搭建应用测试环境的时候遇到一个问题,应用搭建不起来,而且spring框架的日志都没有打印出来
http://stackoverflow.com/questions/4883891/ruby-on-rails-production-log-rotation logrotate 程
项目打包的时候,js文件后缀类似这样的,a.js?v==TIMESTAMP 没有replace成功: 其中pom.xml配置如下
昨天老板让我帮忙解决个问题。一个没人在维护的某酒店订票应用的预定日期等很多有日期的地方都显示
1、日志格式分析 首先分析 Hadoop 的日志格式, 日志是一行一条, 日志格式可以依次描述为:日期、时间
针对app,resin,tomcat日志分割脚本 appname:填写app(包含resin/tomcat)的名字; key:过滤日志关
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号