Hive 的简单使用及调优参考文档

时间:2021-08-22 00:10:59

Hive 的简单使用及调优参考文档

 

  1. HIVE的使用

    1. 命令行界面

使用一下命令查看hive的命令行页面,

hive --help --service cli 简化命令为hive –h

会输出下面的这些东西

-d,--define <key=value> Variable subsitution to apply to hive

commands. e.g. -d A=B or --define A=B

--database <databasename> Specify the database to use

-e <quoted-query-string> SQL from command line

-f <filename> SQL from files

-H,--help Print help information

-h <hostname> connecting to Hive Server on remote host

--hiveconf <property=value> Use value for given property

--hivevar <key=value> Variable subsitution to apply to hive

commands. e.g. --hivevar A=B

-i <filename> Initialization SQL file

-p <port> connecting to Hive Server on port number

-S,--silent Silent mode in interactive shell

-v,--verbose Verbose mode (echo executed SQL to the

console)

我们常用的 hive –e ,hive –f ,hive –S 和hive –h

演示下上面几个命令的使用示例

  1. Shell页面执行hive命令

假如 希望使用shell脚本把hive库bdp_3 表里的mobile_01_2的表数据导出

hive -e "use bdp_3;select * from mobile_01_2;">11.log

就可以在执行hive命令的当前目录下看到11.log里面有表mobile_01_2的数据了。当然为了切换用户命令也可以省略写成下面的方式,直接在表名前加用户名

hive -e "select * from bdp_3.mobile_01_2;">12.log

  1. Shell脚本中获得HQL统计结果

在shell脚本中获得HQL的统计结果 并赋给一个变量

count=`hive -e "select count(*) from bdp_3.mobile_01_2;"`

echo 'count的值为:'$count

  1. shell执行封装好的HQL脚本文件

封装好的hql 命令放到单独的一个文件里,然后统一在shell 里执行,此时可以使用hive –f 命令

假设在 /root/shell/11.q 文件下有一句HQL

create table bdp_3.test as

select * from bdp_3.mobile_01_2;

执行命令

hive –f /root/shell/11.q

之后就能在数据库里看到这张创建的表了

Hive 的简单使用及调优参考文档

  1. 有趣的几个Hive功能

    1. Hive命令字段补齐

hive 命令字段补全功能,同linux一样,敲命令时候敲一般按TAB键系统会帮助补全关键字,有几个选择的时候会给提示

Hive 的简单使用及调优参考文档

  1. Hive 命令窗口使用 shell 命令

在hive CLI窗口 输入! 加分号结尾就能使用shell 命令了,比如查看当前目录

Hive 的简单使用及调优参考文档

显示当前目录文件

Hive 的简单使用及调优参考文档

这个功能和真正的shell还是有写区别的,可以自己多试试

  1. Hive 使用hadoop的dfs命令

只需要把hadoop 命令中的关键字hadoop 干掉,分号结尾就好了,比如,查看hdfs 根目录 hadoop 命令为 hadoop dfs –ls / 在hive中只需要敲dfs –ls /

Hive 的简单使用及调优参考文档

 

  1. hive 数据导出

hive 数据导出有三种常见的场景

(1)导出到本地文件系统;(2)导出到HDFS中;(3)导出到Hive的另一个表中。

  1. 导出到本地文件系统

insert overwrite local directory '/root/shell/mobile_01_1'

select * from mobile_log_01;

 这条HQL的执行需要启用Mapreduce完成,运行完这条语句之后,将会在本地文件系统的/root/shell/mobile_01_1目录下生成文件,这个文件是Reduce产生的结果(这里生成的文件名是000000_0),我们可以看看这个文件的内容

注:上面使用的都是默认的导出格式,如果需要使用特定的分隔符导出可以使用下面的语句

insert overwrite local directory '/root/shell/mobile_01_3'

row format delimited

fields terminated by '$'

select * from bdp_3.mobile_01_1;

  1. 导出到hdfs中

insert overwrite directory '/root/shell/mobile_01_1'

select * from mobile_log_01;

导出本地和导出到hdfs的区别 就差一个local关键字

 

Hive 还可以使用hive –e 和hive –f 命令来导出数据如同我前面1.1.1一样,我这里就不在讲述

  1. 导出到Hive的另一个表中

这个同常见的sql命令一样,我就不在讲述

 

  1. Hive数据库的一些常见操作

    1. Hive数据库操作

      1. 创建数据库

hive> create database if not exists db_test;

OK

Time taken: 2.3 seconds

  1. 查看数据库

hive> show databases;

OK

bdp

bdp_3

db_test

default

Time taken: 0.526 seconds, Fetched: 4 row(s)

  1. 查看指定的数据库

hive> show databases like 'db*';

OK

db_test

