1.概述

  在存储业务数据的时候,随着业务的增长,Hive 表存储在 HDFS 的上的数据会随时间的增加而增加,而以 Text 文本格式存储在 HDFS 上,所消耗的容量资源巨大。那么,我们需要有一种方式来减少容量的成本。而在 Hive 中,有一种 ORC 文件格式可以极大的减少存储的容量成本。今天,笔者就为大家分享如何实现流式数据追加到 Hive ORC 表中。

2.内容

2.1 ORC

  这里,我们首先需要知道 Hive 的 ORC 是什么。在此之前,Hive 中存在一种 RC 文件,而 ORC 的出现,对 RC 这种文件做了许多优化,这种文件格式可以提供一种高效的方式来存储 Hive 数据,使用 ORC 文件可以提供 Hive 的读写以及性能。其优点如下:

  • 减少 NameNode 的负载
  • 支持复杂数据类型(如 list,map,struct 等等)
  • 文件中包含索引
  • 块压缩
  • ...

  结构图(来源于 Apache ORC 官网)如下所示:

  这里笔者就不一一列举了,更多详情,可以阅读官网介绍:[入口地址]

2.2 使用

  知道了 ORC 文件的结构,以及相关作用,我们如何去使用 ORC 表,下面我们以创建一个处理 Stream 记录的表为例,其创建示例 SQL 如下所示:

create table alerts ( id int , msg string )
partitioned by (continent string, country string)
clustered by (id) into 5 buckets
stored as orc tblproperties("transactional"="true"); // currently ORC is required for streaming

  需要注意的是,在使用 Streaming 的时候,创建 ORC 表,需要使用分区分桶。

  下面,我们尝试插入一下数据,来模拟 Streaming 的流程,代码如下所示:

String dbName = "testing";
String tblName = "alerts";
ArrayList<String> partitionVals = new ArrayList<String>(2);
partitionVals.add("Asia");
partitionVals.add("India");
String serdeClass = "org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe"; HiveEndPoint hiveEP = new HiveEndPoint("thrift://x.y.com:9083", dbName, tblName, partitionVals);

  如果,有多个分区,我们这里可以将分区存放在分区集合中,进行加载。这里,需要开启 metastore 服务来确保 Hive 的 Thrift 服务可用。

//-------   Thread 1  -------//
StreamingConnection connection = hiveEP.newConnection(true);
DelimitedInputWriter writer = new DelimitedInputWriter(fieldNames,",", endPt);
TransactionBatch txnBatch = connection.fetchTransactionBatch(10, writer);
///// Batch 1 - First TXN
txnBatch.beginNextTransaction();
txnBatch.write("1,Hello streaming".getBytes());
txnBatch.write("2,Welcome to streaming".getBytes());
txnBatch.commit();
if(txnBatch.remainingTransactions() > 0) {
///// Batch 1 - Second TXN
txnBatch.beginNextTransaction();
txnBatch.write("3,Roshan Naik".getBytes());
txnBatch.write("4,Alan Gates".getBytes());
txnBatch.write("5,Owen O’Malley".getBytes());
txnBatch.commit();
txnBatch.close();
connection.close();
}
txnBatch = connection.fetchTransactionBatch(10, writer);
///// Batch 2 - First TXN
txnBatch.beginNextTransaction();
txnBatch.write("6,David Schorow".getBytes());
txnBatch.write("7,Sushant Sowmyan".getBytes());
txnBatch.commit();
if(txnBatch.remainingTransactions() > 0) {
///// Batch 2 - Second TXN
txnBatch.beginNextTransaction();
txnBatch.write("8,Ashutosh Chauhan".getBytes());
txnBatch.write("9,Thejas Nair" getBytes());
txnBatch.commit();
txnBatch.close();
}
connection.close();

  接下来,我们对 Streaming 数据进行写入到 ORC 表进行存储。实现结果如下图所示:

