关于hive RegexSerDe的源码分析

最近有个业务建表使用了 RegexSerDe,之前虽然也它来解析nginx日志,但是没有做深入的了解。这次看了下其实现方式。

建表语句:

CREATE external TABLE ods_cart_log
(
time_local STRING,
request_json  STRING,
trace_id_num STRING
)
PARTITIONED BY
(
dt string,
hour string
)
ROW FORMAT SERDE ‘org.apache.hadoop.hive.contrib.serde2.RegexSerDe‘
WITH SERDEPROPERTIES
("input.regex" =
"\\\[(.*?)\\\] .*\\\|(.*?) (.*?) \\\[(.*?)\\\]",
"output.format.string" ="%1$s %2$s  %4$s")
STORED AS TEXTFILE;

测试数据:

[2014-07-24 15:54:54] [6] OperationData.php: 
:89|{"action":"add","redis_key_hash":9,"time":"1406188494.73745500","source":"web",
"mars_cid":"","session_id":"","info":{"cart_id":26885,"user_id":4,"size_id":"2784145",
"num":"1","warehouse":"VIP_NH","brand_id":"7379","cart_record_id":26885,"channel":"te"}}
 trace_id [40618849399972881308]

这里trace_id_num按照猜想应该是第4个字段(即40618849399972881308),但是实际输出了第3个字段(trace_id)

查看其代码实现:

RegexSerDe主要由下面三个参数:

1)input.regex 正则

2)output.format.string 输出格式

3)input.regex.case.insensitive  大小写是否敏感

其中input.regex用在反序列化方法中,即数据的读取(hive读取hdfs文件),相对的output.format.string 用在序列化的方法中,即数据的写入(hive写入hdfs文件)。

在反序列化的方法deserialize中有如下代码,用于返回代表匹配字段的数据:

   for (int c = 0; c < numColumns; c++) {   //numColumns是按表中column的数量算的(
   比如这个例子columnNames 是[time_local, request_json, trace_id_num]   | numColumns = columnNames.size();
      try {
        row.set(c, m.group(c + 1));  //可以看到字段的匹配从0开始,中间不会有跳跃,
        所以这里select  trace_id_num 字段是正则里面的第3个组,而和output.format.string没有关系
          } catch (RuntimeException e) {
        partialMatchedRows++;
        if (partialMatchedRows >= nextPartialMatchedRows) {
          nextPartialMatchedRows = getNextNumberToDisplay(nextPartialMatchedRows);
          // Report the row
          LOG.warn("" + partialMatchedRows
              + " partially unmatched rows are found, " + " cannot find group "
              + c + ": " + rowText);
        }
        row.set(c, null);
      }
    }

这里output.format.string的设置仔细想想貌似没什么用,首先RegexSerDe的方式只在textfile下生效,即可以用load向hive的表中导入数据,但是load是一个hdfs层面的文件操作,不涉及到序列化,如果想使用序列化,需要使用insert into select的方式插入数据,但是这种方式插入的数据又和select的数据有关系,和output.format.string没什么关系了。。

其实regexserde类有两个

分别位于

./serde/src/java/org/apache/hadoop/hive/serde2/RegexSerDe.java 和
./contrib/src/java/org/apache/hadoop/hive/contrib/serde2/RegexSerDe.java

都是扩展了AbstractSerDe这个抽象类。通过代码可以看到contrib下的这个类是实现了serialize 和 deserialize 方法,而上面这个只实现了deserialize 方法,由此看来RegexSerDe中的serialize 方法可能是没什么用的。。

另外需要注意几点:

1.如果一行匹配不上,整个行的字段输出都是null

 if (!m.matches()) {
      unmatchedRows++;
      if (unmatchedRows >= nextUnmatchedRows) {
        nextUnmatchedRows = getNextNumberToDisplay(nextUnmatchedRows);
        // Report the row
        LOG.warn("" + unmatchedRows + " unmatched rows are found: " + rowText);
      }
      return null;
    }

2.表的字段类型必须都是string,否则会报错,如果需要别的字段,可以在select中使用cast做转换

    for ( int c = 0; c < numColumns ; c++) {
      if (!columnTypes.get(c).equals( TypeInfoFactory.stringTypeInfo)) {
        throw new SerDeException(getClass().getName()
            + " only accepts string columns, but column[" + c + "] named "
            + columnNames.get(c) + " has type " + columnTypes.get(c));
      }
    }

关于hive RegexSerDe的源码分析,布布扣,bubuko.com

时间: 2024-10-05 05:06:19

关于hive RegexSerDe的源码分析的相关文章

Spark SQL Catalyst源码分析之TreeNode Library