Time taken: 0.075 seconds, Fetched: 1 row(s)Hive 的简单使用及调优参考文档

 

使用 use 命令切换不同的数据库

use bdp_3;

Hive 的简单使用及调优参考文档

 

  1. Hive表操作

    1. Hive查看表

Hive建表我这里不多说了,比较基础,给几个查看表的语句

查看数据库下面的表

hive> show tables;

 

hive> show tables in bdp_3;

 

  1. 显示表的详细信息

 

hive> describe extended bdp_3.mobile_01_1;

 

  1. 查看表分区

hive>show partitions mobile_01_1;

  1. 建表

CREATE TABLE BOSS_05016_HD2

(

feild_1 STRING,

feild_2 STRING,

feild_3 STRING,

feild_4 STRING,

feild_5 STRING,

feild_6 STRING,

feild_7 STRING)

ROW format delimited

fields terminated by'\t' --指定制表符为列分隔符

lines terminated by'\n' --指定换行符为行分隔符(注:目前hive好像只支持换行符为行分隔符,默认也是这样,可以不指定)

;

 

  1. 删除表

hive>drop table if exists mobile_01_1;

 

  1. 重命名表

hive> alter table mobile_01_1 rename to mobile_01_3;

 

  1. 修改表

大多数表可以通过alter table 语句来修改 但是这只会修改表的元数据,表数据本身不会有任何修改

Hive 可以修改表名,表字段名,修改列,增加或者删除列,也可以通过alter table 来删除和添加分区表的分区

这里后续慢慢补充

 

  1. Hive函数

    1. Hive目前支撑的内部函数

可以使用下面命令来查看hive目前支撑的内部函数

hive> show functions;

OK

!

!=

%

&

*

+

-

/

<

<=

<=>

<>

=

==

>

>=

^

abs

acos

and

array

array_contains

ascii

asin

assert_true

atan

avg

base64

between

bin

case

ceil

ceiling

coalesce

collect_set

compute_stats

concat

concat_ws

context_ngrams

conv

corr

cos

count

covar_pop

covar_samp

create_union

cume_dist

date_add

date_sub

datediff

day

dayofmonth

decode

degrees

dense_rank

div

e

elt

encode

ewah_bitmap

ewah_bitmap_and

ewah_bitmap_empty

ewah_bitmap_or

exp

explode

field

find_in_set

first_value

floor

format_number

from_unixtime

from_utc_timestamp

get_json_object

hash

hex

histogram_numeric

hour

if

in

in_file

index

inline

instr

isnotnull

isnull

java_method

json_tuple

lag

last_value

lcase

lead

length

like

ln

locate

log

log10

log2

lower

lpad

ltrim

map

map_keys

map_values

max

min

minute

month

named_struct

negative

ngrams

noop

noopwithmap

not

ntile

nvl

or

parse_url

parse_url_tuple

percent_rank

percentile

percentile_approx

pi

pmod

positive

pow

power

printf

radians

rand

rank

reflect

reflect2

regexp

regexp_extract

regexp_replace

repeat

reverse

rlike

round

row_number

rpad

rtrim

second

sentences

sign

sin

size

sort_array

space

split

sqrt

stack

std

stddev

stddev_pop

stddev_samp

str_to_map

struct

substr

substring

sum

tan

to_date

to_unix_timestamp

to_utc_timestamp

translate

trim

ucase

unbase64

unhex

unix_timestamp

upper

var_pop

var_samp

variance

weekofyear

when

windowingtablefunction

xpath

xpath_boolean

xpath_double

xpath_float

xpath_int

xpath_long

xpath_number

xpath_short

xpath_string

year

|

~

Time taken: 0.106 seconds, Fetched: 191 row(s)

hive>

 

附件为hive函数大全

Hive 的简单使用及调优参考文档

  1. HIVE优化

    1. JOIN 优化

Hive 支持通常的SQL JOIN 语句,但是只支持等值连接

  1. 通过连接顺序优化

分析一个语句

Select * from

table_1 a join table_2 b on a.serv_id = b.serv_id

         join table_3 c on a.serv_id = c.serv_id

 

HIVE的解析执行顺序是按照从左到右,hive对每个join对象启动一个mapreduce任务,首先对 表a和表b进行连接操作 然后将输出结果和表c进行连接操作。

 

所以我们可以通过合理的指定连接表的顺序来优化语句,保证查询顺序中表的大小从左到右依次是增加的。Hive执行时假定查询中最后一个表是最大的表,在对每行记录进行连接操作时,它会先尝试将其他表缓存起来,然后扫描最后那个表进行计算。

  1. 标记大表

Select /*+STREAMTABLE(a) */ * from

table_1 a join table_2 b on a.serv_id = b.serv_id

         join table_3 c on a.serv_id = c.serv_id;

 

