背景
 
JSON是一种轻量级的数据格式,结构灵活,支持嵌套,非常易于人的阅读和编写,而且主流的编程语言都提供相应的框架或类库支持与JSON数据的交互,因此大量的系统使用JSON作为日志存储格式。
 
使用Hive分析数据(均指文本)之前,首先需要为待分析的数据建立一张数据表,然后才可以使用Hive SQL分析这张数据表的数据。这就涉及到我们如何把一行文本数据映射为数据表的列,常规的方式有两种:
 
(1)分隔符
 
 
(2)正则表达式
 
 
但是Hive本身并没有针对JSON数据的解析提供原生的支持方式,仅提供了两个内建函数:get_json_object和json_tuple,用于解析某一列的JSON数据。究其原因主要是JSON格式的数据太过灵活,尤其是存在普通数据与JSON数据结合使用、多层嵌套、JSON对象和JSON数组对象结合使用的场景下,常规的数据解析方式变得捉襟见肘。这也是本文探讨的重点所在。
 
方案
 
1. 普通数据与JSON数据结合使用,其中JSON数据不存在多层嵌套、JSON对象和JSON数组对象结合使用的情况;
 
 
可以认为上述数据以“&_”分隔,data部分数据格式为JSON,针对此情况,我们选用正则的方式为其建立数据表,如下:
 
 
验证数据表解析数据是否正确,
 
 
可见三行数据都正确的被解析,但是我们没有办法直接将“data”的slice_id、status映射为列,我们只能通过get_json_object或json_tuple间接的分析数据。
 
因为get_json_object在解析多列数据的场景下存在性能问题,详情可参考https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-json_tuple,因此这里我们仅讨论json_tuple。
 