3.案例

  下面,我们来完成一个完整的案例,有这样一个场景,每天有许多业务数据上报到指定服务器,然后有中转服务将各个业务数据按业务拆分后转发到各自的日志节点,再由 ETL 服务将数据入库到 Hive 表。这里,我们只说说入库 Hive 表的流程,拿到数据,处理后,入库到 Hive 的 ORC 表中。具体实现代码如下所示:

/**
* @Date Nov 24, 2016
*
* @Author smartloli
*
* @Email smartdengjie@gmail.com
*
* @Note TODO
*/
public class IPLoginStreaming extends Thread {
private static final Logger LOG = LoggerFactory.getLogger(IPLoginStreaming.class);
private String path = ""; public static void main(String[] args) throws Exception {
String[] paths = SystemConfigUtils.getPropertyArray("hive.orc.path", ",");
for (String str : paths) {
IPLoginStreaming ipLogin = new IPLoginStreaming();
ipLogin.path = str;
ipLogin.start();
}
} @Override
public void run() {
List<String> list = FileUtils.read(this.path);
long start = System.currentTimeMillis();
try {
write(list);
} catch (Exception e) {
LOG.error("Write PATH[" + this.path + "] ORC has error,msg is " + e.getMessage());
}
System.out.println("Path[" + this.path + "] spent [" + (System.currentTimeMillis() - start) / 1000.0 + "s]");
} public static void write(List<String> list)
throws ConnectionError, InvalidPartition, InvalidTable, PartitionCreationFailed, ImpersonationFailed, InterruptedException, ClassNotFoundException, SerializationError, InvalidColumn, StreamingException {
String dbName = "default";
String tblName = "ip_login_orc";
ArrayList<String> partitionVals = new ArrayList<String>(1);
partitionVals.add(CalendarUtils.getDay());
String[] fieldNames = new String[] { "_bpid", "_gid", "_plat", "_tm", "_uid", "ip", "latitude", "longitude", "reg", "tname" }; StreamingConnection connection = null;
TransactionBatch txnBatch = null; try { HiveEndPoint hiveEP = new HiveEndPoint("thrift://master:9083", dbName, tblName, partitionVals);
HiveConf hiveConf = new HiveConf();
hiveConf.setBoolVar(HiveConf.ConfVars.HIVE_HADOOP_SUPPORTS_SUBDIRECTORIES, true);
hiveConf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
connection = hiveEP.newConnection(true, hiveConf);
DelimitedInputWriter writer = new DelimitedInputWriter(fieldNames, ",", hiveEP);
txnBatch = connection.fetchTransactionBatch(10, writer); // Batch 1
txnBatch.beginNextTransaction();
for (String json : list) {
String ret = "";
JSONObject object = JSON.parseObject(json);
for (int i = 0; i < fieldNames.length; i++) {
if (i == (fieldNames.length - 1)) {
ret += object.getString(fieldNames[i]);
} else {
ret += object.getString(fieldNames[i]) + ",";
}
}
txnBatch.write(ret.getBytes());
}
txnBatch.commit(); } finally {
if (txnBatch != null) {
txnBatch.close();
}
if (connection != null) {
connection.close();
}
}
}
}

  PS:建议使用多线程来处理数据。

4.预览

  实现结果如下所示:

  • 分区详情

  • 该分区下记录数

5.总结

  在使用 Hive Streaming 来实现 ORC 追加的时候,除了表本身需要分区分桶以外,工程本身的依赖也是复杂,会设计 Hadoop Hive 等项目的依赖包,推荐使用 Maven 工程来实现,由 Maven 工程去帮我们解决各个 JAR 包之间的依赖问题。

6.结束语

  这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