通过这个标记来告诉hive 那张表是大表,hive在执行时会尝试将a表作为驱动表。

 

  1. map-side JOIN

如果所有的表中有一张是小表,可以在最大的表通过mapper的时候将小表完全放到内存中,hive可以在map端执行连接过程,因为hive可以和内存中的小表进行逐一匹配,从而省略掉常规连接所需要的reduce过程。

详细解读可以查看

http://tech.ddvip.com/2013-10/1381313795203738.html

hive v0.7版本以前 使用这个优化可以这么写语句

 

select /*MAPJOIN(d) */ s.ymd,s.symbol,d.dividend from

stocks s join dividends s on s.ymd=d.ymd;

 

hive v0.7版本以后,废弃这个标记方式,(增加这个标记同样有用),需设置hive的属性,hive.auto.convert.JOIN的值为true,默认这个属性的值是false。

 

用户可以设置使用这个优化的小表的大小

 

hive.mapjoin.smalltable.filesize=25000000 (默认是25M)

 

注意:hive的right out join 和full out join 不支持这个优化

  1. 使用EXPLAIN 和EXPLAIN EXTENDED

学习hive是如何工作的,第一个步骤就是学习explain 功能,可以帮助我们学习hive是如何将查询

explain select * from boss_05002;

Hive 的简单使用及调优参考文档

explain select count(1) from boss_05002;

Hive 的简单使用及调优参考文档

 

hive> explain select count(1) from boss_05002;

OK

ABSTRACT SYNTAX TREE:

(TOK_QUERY (TOK_FROM (TOK_TABREF (TOK_TABNAME boss_05002))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION count 1)))))

 

STAGE DEPENDENCIES:

Stage-1 is a root stage

Stage-0 is a root stage

 

STAGE PLANS:

Stage: Stage-1

Map Reduce

Alias -> Map Operator Tree:

boss_05002

TableScan

alias: boss_05002

Select Operator

Group By Operator

aggregations:

expr: count(1)

bucketGroup: false

mode: hash

outputColumnNames: _col0

Reduce Output Operator

sort order:

tag: -1

value expressions:

expr: _col0

type: bigint

Reduce Operator Tree:

Group By Operator

aggregations:

expr: count(VALUE._col0)

bucketGroup: false

mode: mergepartial

outputColumnNames: _col0

Select Operator

expressions:

expr: _col0

type: bigint

outputColumnNames: _col0

File Output Operator

compressed: false

GlobalTableId: 0

table:

input format: org.apache.hadoop.mapred.TextInputFormat

output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat

serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

 

Stage: Stage-0

Fetch Operator

limit: -1

 

 

Time taken: 0.314 seconds, Fetched: 52 row(s)

  1. 限制调整

Limit 语句是大家经常用到的,但是很多情况下limit语句还是需要执行这个查询语句,然后返回部分结果,因为这种情况通常是浪费的,所以应该尽可能避免出现这种情况

Hive 有个配置属性可以开启:

hive.limit.optimize.enable

当hive.limit.optimize.enable=true时,有两个对应的参数可以设置

hive.limit.optimize.limit.file和hive.limit.row.max.size

 

注意:这个功能有一个缺陷 ,有可能输入中有用的数据永远不会被处理到,任意一个需要reduce步骤的查询,join和group by操作 以及聚合函数的调用,都会产生不同的结果。

 

  1. 本地模式

大多数的hadoop job 是需要hadoop提供的可扩展性来处理大数据的,不过,有时hive的输入数据量是非常小的,在这种情况下,为查询触发执行任务的时间消耗可能会比实际job的执行时间要多的多,对于大多数这种情况,hive可以通过本地模式在单台机器上处理所有的任务,对于小数据集执行的时间可以明显缩短:

 

用户可以设置hive属性:hive.exec.mode.local.auto = true 来让hive 在适当的时候自动启动这个优化

  1. 并行执行

Hive 会将一个查询转化成一个或多个阶段,这样的阶段可以是mapreduce阶段,抽样阶段,合并阶段,limit阶段,或者hive执行过程中可能需要的其他阶段,默认情况下hive一次性只会执行一个阶段,不过某个特定的job可能包含众多阶段,而这些阶段可能并非完全互相依赖,也就是说这些阶段是可以并行的,这样可以缩短整个job的执行时间缩短。

可以通过设置hive参数 hive.exec.parallel=true 来开启并发执行。

  1. 严格模式

  2. 调整mapper和reduce 个数

Hive通过将查询划分成一个或多个mapreduce任务来达到并行的目的,每个任务都可能具有多个mapper和reducer任务,确定最佳的mapper个数和reducer 个数取决于多个变量,例如输入数据量大小以及对这些数据执行的操作类型等。

 