前几篇文章介绍了Spark SQL的Catalyst的SqlParser,和Analyzer,本来打算直接写Optimizer的,但是发现忘记介绍TreeNode这个Catalyst的核心概念,介绍这个可以更好的理解Optimizer是如何对Analyzed Logical Plan进行优化的生成Optimized Logical Plan,本文就将TreeNode基本架构进行解释. 一.TreeNode类型 TreeNode Library是Catalyst的核心类库,语法树的构建都是由一个个

Hadoop之HDFS原理及文件上传下载源码分析(下)

上篇Hadoop之HDFS原理及文件上传下载源码分析(上)楼主主要介绍了hdfs原理及FileSystem的初始化源码解析, Client如何与NameNode建立RPC通信.本篇将继续介绍hdfs文件上传.下载源解析. 文件上传 先上文件上传的方法调用过程时序图: 其主要执行过程: FileSystem初始化,Client拿到NameNodeRpcServer代理对象,建立与NameNode的RPC通信(楼主上篇已经介绍过了) 调用FileSystem的create()方法,由于实现类为Dis

Spark SQL源码分析之核心流程

自从去年Spark Submit 2013 Michael Armbrust分享了他的Catalyst,到至今1年多了,Spark SQL的贡献者从几人到了几十人,而且发展速度异常迅猛,究其原因,个人认为有以下2点: 1.整合:将SQL类型的查询语言整合到 Spark 的核心RDD概念里.这样可以应用于多种任务,流处理,批处理,包括机器学习里都可以引入Sql. 2.效率:因为Shark受到hive的编程模型限制,无法再继续优化来适应Spark模型里. 前一段时间测试过Shark,并且对Spark

Spark SQL 源码分析之 In-Memory Columnar Storage 之 cache table

/** Spark SQL源码分析系列文章*/ Spark SQL 可以将数据缓存到内存中,我们可以见到的通过调用cache table tableName即可将一张表缓存到内存中,来极大的提高查询效率. 这就涉及到内存中的数据的存储形式,我们知道基于关系型的数据可以存储为基于行存储结构 或 者基于列存储结构,或者基于行和列的混合存储,即Row Based Storage.Column Based Storage. PAX Storage. Spark SQL 的内存数据是如何组织的? Spar

Spark SQL 源码分析之 In-Memory Columnar Storage 之 in-memory query

/** Spark SQL源码分析系列文章*/ 前面讲到了Spark SQL In-Memory Columnar Storage的存储结构是基于列存储的. 那么基于以上存储结构,我们查询cache在jvm内的数据又是如何查询的,本文将揭示查询In-Memory Data的方式. 一.引子 本例使用hive console里查询cache后的src表. select value from src 当我们将src表cache到了内存后,再次查询src,可以通过analyzed执行计划来观察内部调用

hadoop源码分析解读入门

hadoop 源代码分析(一) Google 的核心竞争技术是它的计算平台.HadoopGoogle的大牛们用了下面5篇文章,介绍了它们的计算设施. Google的几篇论文 GoogleCluster:http://research.google.com/archive/googlecluster.html Chubby:http://labs.google.com/papers/chubby.html GFS:http://labs.google.com/papers/gfs.html Big

第二篇:Spark SQL Catalyst源码分析之SqlParser

/** Spark SQL源码分析系列文章*/ Spark SQL的核心执行流程我们已经分析完毕,可以参见Spark SQL核心执行流程,下面我们来分析执行流程中各个核心组件的工作职责. 本文先从入口开始分析,即如何解析SQL文本生成逻辑计划的,主要设计的核心组件式SqlParser是一个SQL语言的解析器,用scala实现的Parser将解析的结果封装为Catalyst TreeNode ,关于Catalyst这个框架后续文章会介绍. 一.SQL Parser入口 Sql Parser 其实是

第一篇:Spark SQL源码分析之核心流程

/** Spark SQL源码分析系列文章*/ 自从去年Spark Submit 2013 Michael Armbrust分享了他的Catalyst,到至今1年多了,Spark SQL的贡献者从几人到了几十人,而且发展速度异常迅猛,究其原因,个人认为有以下2点: 1.整合:将SQL类型的查询语言整合到 Spark 的核心RDD概念里.这样可以应用于多种任务,流处理,批处理,包括机器学习里都可以引入Sql.    2.效率:因为Shark受到hive的编程模型限制,无法再继续优化来适应Spark

第八篇:Spark SQL Catalyst源码分析之UDF

/** Spark SQL源码分析系列文章*/ 在SQL的世界里,除了官方提供的常用的处理函数之外,一般都会提供可扩展的对外自定义函数接口,这已经成为一种事实的标准. 在前面Spark SQL源码分析之核心流程一文中,已经介绍了Spark SQL Catalyst Analyzer的作用,其中包含了ResolveFunctions这个解析函数的功能.但是随着Spark1.1版本的发布,Spark SQL的代码有很多新完善和新功能了,和我先前基于1.0的源码分析多少有些不同,比如支持UDF: sp