Hive Streaming 追加 ORC 文件的更多相关文章

  1. Hive Hadoop 解析 orc 文件

    解析 orc 格式 为 json 格式: ./hive --orcfiledump -d <hdfs-location-of-orc-file> 把解析的 json 写入 到文件 ./hi ...

  2. 大数据:Hive - ORC 文件存储格式

    一.ORC File文件结构 ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache ...

  3. Hive - ORC 文件存储格式【转】

    一.ORC File文件结构 ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache ...

  4. hive streaming 使用shell脚本

    一.HIVE streaming 在Hive中,需要实现Hive中的函数无法实现的功能时,就可以用Streaming来实现.其原理可以理解成:用HQL语句之外的语言,如Python.Shell来实现这 ...

  5. spark SQL读取ORC文件从Driver启动到开始执行Task(或stage)间隔时间太长(计算Partition时间太长)且产出orc单个文件中stripe个数太多问题解决方案

    1.背景: 控制上游文件个数每天7000个,每个文件大小小于256M,50亿条+,orc格式.查看每个文件的stripe个数,500个左右,查询命令:hdfs fsck viewfs://hadoop ...

  6. hive自定义函数——hive streaming

    Hadoop Streaming提供了一个便于进行MapReduce编程的工具包,使用它可以基于一些可执行命令.脚本语言或其他编程语言来实现Mapper和 Reducer,Streaming方式是基于 ...

  7. Hive存储格式之ORC File详解,什么是ORC File

    目录 概述 文件存储结构 Stripe Index Data Row Data Stripe Footer 两个补充名词 Row Group Stream File Footer 条纹信息 列统计 元 ...

  8. oracle数据库表空间追加数据库文件方法

    oracle数据库表空间追加数据库文件方法   针对非大文件方式表空间,允许追加文件进行表空间的扩展,单个文件最大大小是32G  第一种方式:表空间增加数据文件    www.2cto.com   1 ...

  9. shell脚本实现覆盖写文件和追加写文件

    1.覆盖写文件 ">" date  > not_append_file.txt

随机推荐

  1. 安装SQLSERVER2012遇到的一些问题

    安装SQLSERVER2012遇到的一些问题 先到MSDN我告诉你http://msdn.itellyou.cn/下载安装包,我每次都到MSDN我告诉你里下载的,因为那里的安装包保证能用 我的环境是: ...

  2. Dynamic CRM 2015学习笔记 系列汇总

    这里列出所有 Dynamic CRM 2015学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址:Dynamic CRM 2015学习笔记 系列汇总 一 ...

  3. JavaScript严谨模式(Strict Mode)

    下面的内容翻译自It’s time to start using JavaScript strict mode,作者Nicholas C.Zakas参与了YUI框架的开发,并撰写了多本前端技术书籍,在 ...

  4. Memcached使用小记

    该文章简单记录一下在Windows平台下安装与配置Memcached的方法,Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载. 1.下载Memcached ...

  5. SQL Server FileStream

    以往我们对文件管理有两种方法: 数据库只保存文件的路径,具体的文件保存在文件服务器(NFS)上,使用时,编程实现从文件服务器读取文件: 将文件直接以varbinary(max)或image数据类型保存 ...

  6. servlet servlet请求与响应

    request 客户端浏览器发出的请求被封装成一个HttpServletRequest对象.所有的信息包括请求的地址,请求的参数,提交的数据,上传的文件,客户端的Ip地址甚至客户端操作系统都包含在Ht ...

  7. atitit.设计模式(2) -----查表模式/ command 总结

    atitit.设计模式(2) -----查表模式/ command 总结 1. 应用场景: 1 1. 取代一瓦if else 1 2. 建设api rpc风格的时候儿. 1 3. 菜单是Command ...

  8. iOS开发-NSURLSession详解

    Core Foundation中NSURLConnection在2003年伴随着Safari浏览器的发行,诞生的时间比较久远,iOS升级比较快,AFNetWorking在3.0版本删除了所有基于NSU ...

  9. 解决JS传参中文乱码

    function PopupFK(cNum,type){ var url = "contract!Paying.action"; url = url + "?contra ...

  10. Linux Netcat 命令——网络工具中的瑞士军刀

    原文:http://www.oschina.net/translate/linux-netcat-command netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据.通过与其他 ...