实际是我们想要的效果无非是将“data”部分的数据也映射为列,注意到“data”部分的数据全部为key/value的简单非嵌套形式,因此我们可以这么做:
 
 
通过Lateral View(https://cwiki.apache.org/confluence/display/Hive/LanguageManual+LateralView)的方式我们借助json_tuple的方式得到了全部的数据列。很显然如果让我们的用户每次分析数据时都要面对如此复杂的SQL语句编写,这样的方式是很不友好的,可以通过创建视图的方式将这个过程隐藏。
 
 
视图mytable_view帮助我们隐藏了JSON数据与数据列的映射过程,用户分析数据时仅仅需要操纵一个标准列格式的数据视图即可。
 
2. JSON数组对象;
 
get_json_object和json_tuple仅仅能够处理JSON对象,而没有办法处理JSON数组对象,如果我们需要解析的是下述的数据:
 
 
Hive内建的功能是没有办法支持这样的数据解析的,因此我们需要自己扩展。
 
json_tuple能够处理普通的JSON对象,因此我们要做的只是扩展出一个json_array,可以将JSON数组对象转换为一个JSON对象数组即可。
 
注意:这里讨论的JSON对象、JSON数组对象、JSON对象数组元素均为JSON字符串。
 
2.1 创建json_array
 
扩展UDF需要继承GenericUDF,一般情况下需要重写两个方法:initialize、evaluate。
 
initialize核心逻辑如下:
 
(1)参数个数是否为1,这个参数即为JSON数组对象的字符串;
(2)定义参数的转换器,用于后期获取参数值;
(3)定义UDF返回结果类型:字符串数组;
 
 
evaluate核心逻辑如下:
 
(1)判断参数个数是否为1,参数值是否为空,如果参数合法,则获取传入的JSON数组对象字符串jsonArrayStr;
 
 
(2)如果jsonArrayStr为空字符串,则返回null,否则继续下一步;
(3)使用Gson解析jsonArrayStr,如果解析失败,返回null;如果解析成功,需要作出如下判断:
     a. 如果是JSON数组对象,则继续下一步;
     b. 如果不是JSON数组对象,则返回null;
(4)将JSON数组对象的各个“元素”的字符串形式存入result并返回(需要注意不同的“元素”类型获取字符串的方式不同,此处我们忽略null)。
 
 
我们将该类的class文件以及Gson打包为一个独立的jar,存入HDFS,然后通过Hive创建Permanent Function,如下:
 
这样我们就可以开始在Hive SQL中使用函数json_array。
 
2.2 使用json_array
 
(1)建立数据表;
 
因为日志数据为JSON数组字符串,所以我们建立的数据表只能为一列,如下:
 
 
 
(2)使用json_array映射列;
 
每一个JSON数组对象包含两个JSON对象(可以数目不一样),每一个JSON对象包含如下属性:ts、id、log、ip,我们首先映射这些列,如下:
 
 
第一个Lateral View将JSON数组对象(字符串)转换为JSON对象数组(字符串),并通过explode将其转换为一个个JSON对象(字符串);
第二个Lateral View将JSON对象(字符串)“映射”为数据列。
 
我们还可以更进一步,利用同样的方法将“ip”列进行分解,如下:
 
 
我们还可以通过前面讲述过的创建视图的方法将上述映射过程隐藏,在此不再赘述。
 
总结
 
通过Hive内建函数json_tuple以及我们自己扩展的json_array,两者相互组合可以非常灵活的完成JSON数据的“映射”,并且可以通过创建视图的方式将“映射”过程隐藏。
 
同时我们也需要注意到,JSON本身是一种非常灵活的数据格式,但实际应用中也不能滥用,如:避免多层嵌套、数据结构不统一等,否则使用Hive分析JSON日志数据时会比较繁琐。

Hive JSON数据处理的一点探索的更多相关文章

  1. Spark SQL JSON数据处理

    背景   这一篇可以说是“Hive JSON数据处理的一点探索”的兄弟篇.   平台为了加速即席查询的分析效率,在我们的Hadoop集群上安装部署了Spark Server,并且与我们的Hive数据仓 ...

  2. 【多端应用开发系列1.1.1 —— Android:使用新浪API V2】服务器Json数据处理——Json数据概述

    [前白] 一些基础的东西本系列中就不再详述了,争取尽量写些必不可少的技术要点. 由于本系列把Web Service 构建放到了第二部分,Android项目就采用新浪微博API v2作为服务器端. [原 ...

  3. iOS开发——数据解析Swift篇&简单json数据处理

    简单json数据处理 //loadWeather var url = NSURL(string: "http://www.weather.com.cn/adat/sk/101240701.h ...

  4. C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化

    在前两篇文章中,我们已经完成对普通对象以及复杂对象嵌套的序列化与反序列化,见如下地址: C++对象的JSON序列化与反序列化探索 C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化 ...

  5. C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化

    本文是基本上一篇博文进行改进而成,上一篇请见: C++对象的JSON序列化与反序列化探索 此处就不多说了,直接上代码. 1. 序列化基类 #pragma once #include <strin ...

  6. python接口自动化(十九)--Json 数据处理---实战(详解)

    简介 上一篇说了关于json数据处理,是为了断言方便,这篇就带各位小伙伴实战一下.首先捋一下思路,然后根据思路一步一步的去实现和实战,不要一开始就盲目的动手和无头苍蝇一样到处乱撞,撞得头破血流后而放弃 ...

  7. Python 关于Python函数参数传递方式的一点探索

    关于Python函数参数传递方式的一点探索 by:授客 QQ:1033553122 实践代码 #!/usr/bin/env python # -*- coding:utf-8 -*- __author ...

  8. JSON数据处理框架Jackson精解第一篇-序列化与反序列化核心用法

    Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制.它提供了很 ...

  9. python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)

    简介 有些 post 的请求参数是 json 格式的,这个前面发送post 请求里面提到过,需要导入 json模块处理.现在企业公司一般常见的接口因为json数据容易处理,所以绝大多数返回数据也是 j ...

随机推荐

  1. Oracle 11g gateways(透明网关)配置

    配置要点主要有三点: 1.%GATEWAYS_HOME%(透明网关安装目录)\dg4msql\admin\initdg4msql.ora 内容: HS_FDS_CONNECT_INFO=localho ...

  2. Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法

    Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法 Ext.Net GridPanel可以进行Group操作,例如: 如何启用Grouping功能呢?只需要在Grid ...

  3. iOS支付宝集成步骤;王刚韧的技术博客

  4. html结构,第一节

    第1步: 新建一个txt文件,重命名为index.html; 第2步: 打开方式:记事本,输入下面代码: <html> <head> <title>我的第一个网页& ...

  5. UVA 11300 Spreading the Wealth (数学推导 中位数)

    Spreading the Wealth Problem A Communist regime is trying to redistribute wealth in a village. They ...

  6. IF EXIST: The syntax of the command is incorrect.

    Batch 脚本中使用 IF EXIST 语句时,总是提示 The syntax of the command is incorrect. 原始 bat 脚本如下: ECHO OFF SET proj ...

  7. 修复Windows7的便签问题

    工作的时候,喜欢利用Windows的附件“便签”,将自己要做的事情一一列在上面,显示在桌面上, 今天突然发现便签损坏,系统是元数据损坏,后来在网上查到解决方法,特此记录: 1. 以管理员身份运行 cm ...

  8. 远程mysql出现ERROR 1130 (HY000): Host '172.17.42.1' is not allowed to connect to this MySQL server

    ERROR 1130: Host ***.***.***.*** is not allowed to connect to this MySQL server 说明所连接的用户帐号没有远程连接的权限, ...

  9. 【笔记-前端】div+css排版基础,以及错误记录

    现在的网站对于前端的排版已经逐渐不使用<table>,而是使用div+css. 使用这种方法的最大好处就在于在维护页面时,可以只维护css而不去改动html. 可是这种方式对于初学者来说可 ...

  10. 关于datagridview单元格不切换焦点无法获得新输入数据的问题解决方法

    问题描述:将EXCEL中的数据导入到dataGridView中,然后通过点击toolStripButton对dataGrideView中的数据进行处理,在测试时,向dataGridView中的某个单元 ...