hive的实践部分
一.hive的事务
(1)什么是事务
要知道hive的事务,首先要知道什么是transaction(事务)?事务就是一组单元化操作,这些操作要么都执行,要么都不执行,是一个不可分割的工作单位。
事务有四大特性:A、C、I、D (原子性、一致性、隔离性、持久性)
Atomicity: 不可再分割的工作单位,事务中的所有操作要么都发,要么都不发。
Consistency: 事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的 一致性。
Isolation: 多个事务并发访问,事务之间是隔离的
Durability: 意味着在事务完成以后,该事务锁对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
(2)hive事务的特点与局限性
从hive的0.14版本开始支持低等级的事务
支持事务的增删改查,从hive的2.2版本开始,开始支持merge
不支持事务的begin、commit以及rollback(事务的回滚)
不支持使用update更新分桶列和分区列
想使用事务的话,文件格式必须是ORC
表必须是分桶表
需要压缩工作,需要时间,资源和空间
支持S(共享锁)和X(排它锁)
不允许从一个非ACID连接写入/读取ACID表
(3)hive的事务开启
hive的事务开启有三种方式:a.通过Ambari UI-Hive Config
b.通过hive-xml 的配置文件添加如下内容
<property>
<name>hive.support.concurrency</name>
<value>true</value>
</property>
<property>
<name>hive.txn.manager</name>
<value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
</property>
c.通过命令行,在beeline这种交互式环境下:
set hive.support.concurrency = true;
set hive.enforce.bucketing = true;
set hive.exec.dynamic.partition.mode = nonstrict;
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.compactor.initiator.on = true;
set hive.compactor.worker.threads = 1;
(4)hive的merge
merge的语法:
MERGE INTO <target table> AS T USING <source expression/table> AS S ON <boolean expression1>
WHEN MATCHED [AND <boolean expression2>] THEN UPDATE SET <set clause list>
WHEN MATCHED [AND <boolean expression3>] THEN DELETE
WHEN NOT MATCHED [AND <boolean expression4>] THEN INSERT VALUES<value list>
merge的局限性:
最多三条when语句,只支持update/delete/insert。when not matched 必须在when语句的最后面。
如果出现update和delete的时候 ,两个条件是分开的,而且必须在条件前面加上AND.像 [AND <boolean expression>]
(5)例子
a.创建两个事务表
CREATE TABLE IF NOT EXISTS employee (
emp_id int,
emp_name string,
dept_name string,
work_loc string )
PARTITIONED BY (start_date string)
CLUSTERED BY (emp_id) INTO 2 BUCKETS STORED AS ORC TBLPROPERTIES('transactional'='true'); create table employee_state(
emp_id int,
emp_name string,
dept_name string,
work_loc string,
start_date string,
state string
)
STORED AS ORC;
b.开启事务(见上面的开启事务的c,一般有些默认的设置是开的,我这里就只开了自动分区和分桶)
c.插入数据
INSERT INTO table employee PARTITION (start_date) VALUES (1,'Will','IT','Toronto','20100701'),
(2,'Wyne','IT','Toronto','20100701'),
(3,'Judy','HR','Beijing','20100701'),
(4,'Lili','HR','Beijing','20101201'),
(5,'Mike','Sales','Beijing','20101201'), (6,'Bang','Sales','Toronto','20101201'), (7,'Wendy','Finance','Beijing','20101201'); insert into table employee_state values
(2,’Wyne’,’IT’,’Beijing’,’20100701’,’update’),
(4,’Lili’,’HR’,’Beijing’,’20101201’,’quit’),
(8,’James’,’IT’,’Toronto’,’20170101’,’new’)
d.检验数据是否被插入
e.这里通过merge操作,完成更新、删除、插入操作。
employe字段解释:id为2的员工之前的工作地在Toronto,现在在Beijing,state的状态为update。所以需要更新表employee中员工2的信息
id为4的员工的state状态为quit,说明目前员工已经离职,所以需要在employee表中删除关于id为4的员工的信息。
id为8的员工的state状态为new,说明是新员工,所以需要插入empoyee中。
MERGE INTO employee AS T
USING employee_state AS S
ON T.emp_id = S.emp_id and T.start_date = S.start_date
WHEN MATCHED AND S.state = 'update' THEN UPDATE SET dept_name = S.dept_name,work_loc = S.work_loc
WHEN MATCHED AND S.state = 'quit' THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES(S.emp_id,S.emp_name,S.dept_name,S.work_loc,S.start_date);
--这里目标表为employee,源表为employee_state
--这里新员工是属于第三中情况,未在目标表中匹配到,所以直接插入到目标表中。
二.hive的udf
(1)什么是hive的udf?
User-defined function (UDF): 这提供了一种使用外部函数(在Java中)扩展功能的方法,可以在HQL中进行评估
(2)hive的udf分类
hive的udf一般分为三种:
a.UDF:用户定义的简单函数,按行操作并为一行输出一个结果,例如大多数内置数学和字符串函数
b.UDAF: 用户定义的聚合函数,按行或按组操作,并为每个组输出一行或一行,例如MAX和COUNT内置函数。
c.UDTF:用户定义的表生成函数也按行运行,但结果会生成多行/表,例如EXPLODE函数。 UDTF可以在SELECT之后或在LATERAL VIEW语句之后使用。
(3)hive的udf使用举例
a.对于hive的udf,这里我写了一个把字符串的大写全部换成小写和一个判断字符串是否在一个array数组里面的函数
--将字符串的所有大写改成小写
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text; public final class StringLower extends UDF {
public Text evaluate(final Text s) {
if (s == null) { return null; }
return new Text(s.toString().toLowerCase());
}
}
--判断当前字符串是否在数组里面
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde.serdeConstants;
import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.io.BooleanWritable; @Description(name = "Arraycontains",
value="_FUNC_(array, value) - Returns TRUE if the array contains value.",
extended="Example:\n"
+ " > SELECT _FUNC_(array(1, 2, 3), 2) FROM src LIMIT 1;\n"
+ " true") public class ArrayContains extends GenericUDF {
private static final int ARRAY_IDX = 0;
private static final int VALUE_IDX = 1;
private static final int ARG_COUNT = 2;//这个udf函数需要参数的个数
private static final String FUNC_NAME = "ARRAYCONTAINS";//外部名字 private transient ObjectInspector valueOI;
private transient ListObjectInspector arrayOI;
private transient ObjectInspector arrayElementOI;
private BooleanWritable result;
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
//检查是否传入了两个参数
if (arguments.length != ARG_COUNT) {
throw new UDFArgumentException("the function" + FUNC_NAME + "accepts"
+ ARG_COUNT + "arguments");
}
//检查参数是否是属于LIST类型
if (!arguments[ARRAY_IDX].getCategory().equals(ObjectInspector.Category.LIST)) {
throw new UDFArgumentTypeException(ARRAY_IDX, "\"" + serdeConstants.LIST_TYPE_NAME + "\""
+ "expected at function ARRAY_CONTAINS,but"
+ "\"" + arguments[ARRAY_IDX].getTypeName() + "\""
+ "is found"); } arrayOI = (ListObjectInspector) arguments[ARRAY_IDX];
arrayElementOI = arrayOI.getListElementObjectInspector(); valueOI = arguments[VALUE_IDX]; //检查list的元素和传入的值是否属于同一个类型
if (!ObjectInspectorUtils.compareTypes(arrayElementOI, valueOI)) {
throw new UDFArgumentTypeException(VALUE_IDX, "\"" + arrayElementOI.getTypeName() + "\""
+ "expectd at function ARRAY_CONTAINS,but"
+ "\"" + valueOI.getTypeName() + "\""
+ "is found");
} //检查此类型是否支持比较
if (!ObjectInspectorUtils.compareSupported(valueOI)){
throw new UDFArgumentException("this function" + FUNC_NAME
+"does not support comparison for"
+"\"" + valueOI.getTypeName() + "\""
+ "types"); }
result = new BooleanWritable(false);
return PrimitiveObjectInspectorFactory.writableBooleanObjectInspector;
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
result.set(false);
Object array = arguments[ARRAY_IDX].get();
Object value = arguments[VALUE_IDX].get(); int arrayLength = arrayOI.getListLength(array); //检查数组是否null还是空value是否为null
if (value == null || arrayLength <= 0)//判断value是否为空,若真则不判断右边,不然为假继续判断右边
{
return result;//满足条件直接返回result初始状态值
} //将值与数组的每个元素进行比较,直到找到匹配项
for (int i=0;i<arrayLength;i++){
Object listElement = arrayOI.getListElement(array,i);
if(listElement != null){
if (ObjectInspectorUtils.compare(value,valueOI,listElement,arrayElementOI) == 0){
result.set(true);//找到匹配,直接将result置于真
break;
}
}
} return result;//返回真值result
} @Override
public String getDisplayString(String[] childeren) {
assert (childeren.length == ARG_COUNT);
return "array_contains(" + childeren[ARRAY_IDX] + ","
+ childeren[VALUE_IDX] + ")";
}
}
b.然后通过编译器打包到hdfs文件系统上,通过执行hive命令构造函数
DROP FUNCTION IF EXISTS str_lower;
DROP FUNCTION IF EXISTS Array_contains;
CREATE FUNCTION str_lower AS 'com.data.hiveudf.udf.StringLower'
USING JAR 'hdfs:////apps/hive/functions/df-hiveudf-1.0-SNAPSHOT.jar';
CREATE FUNCTION Array_contains AS 'com.data.hiveudf.gudf.ArrayContains'
USING JAR 'hdfs:////apps/hive/functions/df-hiveudf-1.0-SNAPSHOT.jar';
c.使用自定义函数
这里使用了另一库里的一张employee表,里面使用了string类型、array类型...。表描述与内容如下:
然后使用str_lower的函数:
使用Array_contains函数
hive的实践部分的更多相关文章
- 大数据(2):基于sogou.500w.utf8数据hive的实践
一.环境的搭建 1.安装配置mysql rpm –ivh MySQL-server-5.6.14.rpm rpm –ivh MySQL-client-5.6.14.rpm 启动mysql 创建hive ...
- 《细细品味Hive》系列课程
Hi,博友: 我是解耀伟,笔名是虾皮,最近我在极客学院录制Hive系列教程,也是督促自己学习一种方式,可以把自己的学习积累有方向,星期天也能做点有意义的事情.在做每一期的过程中,需要找资料,总结,先自 ...
- hbase+hive应用场景
一.Hive应用场景本文主要讲述使用 Hive 的实践,业务不是关键,简要介绍业务场景,本次的任务是对搜索日志数据进行统计分析.集团搜索刚上线不久,日志量并不大 .这些日志分布在 5 台前端机,按小时 ...
- DataPipeline在大数据平台的数据流实践
文 | 吕鹏 DataPipeline架构师 进入大数据时代,实时作业有着越来越重要的地位.本文将从以下几个部分进行讲解DataPipeline在大数据平台的实时数据流实践. 一.企业级数据面临的主要 ...
- Hive原理总结(完整版)
目录 课程大纲(HIVE增强) 3 1. Hive基本概念 4 1.1 Hive简介 4 1.1.1 什么是Hive 4 1.1.2 为什么使用Hive 4 1.1.3 Hive的特点 4 1.2 H ...
- 基于hive的日志分析系统
转自 http://www.cppblog.com/koson/archive/2010/07/19/120773.html hive 简介 hive 是一个基于 ...
- hive数据仓库入门到实战及面试
第一章.hive入门 一.hive入门手册 1.什么是数据仓库 1.1数据仓库概念 对历史数据变化的统计,从而支撑企业的决策.比如:某个商品最近一个月的销量,预判下个月应该销售多少,从而补充多少货源. ...
- DataPipeline联合Confluent Kafka Meetup上海站
Confluent作为国际数据“流”处理技术领先者,提供实时数据处理解决方案,在市场上拥有大量企业客户,帮助企业轻松访问各类数据.DataPipeline作为国内首家原生支持Kafka解决方案的“iP ...
- 【学习笔记】大数据技术原理与应用(MOOC视频、厦门大学林子雨)
1 大数据概述 大数据特性:4v volume velocity variety value 即大量化.快速化.多样化.价值密度低 数据量大:大数据摩尔定律 快速化:从数据的生成到消耗,时间窗口小,可 ...
随机推荐
- js匹配日期和时间的正则表达式
自己写比较头疼,copy下来留着以后用 //日期的正则表达式 -]\d{}-([-]|[-])-([-]|[-][-]|[-])$/; var regExp = new RegExp(reg); if ...
- create alter rename desc select update delete insert
conn scott/root;create table student (id number(3), name varchar2(10), sex char(2), sno number(3));a ...
- oracle profile 概要文件
Profile文件概述: Profile是Oracle安全策略的一个组成部分,当Oracle建立数据库时,会自动建立名称为Default的Profile文件. 创建用户的时候,如果没有指定profil ...
- oracle常见的等待事件说明
转自 http://blog.itpub.net/29371470/viewspace-1063994/ 1. Buffer busy waits 从本质上讲,这个等待事件的产生仅说明了一个会话在等待 ...
- CSS深入理解之absolute(HTML/CSS)
absolute和float是同父异母的兄弟,因为它们具有相同点:包裹性与破坏性 absolute的特点 1.独立的,并且可以摆脱overflow的限制,无论是滚动还是隐藏: 2.无依赖,不受rela ...
- vuejs electron webpack集成使用
传统的vue SPA页面在浏览器环境中使用,但是有的时候我们还希望能够做成一个类似于桌面的app在PC上使用,希望不仅可以使用所有的浏览器SPA的功能,你也可能外加host os的功能,比如文件的本地 ...
- 理解和配置Out of memory: Kill process
转自:爱开源 理解 OOM killer 最近有位 VPS 客户抱怨 MySQL 无缘无故挂掉,还有位客户抱怨 VPS 经常死机,登陆到终端看了一下,都是常见的 Out of memory 问题.这通 ...
- openweathermap-免费的天气预报接口
openweathermap-免费的天气预报接口 其官方网址为:http://www.openweathermap.org/api 静态截图: 具备以下的一些特点: 1. Current weathe ...
- 铁乐学python_day01-和python有关的唠嗑
铁乐学python_day01-和python有关的唠嗑 文:铁乐与猫 2018-03-16 01_python的历史 python的创始人为荷兰人吉多·范罗苏姆(Guido van Rossum). ...
- webpack react 单独打包 CSS
webpack react 单独打包 CSS webpack require css的方法,默认会把css 打入到js文件中,加载顺序有问题,如果需要打出独立的css文件 操作步骤: step1: 安 ...