文章目录
函数
在hive中存在系统自带的函数, 如果说自带的函数不能满足开发需求的时候, 就必须编写自定义函数
查看系统自带的函数
ow functions
================
tab_name
!
!=
%
...
...
xpath_short
xpath_string
year
=================
自定义函数
主要是为了对hive中函数进行扩展, 因为hive中虽然自定义了一些函数, 但是在实际开发中基本上是满足不了需求的, 就需要自定义函数
创建自定义函数的步骤
需要hive jar包的环境, 可以使用maven, 也可以直接导入hive中jar包
- 解压hive安装包, 在lib路径下的所有jar包拷贝到项目中, build path
- 如果要想自定义函数的开发, 则自定义创建的类, 必须继承自UDF
import org.apache.hadoop.hive.ql.exec.UDF;
- 创建自定义函数
import org.apache.hadoop.hive.ql.exec.UDF;
public class Myudf extends UDF {
// 需要实现evaluate函数
public String evaluate(String s) {
if (s == null) {
return null;
}
return s.toString().toUpperCase();
}
}
对于以上的自定义函数, 完成之后需要打成jar包上传到服务器中
- 打成jar包, 通过eclipse导出
- 把导出的jar包与hive进行关联, 添加到hive的classpath中
add jar /home/hadoop/data/myUdf.jar;
- 创建临时函数, 与开发好的Javaclass进行关联
create temporary function myUdf as 'com.hive.udf.Myudf';
- 在hive中使用自定义函数
select name ,myudf(name) from student;
压缩和存储格式
在hive中压缩的目的是为了节省数据传输的带宽, hive中底层运行的是MapReduce, 在设置压缩的时候有以下几种格式:
bin/hadoop checknative
------------------------------------
hadoop: true /opt/app/hadoop-2.7.2/lib/native/libhadoop.so.1.0.0
zlib: true /lib64/libz.so.1
snappy: false
lz4: true revision:99
bzip2: false
对于hadoop支持的压缩格式, 在hive中设置压缩格式之后就可以使用, 但是对于不支持的压缩格式, 需要安装编译
压缩
map阶段的输出, 减少map到reduce之间的数据传输量
开启map端输出压缩配置
- 开启传输压缩的功能
<property>
<name>hive.exec.compress.intermediate</name>
<value>true</value>
----------- <description>
这个是开启压缩
</description>
</property>
- 开启MapReduce中map的输出压缩功能
set mapreduce.map.output.compress=true;
- 设置MapReduce中map输出压缩的方式
set mapreduce.map.output.compress.codec;
-----------------------------------------
mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
由于没有安装snappy 首先使用默认压缩方式进行压缩
- 执行查询语句
select count(*) from emp;
开启reduce端的输出压缩
- 开启最终的输出压缩功能
hive (default)> set hive.exec.compress.output=true;
- 开启最终输出压缩的设置
hive (default)> set mapreduce.output.fileoutputformat.compress=true;
- 设置最终输出压缩的方式
hive (default)> set mapreduce.output.fileoutputformat.compress.codec;
mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
- 最终输出数据格式
hive (default)> set mapreduce.output.fileoutputformat.compress.type;
mapreduce.output.fileoutputformat.compress.type=RECORD
//这里默认是RECORD,也可以设置成BLOCK
- 查看输出的数据是否是压缩文件
insert overwrite local directory '/home/hadoop/data' select * from emp distribute by deptno sort by empno desc;
---------------------------------------------
cat /home/hadoop/data/000000_0.deflate
---------------------------------------------
ly▒!▒3 ▒7\▒36▒뒹▒t▒v▒▒▒[▒E▒▒▒;▒F▒▒g▒mb▒q▒▒8;▒▒▒p▒"▒y▒o▒▒kaV▒▒s▒a▒▒R▒|▒[
文件的存储格式
file_format:
: SEQUENCEFILE
| TEXTFILE -- (Default, depending on hive.default.fileformat configuration)
| RCFILE -- (Note: Available in Hive 0.6.0 and later)
| ORC -- (Note: Available in Hive 0.11.0 and later)
| PARQUET -- (Note: Available in Hive 0.13.0 and later)
| AVRO -- (Note: Available in Hive 0.14.0 and later)
| JSONFILE -- (Note: Available in Hive 4.0.0 and later)
| INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
- TEXTFILE : hive中默认的存储格式, 该文件格式是按照行进行存储的.
- ORC: 在hive 0 .11版本之后引用的存储格式, 可以存放索引 index , row data 存放具体的数据, findex 下标数据
- JSONFILE: 可以通过web前端, 编写js 埋点, 进行事件处理, 生成json数据, 传输到后台, 以json的格式进行存储
- PARQUET : 同样也是面向列式的存储格式, 以二进制的方式保存.
列式存储和行式存储
行式存储的特点:
存储数据的时候, 以一行数据为准进行存储, 在检索的时候方便检索相邻字段. 检索相邻字段的时候效率快, 但是对于如果存在大量数据的时候, 检索单个字段的时候会把所有行的数据全部检索出来.
列式存储的特点:
每个字段都在数据列上进行存储, 和相邻的字段关联不大, 这样的话在检索的时候, 尤其是检索少数列的时候, 增加了检索的效率, 节省了缓存数据的空间.
安装snappy压缩支持
- 解压snappy
[hadoop@hadoop apache-hive-1.2.1-bin]$ tar -zxvf ~/data/native-2.7.3-snappy.tar.gz
- 替换解压之后本地库的native
[hadoop@hadoop apache-hive-1.2.1-bin]$ mv native native.bak
- 关闭集群, 分发到各个节点, 重启集群
scp -r /opt/app/hadoop-2.7.2/lib/native hadoop02:/opt/app/hadoop-2.7.2/lib/native
sbin/stop-all.sh
sbin/start-dfs.sh
sbin/start-yarn.sh
调优
fetch 抓取
hive在运行查询任务的时候, 很多时候都会运行MapReduce任务, 在某些情况下, 不需要运行MapReduce任务, 这个时候就可以进行一些设置, 设置什么情况下运行MapReduce任务, 什么时候不运行MapReduce任务
<property>
<name>hive.fetch.task.conversion</name>
<value>more</value>
<description>
Expects one of [none, minimal, more].
Some select queries can be converted to single FETCH task minimizing latency.
Currently the query should be single sourced not having any subquery and should not have
any aggregations or distincts (which incurs RS), lateral views and joins.
0. none : disable hive.fetch.task.conversion
1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only
2. more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
</description>
</property>
- none : disable hive.fetch.task.conversion, 在运行任何查询语句的时候, 都会运行MapReduce任务
set hive.fetch.task.conversion=none;
-
minimal : SELECT STAR, FILTER on partition columns, LIMIT only
-
more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns) , 默认的方式, 以下查询方式不运行MapReduce任务
//使用 * 的时候不运行MapReduce任务
select * from emp;
//使用单个字段的方式不运行MapReduce任务
select ename from emp;
//使用limit的时候不运行MapReduce任务
select ename from emp limit 1;
本地模式
hive中的本地模式, 在hive所在的本地节点上, 运行小量的数据, 这样就不会涉及到集群分配资源, 在小数据量的情况下, 效率会高很多
<property>
<name>hive.exec.mode.local.auto</name>
<value>false</value>
<description>Let Hive determine whether to run in local mode automatically</description>
</property>
set hive.exec.mode.local.auto=true;
可以通过以上两种方式开启本地模式, hive会自动判断数据量, 如果数据量较大会在集群上运行, 如果数据量较小, 则会在本地节点上运行.
可以通过以下属性进行文件大小的设置
set hive.exec.mode.local.auto.inputbytes.max==134217728
设置MapReduce最大文件输入量, 如果超过该数量则再集群中运行任务, 没有超过该数据则再本地节点上运行
set hive.exec.mode.local.auto.input.files.max=4
测试本地模式:
select * from emp cluster by deptno;
开启本地模式之前:
Time taken: 11.851 seconds, Fetched: 14 row(s)
开启本地模式之后
Time taken: 1.378 seconds, Fetched: 14 row(s)
日志分析
"27.38.5.159" "-" "31/Aug/2015:00:04:37 +0800" "GET /course/view.php?id=27 HTTP/1.1" "303" "440" - "http://www.qianfeng.com/user.php?act=mycourse" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "-" "learn.qianfeng.com"
- 建库
create database if not exists qianfeng_test;
- 建表(字段)
create table IF NOT EXISTS qianfeng_source (
remote_addr string,
remote_user string,
time_local string,
request string,
status string,
body_bytes_sent string,
request_body string,
http_referer string,
http_user_agent string,
http_x_forwarded_for string,
host string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
stored as textfile ;
- 将数据加载到HDFS上, 通过hive对其映射成一张表
load data local inpath '/data/moodle.qianfeng.access.log' into table qianfeng_source;
-
对于以上数据加载之后, 发现实际上导入的数据与源数据不一致, 出现丢失的数据, 经过分析之后发现, 一个字段存在多个空格, 一个字段被切分成多个
-
经过分析, 可以使用正则表达式进行匹配. 以下为hive观望中提供的正则表达式建表实例
CREATE TABLE apachelog (
host STRING,
identity STRING,
user STRING,
time STRING,
request STRING,
status STRING,
size STRING,
referer STRING,
agent STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "([^]*) ([^]*) ([^]*) (-|\\[^\\]*\\]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\".*\") ([^ \"]*|\".*\"))?"
)
STORED AS TEXTFILE;
- 建立正则表达式
"(\"[^ ]*\") (\"[-|^ ]*\") (\"[^}]*\") (\"[^}]*\") (\"[0-9]*\") (\"[0-9]*\") ([-|^ ]*) (\"[^ ]*\") (\"[^}]*\") (\"[-|^ ]*\") (\"[^ ]*\")"
- 重新建表
create table IF NOT EXISTS qianfeng_source (
remote_addr string,
remote_user string,
time_local string,
request string,
status string,
body_bytes_sent string,
request_body string,
http_referer string,
http_user_agent string,
http_x_forwarded_for string,
host string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(\"[^ ]*\") (\"[-|^ ]*\") (\"[^}]*\") (\"[^}]*\") (\"[0-9]*\") (\"[0-9]*\") ([-|^ ]*) (\"[^ ]*\") (\"[^}]*\") (\"[-|^ ]*\") (\"[^ ]*\")"
)
STORED AS TEXTFILE;