一般,hive是按照输入的数据量大小来确定reducer 个数的,我们可以通过dfs –count命令来计算输入量大小。可以通过属性 hive.exec.reducers.bytes.per.reducers.bytes.per.reducer来设置。默认值是1GB。Hive默认的reducer个数是3。可以通过设置属性mapred.reduce.tasks的值来设置。

 

在共享集群上处理大任务时,集群可以提供的map和reduce 资源个数是固定的,某个大job可能会消耗完所有的资源二导致其他job无法执行,可以通过设置hive.exec.reducers.max属性来限制某个查询消耗太多的reducer资源。

  1. JVM重用

JVM重用是hadoop调优参数的内容,其对hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或task特别多的场景,这类场景大多数执行时间很短。

 

Hadoop 的默认配置通常是使用派生JVM来执行map和reduce任务的,这是JVM的启动过程可能会造成相当大的开销,尤其是执行的job包含成百上千个task任务的情况下JVM可以使的JVM实例在同一个job中重新使用N次。N的值可以在hadoop的mapred-site.xml文件中进行设置。

 

注意: 这个功能的缺点,开启JVM重用会一直占用使用到的task插槽,以便进行重用,直到任务完成后才释放,如果某个job中 有几个reduce task 执行的时间要比其他的reduce task 消耗的时间多的多的话,那么保留的插槽会一直空闲,直到所有task都结束了才释放。

  1. 索引

索引可以用来加快含有group 不要 语句的查询计算速度。Hive 从 v0.8.0开始增加了一个bitmap 索引实现

  1. 动态分区调整

  2. 推测执行

  3. 单个MapReduce中的 多个GROUP BY

  1. HIVE 压缩

Hive不要求将数据转换成特定的格式才能使用。压缩通常会节约客观的磁盘空间。压缩同样可以增加吞吐量和性能。

  1. hive中的编码器

    1. 查看hive支持的编译器

hive> set io.compression.codecs;

io.compression.codecs=org.apache.hadoop.io.compress.DefaultCodec,

org.apache.hadoop.io.compress.GzipCodec,

org.apache.hadoop.io.compress.BZip2Codec,

org.apache.hadoop.io.compress.DeflateCodec,

org.apache.hadoop.io.compress.SnappyCodec,

org.apache.hadoop.io.compress.Lz4Codec

hive>

 

  1. 选择编译器

BZip2压缩率最高,但是同时消耗 最多的cpu,GZip是压缩率和解压缩速度上的下一个选择。 在需要优先考虑磁盘空间利用率和I/O的情况下,可以优先考虑这两种压缩方式。

 

LZO和Snappy 压缩率比前面两种小,但是 压缩解压速度要快,特别是解压缩过程,如果相对于磁盘空间和I/O开销,频繁的读取数据所需的解压缩速度更重要的话,可以优先考虑这两种方式。

 

另一个重点考虑的因素是压缩文件是否可分割。

 

Mapreduce 需要将非常大的输入文件分割成多个划分(通常一个文件一个划分),每个划分会被分发到单独的map进程中,文本文件每一行一条记录,hadoop知道文件的记录边界。GZip和Snappy 将这些边界信息掩盖了,BZip2和LZO提供了块级别的压缩,每个块含有完整的记录信息,hadoop可以在块级别对这些文件进行划分。

 

  1. 开启中间压缩

对中间数据进行压缩可以减少job中map和reduce task 间的数据传输。对于中间数据压缩,选择一个低cpu开销的编解码器比较合理,推荐使用Snappycodec。可以通过设置属性:hive.exec.compress.intermediate=true来开启中间件压缩。

 

 

 

 

 

 

  1. HIVE 存在的一些其他需要注意的问题

    1. 管理表(内部表)和外部表问题

Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径, 不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。 

 

  1. Hive表的严格(strict)模式和非严格(nostrict)模式

Hive 有一个参数可以用来控制hive是否为严格模式hive.mapred.mod=strict,当处于严格模式下有很多操作是不允许的,比如,不加limit 的全表查询,表的笛卡尔积 join 操作,分区表不加分区过滤的查询 ,orderby不加limit的查询

可参考:http://blog.csdn.net/wisgood/article/details/19852553

  1. Hive分区字段的使用

Hive的分区字段是用来划分文件目录的,本身不需要在数据文件中存在

 

假设stocks表 的分区字段为symbol 执行如下查询

Select count(distinct symbol) from stocks 会返回结果 0 这个是hive存在的bug

 

  1. 浮点数比较问题

假设 有张employees 表的taxes 字段是float 类型的,标识有两条数据的taxes 的值为0.2

此时使用查询

Select * from employees where taxes > 0.2;

 

你会惊奇的发现 这两条数据在列!!

 

为了避免这种情况发生应该使用下列语句

 

Select * from employees where taxes > cast(0.2 as float);