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. codeforces 429D

    题意:给定一个数组你个数的数组a,定义sum(i, j)表示sigma(a[i],...a[j]),以及另外一个函数f(i, j) = (i - j)^2 + sum(i+1, j)^2 求最小的f( ...

  2. 从0开始学Swift笔记整理(三)

    这是跟在上一篇博文后续内容: --Swift中相关的属性 存储属性 Swift中的属性分为存储属性和计算属性,存储属性就是Objective-C中的数据成员,计算属性不存储数据,但可以通过计算其他属性 ...

  3. [Java Web] 1、Web开发初识——一大堆历史和技术名词

    LZ前言 LZ最近发现网络真是个神奇的东西,以前做的好玩的只能自娱自乐(或者说顾影自怜),现在只要发一个帖子,写一个博客,很快能引来一大群小伙伴的围观(有时候还能遇见几个大牛给个战略性的指导)...L ...

  4. Working With Taxonomy Field in CSOM

    How to create taxonomy field with CSOM If you need to programmatic create a taxonomy field, you need ...

  5. ASP.NET MVC中三方登录: 微软、谷歌、Office365

    创建一个MVC的工程,在Startup.Auth.cs文件中,我们能看到这样的一些代码: 这其实是微软已经帮我们实现好的三方登录的接口,我们只需要创建相应的开发者账号,并在其中配置好跟我们应用程序相关 ...

  6. 如何带领一个Android开发团队

    1)重构,夜未眠 将框架从业务中剥离 如何提高开发效率 如何提高程序性能 单元测试 技术调研 代码版本管理 2)渠道包管理 自动打包工具 批量打渠道包的两种解决方案 定制渠道包的流程管理 3)稳定性, ...

  7. Unexpected namespace prefix "xmlns" found for tag Linear Layout

    原文地址http://blog.csdn.net/taxuexumei/article/details/41523419 今天遇到的问题,,,保存到博客里,下回遇到找博客就行了,,,,,, 今天在制作 ...

  8. python+redis测试环境搭建

    针对windows操作系统. redis安装: 微软操作系统下,需下载github下面的开源项目,redis网站地址可以找到,直接解压即可. cmd到指定目录,输入下方命令,启动redis服务. re ...

  9. Atitit.auto complete 自动完成控件的实现总结

    Atitit.auto complete  自动完成控件的实现总结 1. 框架选型 1 2. 自动完成控件的ioc设置 1 3. Liger  自动完成控件问题 1 4. 官网上的code有问题,不能 ...

  10. shiny server SparkR web展示界面(一)

    1. shiny server简介 shiny-server是一种可用把R 语言以web形式展示的服务,下面就讲讲如何在自己的服务器上构建Shiny Server.下一篇主要介绍如何集成sparkR后 ...