Hive Streaming 追加 ORC 文件
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 文件的更多相关文章
- Hive Hadoop 解析 orc 文件
解析 orc 格式 为 json 格式: ./hive --orcfiledump -d <hdfs-location-of-orc-file> 把解析的 json 写入 到文件 ./hi ...
- 大数据:Hive - ORC 文件存储格式
一.ORC File文件结构 ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache ...
- Hive - ORC 文件存储格式【转】
一.ORC File文件结构 ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache ...
- hive streaming 使用shell脚本
一.HIVE streaming 在Hive中,需要实现Hive中的函数无法实现的功能时,就可以用Streaming来实现.其原理可以理解成:用HQL语句之外的语言,如Python.Shell来实现这 ...
- spark SQL读取ORC文件从Driver启动到开始执行Task(或stage)间隔时间太长(计算Partition时间太长)且产出orc单个文件中stripe个数太多问题解决方案
1.背景: 控制上游文件个数每天7000个,每个文件大小小于256M,50亿条+,orc格式.查看每个文件的stripe个数,500个左右,查询命令:hdfs fsck viewfs://hadoop ...
- hive自定义函数——hive streaming
Hadoop Streaming提供了一个便于进行MapReduce编程的工具包,使用它可以基于一些可执行命令.脚本语言或其他编程语言来实现Mapper和 Reducer,Streaming方式是基于 ...
- Hive存储格式之ORC File详解,什么是ORC File
目录 概述 文件存储结构 Stripe Index Data Row Data Stripe Footer 两个补充名词 Row Group Stream File Footer 条纹信息 列统计 元 ...
- oracle数据库表空间追加数据库文件方法
oracle数据库表空间追加数据库文件方法 针对非大文件方式表空间,允许追加文件进行表空间的扩展,单个文件最大大小是32G 第一种方式:表空间增加数据文件 www.2cto.com 1 ...
- shell脚本实现覆盖写文件和追加写文件
1.覆盖写文件 ">" date > not_append_file.txt
随机推荐
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等.在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆一样 ...
- C++混合编程之idlcpp教程Lua篇(3)
上一篇 C++混合编程之idlcpp教程Lua篇(2) 是一个 hello world 的例子,仅仅涉及了静态函数的调用.这一篇会有新的内容. 与LuaTutorial0相似,工程LuaTutoria ...
- [ASE][Daily Scrum]11.25
View Shilin Liu 修复现有的bug,子弹无法破坏射程内视野外的墙 Yiming Liao 无法看见从视野外到视野内的子弹 Server Songtao He 服务器处理子弹命中t ...
- Razor视图引擎输出没有编码的 Html 字符串
优先选择: @Html.Raw(mystring) 在MVC 3中,你可以这样: ViewBag.Stuff = "<li>Menu</li>" 在视图中也 ...
- Dynamic CRM 2013学习笔记(十八)根据主表状态用JS控制子表自定义按钮
有时要根据主表的审批状态来控制子表上的按钮要不要显示,比如我们有一个需求审批通过后就不能再上传文件了. 首先打开Visual Ribbon Editor, 如下图,我们可以利用Enable Rules ...
- 用SQL语句断开某个数据库的所有活动连接
每次一执行完一个数据库脚本,想要做一些别的操作的时候(比如还原数据库),老是有数据库活动连接,烦不胜烦(如下图所示). 下面给出一种删除数据库活动连接的方式.将下面代码段中的“--修改一下”处的数据库 ...
- [安卓] 4、CheckBox、RadioButton和Toast简单用法
和按钮类似,这里采用cb1.setOnCheckedChangeListener(this);方法分别对3个CheckBox进行CheckChange事件绑定,然后在onCheckedChange ...
- 安全性之DDOS的防护技巧
网站的信息安全越来越重要,结合自己1年多的互联网金融方面的安全防护做些总结. 后续希望研究并运用: 1.加密算法 2.DDOS的防护技巧 3.跨站点请求伪造 4.XSS攻击 5.文件上传漏洞 6.信息 ...
- CSS3与页面布局学习总结
目录 一.BFC与IFC 1.1.BFC与IFC概要 1.2.如何产生BFC 1.3.BFC的作用与特点 二.定位 2.2.relative 2.3.absolute 2.4.fixed 2.5.z- ...
- Atitti.java exp ast java表达式语法ast构造器
Atitti.java exp ast java表达式语法ast构造器 /atiplat_cms/src/com/attilax/lang/AstParser.java 原理 分割tokens_sli ...