hive使用与优化

目录

hive的使用

A、内部表,外部表

B、hive 读检查

C. 静态分区

1.创建分区表

2.上传数据

3. 查询数据

4.删除分区

5.添加分区

D.  通过查询插入数据

E. 正则匹配,加载数据

F. beeline 客户端

G. UDF 函数

H. like 方式创建表结构

i. 设置hive 属性

1. 命令行的方式设置,

2. 使用 .hiverc 配置文件

J. 动态分区

K.分桶

L. 视图

M.索引

N. hive的运行方式

1.hive 会话执行linux命令

2.bash会话执行 hive 命令

3.在 hive 中调用 linux 文件执行 

O. hive 优化

a.严格模式:

b.排序

c.join

d.聚合

e. map、 reduce 数量

 f. jvm 重用

问题

问题1:NoViableAltException(308@[2389:1: columnNameTypeOrConstraint : ( ( tableConstraint ) | ( columnNameTypeConstraint ) );])

问题2:User: root is not allowed to impersonate abc (state=08S01,code=0) 

问题3:Required field 'serverProtocolVersion' is unset!

问题4:Error running 'HiveJdbcClient': Command line is too long. Shorten command line for HiveJdbcClient or also for Application default configuration.

问题5:Failure to find org.glassfish:javax.el:pom:3.0.1-b06-SNAPSHOT in

实践项目:

1. 统计掉话率

a.数据

b. 建表

c. 加载数据

d. 进行sql 语句的计算

e. 结果

2. 统计单词

a.数据

b. 建表

c. 加载数据

d. sql 计算

e. 查询结果


hive的使用

浏览器访问namenode 主节点的, 9870 端口

A、内部表,外部表

1.外部表、外部表,在创建表的时候都可以指定目录,如果指定目录表的元文件会上传到指定目录否则使用 hive-sit.xml 文件中设置的文件目录+表名 作为元文件的目录

2. 删除时内部表会将表结构和元数据全部删除,外部表只删除表结构,不删除元数据

内部表:

CREATE TABLE psn(
id int,
name string,
likes array<string>,
address map<string,string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

查看表的详细信息

desc formatted psn; 

 

外部表:

CREATE EXTERNAL TABLE psnexternal(
id int,
name string,
likes array<string>,
address map<string,string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n'
LOCATION '/user/hive/externalTable';

B、hive 读检查

读检查的体现:

1. 将符合 表结构解析规范的数据,上传到表对应的 hdfs 文件夹,在使用 select 查询的时候,可以查到上传的文件夹的数据

2. 将不符合表结构解析规范的数据,则没有成功解析的字段信息会显示为 null

 

1,小明1,lol-book-movie,beijing:chaoyang-shanghai:pudong
2,小明2,lol-book,beijing:chaoyang-shanghai:pudong
3,小明3,lol-movie,beijing:chaoyang
4,小明4,lol,beijing:chaoyang-shanghai:pudong
5,小明5,book-movie,beijing:chaoyang-shanghai:pudong
6,小明6,lol-book-movie,beijing:chaoyang-shanghai:pudong
7,小明7,movie,beijing:chaoyang-shanghai:pudong
8,小明8,lol-book-movie,shanghai:pudong
9,小明9,lol-book-movie,beijing:chaoyang-shanghai:pudong


-- 不符合psn 表的数据1
10,小明10,lol-book-movie,beijing:chaoyang-shanghai:pudong
11,小明11,
12,小明12,
13,小明13,
14,小明14,
15,小明15,
16,小明16,
17,小明17,
18,小明18,
19,小明19,

查询数据

select * from psn; 

 

C. 静态分区

1.创建分区表

CREATE TABLE psnpartition(
id int,
name string,
likes array<string>,
address map<string,string>
)
PARTITIONED BY (age int, sex string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

2.上传数据

load data

local  -- 表示数据来自于linux服务器

inpath '/hiveData/myData/psn.txt'  -- 需要加压的linux服务器上的数据路径

into table psnpartition  -- 将数据加载到哪个表中

partition (age=18, sex='boy');  -- 手动设置导入的数据中 partition 所属的 age,sex 值

load data local inpath '/hiveData/myData/psn.txt' into table psnpartition partition (age=18, sex='boy');

加载第二部分,分区的数据

 该分区的age=25, sex='boy'

load data local inpath '/hiveData/myData/psnpartition.txt' into table psnpartition partition (age=25, sex='boy');

-- 第一部分的数据
1,小明1,lol-book-movie,beijing:chaoyang-shanghai:pudong
2,小明2,lol-book,beijing:chaoyang-shanghai:pudong
3,小明3,lol-movie,beijing:chaoyang
4,小明4,lol,beijing:chaoyang-shanghai:pudong
5,小明5,book-movie,beijing:chaoyang-shanghai:pudong
6,小明6,lol-book-movie,beijing:chaoyang-shanghai:pudong
7,小明7,movie,beijing:chaoyang-shanghai:pudong
8,小明8,lol-book-movie,shanghai:pudong
9,小明9,lol-book-movie,beijing:chaoyang-shanghai:pudong

-- 第二部分的数据
10,小红100,lol,beijing:chaoyang
11,小红111,lol,henan:chaoyang
12,小红122,lol,beijing:chaoyang
13,小红133,lol,henan:chaoyang
14,小红144,lol,beijing:chaoyang
15,小红155,lol,henan:chaoyang
16,小红166,lol,beijing:chaoyang
17,小红177,lol,henan:chaoyang
18,小红188,lol,beijing:chaoyang
19,小红199,lol,beijing:chaoyang

3. 查询数据

和正常的查询操作没有任何区别,将分区的属性看成正常的字段进行查询操作。

SELECT * FROM psnpartition WHERE age > 18;

 

4.删除分区

alter table psnpartition drop partition (sex='boy');

如果有多个相同的分区,在删除的时候没有指定具体删除的是那一个,则会将所有等于该属性的分区删除。

5.添加分区

alter table psnpartition add partition(age=10, sex='man');

通过这种方式添加的分区,里面是不存在数据的,所添加的分区属性必须是,在创建表的时候定义过的分区字段。 

 

D.  通过查询插入数据

通过这种方式进行数据的插入,需要跑 MapReduce 任务。

创建出需要导入数据的表,创建出源数据表并添加数据 

 可以一次性的对多张表插入数据

在进行数据插入的时候,从 psn 中只查询出几个字段,psn1 表的字段必须有几个字段

-- 表
CREATE TABLE psn(
id int,
name string,
likes array<string>,
address map<string,string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

-- 表1
CREATE TABLE psn1(
id int,
name string,
likes array<string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
LINES TERMINATED BY '\n';

-- 表2
CREATE TABLE psn2(
id int,
name string,
address map<string,string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

-- 插入数据
FROM psn
INSERT OVERWRITE TABLE psn1 SELECT id,name,likes
INSERT OVERWRITE TABLE psn2 SELECT id,name,address;

跑 MapReduce 任务 

 

E. 正则匹配,加载数据

SERDEPROPERTIES   序列化,反序列化

CREATE TABLE logtable(
    host string,
    identity string,
    t_user string,
    time string,
    request 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]*)
192.168.57.4 -        -          [29/Feb/2016:18:14:35 +0800] "GET /bg-upper.png HTTP/1.1" 304            -

数据 

192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.css HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.css HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.css HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-upper.png HTTP/1.1" 304 -

加载数据

load data local inpath '/hiveData/myData/lodatable.txt' into table lodatable;

查询验证

 

F. beeline 客户端

使用 hiveserver2 的方式启动服务端的服务

ss -nal  查看服务端口是否开启 

如果在启动客户端的时候出现这种报错,请看  问题2 

 处理完之后正常的连接

注意添加hive-jdbc 的版本和 hive 的版本一致

<dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>3.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jetty.aggregate</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

使用 jdbc 进行连接查询操作

import java.sql.*;

/**
 * 服务端使用 hiveserver2 启动服务
 *
 * Create by yang_zzu on 2020/9/11 on 10:38
 */
public class HiveJdbcClient {
    private static String driverName = "org.apache.hive.jdbc.HiveDriver";

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Class.forName("org.apache.hive.jdbc.HiveDriver");
        Connection conn = DriverManager.getConnection("jdbc:hive2://192.168.232.100:10000/default", "root", "");
        Statement stmt = conn.createStatement();
        String sql = "select * from psn limit 5 ";

        try {
            ResultSet res = stmt.executeQuery(sql);
            while (res.next()) {
                System.out.println(res.getString(1) + "-" + res.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
        }
        if (stmt != null) {
            stmt.close();
        }
        if (conn != null) {
            conn.close();
        }

    }
}

 

G. UDF 函数

使用 metastore 开启hive 服务端

 hive --service metastore

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

/**
 * udf 函数
 * Create by yang_zzu on 2020/9/11 on 14:00
 */
public class FirstFunction extends UDF {

    public Text evaluate(final Text s) {
        if (s == null) {
            return null;
        }
        String string = s.toString().substring(0, 3) + "*********";

        return new Text(string);

    }

}

pom文件

<dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>3.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jetty.aggregate</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.el</artifactId>
            <version>3.0.1-b06</version>
        </dependency>
    </dependencies>

 将jar包添加到 hive仓库

add jar /hiveData/myData/hello.jar;

 创建函数 helloworld , 该函数是临时函数,退出该hive 会话,则 helloworld 函数失效

create temporary function helloworld as 'com.sys.hive.FirstFunction';

 

H. like 方式创建表结构

like 的方式创建表,只能创建表的结构,不能复制数据

create table psnlike like psn;

 

i. 设置hive 属性

1. 命令行的方式设置,

这种设置的生命周期为当前hive会话,退出则设置的内容消失

当命令行后面不带有参数的时候,是对属性配置内容的查看

-- 查看标题头的属性设置
set hive.cli.print.header;

当命令行后面带有参数的时候,是进行属性的设置

-- 设置hive显示标题头
set hive.cli.print.header=true;

退出hive 会话再次登录

2. 使用 .hiverc 配置文件

这种方式的配置,是在hive 客户端启动的时候自动加载进行配置

 vim .hiverc

关闭客户端再次启动,已经设置为true 

 

J. 动态分区

动态分区,起始和静态分区没有什么大的区别,动态分区的时候,需要开启一些配置,加载数据的不需要手动的进行分区的指定,会更具分区的属性信息自动的进行数据的分配

编辑 .hiverc 文件设置属性

set hive.cli.print.header=true;
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nostrict;
set hive.exec.max.dynamic.partitions.pernode=100;
set hive.exec.max.dynamic.partitions=1000;
set hive.exec.max.created.files=100000;

每个配置的解释信息 

-- 设置hive显示标题头
set hive.cli.print.header=true;
-- 开启动态分区
set hive.exec.dynamic.partition=true;
-- 至少有一个分区是静态分区
set hive.exec.dynamic.partition.mode=nostrict;
-- 每一个执行mr节点上,允许创建的动态分区的最大数量(默认值:100)
set hive.exec.max.dynamic.partitions.pernode=100;
-- 所有执行mr节点上,允许创建的所有动态分区的最大数量(默认值:1000)
set hive.exec.max.dynamic.partitions=1000;
-- 所有的mr job允许创建的文件的最大数量(默认值:100000)
set hive.exec.max.created.files=100000;

创建动态分区的表,和正常的分区表一样

CREATE TABLE psndynamic(
id int,
name string,
likes array<string>,
address map<string,string>
)
partitioned by(age int, sex string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

创建原始数据表

CREATE TABLE psndata(
id int,
name string,
age int,
sex string,
likes array<string>,
address map<string,string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

原始数据

1,小明1,18,man,lol-book-movie,beijing:chaoyang-shanghai:pudong
2,小明2,18,man,lol-book,beijing:chaoyang-shanghai:pudong
3,小明3,18,boy,lol-movie,beijing:chaoyang
4,小明4,18,man,lol,beijing:chaoyang-shanghai:pudong
5,小明5,18,boy,book-movie,beijing:chaoyang-shanghai:pudong
6,小明6,18,man,lol-book-movie,beijing:chaoyang-shanghai:pudong
7,小明7,18,boy,movie,beijing:chaoyang-shanghai:pudong
8,小明8,18,man,lol-book-movie,shanghai:pudong
9,小明9,18,man,lol-book-movie,beijing:chaoyang-shanghai:pudong
11,小明11,28,man,lol-book-movie,beijing:chaoyang-shanghai:pudong
12,小明12,28,man,lol-book,beijing:chaoyang-shanghai:pudong
13,小明13,28,boy,lol-movie,beijing:chaoyang
14,小明14,28,man,lol,beijing:chaoyang-shanghai:pudong
15,小明15,28,boy,book-movie,beijing:chaoyang-shanghai:pudong
16,小明16,28,man,lol-book-movie,beijing:chaoyang-shanghai:pudong
17,小明17,28,boy,movie,beijing:chaoyang-shanghai:pudong
18,小明18,28,man,lol-book-movie,shanghai:pudong
19,小明19,28,boy,lol-book-movie,beijing:chaoyang-shanghai:pudong

将原始数据加载到psndata 表

load data local inpath '/hiveData/myData/psndata.txt' into table psndata;

psndynamic 表加载数据

注意:

select 后面查询的字段顺序,要和插入的表的的字段结构保持一致,分区的字段要放在后面,且和建表时候指定的分区字段顺序保持一致

否则在进行数据插入的时候,会出现某些字段为null 的情况

因为hive 是读检查,所以在进行插入的时候,如果字段类型不匹配,也能够正常的写入到文件,但是在读取的时候不能正常的读取数据,所以显示 null  

可以看到,age 这个字段是存在的,但是查询的时候显示的为空 

1. 不指定分区,这个时候不会执行 reduce 操作

overwrite 表示的是覆盖数据

-- 覆盖添加数据,写法一,from 放在上面
from psndata
insert overwrite table psndynamic partition(age, sex)  
select id, name, likes, address, age, sex distribute by age, sex;

-- 直接插入数据,写法二,正常的查询操作
INSERT INTO TABLE psndynamic
PARTITION (sex, age)
select id, name, likes, address, age, sex FROM psndata where age<18;

2. 指定分区,这个时候会执行 reduce 的操作

overwrite 表示的是覆盖数据

-- 覆盖添加数据,写法一,from 放在上面
from psndata
insert overwrite table psnpartition partition(age, sex)  
select id, name, likes, address, age, sex distribute by age, sex;

-- 直接插入数据,写法二,正常的查询操作
INSERT INTO TABLE psnpartition
PARTITION (sex, age)
select id, name, likes, address, age, sex FROM psndata where age<18;

K.分桶

分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储。

对于hive中每一个表、分区都可以进一步进行分桶。

由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中。

分桶,只适用于: 数据抽样( sampling )、map-join

-- 开启分桶
set hive.enforce.bucketing = true;

我这是为了省劲,将属性配置放到 .hiverc 文件中, 在生产环境的时候,不建议这样进行配置,因为每一个项目所需要的环境和配置都不太一样 

set hive.cli.print.header=true;
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nostrict;
set hive.exec.max.dynamic.partitions.pernode=100;
set hive.exec.max.dynamic.partitions=1000;
set hive.exec.max.created.files=100000;
set hive.enforce.bucketing = true;

 创建数据表

CREATE TABLE bucketdata(
id int,
name string,
age int
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

创建分桶表,桶按照 age 进行划分,个数为4

CREATE TABLE psnbucket(
id int,
name string,
age int
)
CLUSTERED BY(age) INTO 4 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n';

数据

1,小红11,0
2,小红12,0
3,小红13,0
4,小红14,0
5,小红15,0
6,小红16,0
7,小红17,0
8,小红18,0
9,小红19,0
11,小红11,10
12,小红12,10
13,小红13,10
14,小红14,10
15,小红15,10
16,小红16,10
17,小红17,10
18,小红18,10
19,小红19,10
21,小红21,18
22,小红22,18
23,小红23,18
24,小红24,18
25,小红25,18
26,小红26,18
27,小红27,18
28,小红28,18
29,小红29,18
31,小红31,24
32,小红32,24
33,小红33,24
34,小红34,24
35,小红35,24
36,小红36,24
37,小红37,24
38,小红38,24
39,小红39,24
41,小红41,28
42,小红42,28
43,小红43,28
44,小红44,28
45,小红45,28
46,小红46,28
47,小红47,28
48,小红48,28
49,小红49,28

数据表中加载数据

load data local inpath '/hiveData/myData/bucketdata.txt' into table bucketdata;

向分桶表中插入数据

INSERT into TABLE psnbucket
SELECT id, name, age from bucketdata WHERE name like '小红%';

执行完后,看到有两个桶里面是没有分到数据

进行数据抽样

select id,name,age from psnbucket tablesample(bucket 2 out of 4 on age);

bucket 2 out of 4 on age
表示的是 从 2 号桶开始抽样,抽样的桶的个数为 桶的总数/4  (可见简单的理解为这样)如果想要了解更具体的,可以查看 tablesample 的抽样方法

 

L. 视图

视图,可以简单的看成一个表,删除、查看,都和表一样

查询操作,没有创建视图的时候,sql语句

select
count(distinct(myCol1)), count(distinct(myCol2)) from psn
LATERAL VIEW explode(likes) myTable1 AS myCol1
LATERAL VIEW explode(address) myTable2 AS myCol2, myCol3;

因为 address 是 map 键值对,所以需要两个变量 myCol2, myCol3 一个代表 key 一个代表 value 

创建视图

CREATE VIEW v_psn
comment '查询psn表的id,name'
as select id,name from psn;

查看视图信息

desc formatted v_psn;

查询,使用视图进行查询操作

select * from v_psn;

删除视图

DROP VIEW v_psn;

查看所有视图和表

show tables;

 

M.索引

创建索引

CREATE INDEX psn_name on table psn (name)
AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
in table t1_index_table;

as:指定索引器;
in table:指定索引表,若不指定默认生成在default__psn_t1_index__表中 

在进行索引创建的时候出现了不识别 create index 不知道是我安装的问题还是其他原因造成的,没有解决

对表重建索引

ALTER INDEX psn_name ON psn REBUILD;

查看索引信息

select * from psn_name;

查看表,存在的索引

show idnex on psn;

删除索引

DROP INDEX IF EXISTS psn_name ON psn;

 

N. hive的运行方式

1.hive 会话执行linux命令

在 hive 环境中执行 hdfs 语句

dfs -cat /user/hive/warehouse/psnbucket/000002_0;

强行与 linux 进行交互

! cat /hiveData/myData/word.txt;

2.bash会话执行 hive 命令

hive -e 'select * from psn'

 

hive -S -e 'select * from psn'

使用 -S 不显示下面这两处,没什么作用

将查询结果输出到文件中

hive -e 'select * from psn' >> bbb.txt  

cat bbb.txt 

创建文件

执行文件中的sql语句

hive -f hive.txt 

hive -i hive.txt

表示的是在执行完sql 之后会进入到 hive 会话。 

3.在 hive 中调用 linux 文件执行 

 在使用 source hive.txt;

的时候,启动 hive会话 的时候必须在 文件的路径下,否则无法执行,文件中的sql 语句

 

O. hive 优化

把Hive SQL 当做Mapreduce程序去优化

显示 SQL 的执行计划

explain extended select count(id) from psn;

 加载文件的最大值

set hive.exec.mode.local.auto.inputbytes.max;

a.严格模式:

1、对于分区表,必须添加where对于分区字段的条件过滤;

2、order by语句必须包含limit输出限制;

3、限制执行笛卡尔积的查询。

 set hive.mapred.mode;

设置为严格模式后,

对存在分区的表进行排序的时候 where 后面必须要有 分区的字段条件, 且要有 limit

select * from psnpartition where age>10 order by age limit 10;

对不存分区的表进行排序的时候,where 后面必须有添加, 且要有 limit

select * from psnpartition where name like '小%' order by age limit 30;

我这里又和别人的不一样的,我这里显示的是未定义,其他人的显示的是 默认为:nonstrict非严格模式

-- 开启本地模式
set hive.exec.mode.local.auto=true;
-- 加载文件的最大值,大于该值,则以集群的方式运行(默认128M)
set hive.exec.mode.local.auto.inputbytes.max=134217728;
-- 开启并行模式,如果系统资源不足的情况下,不建议开启并行模式
-- 如果资源足够的情况下,在执行SQL的时候,可能有多个子查询一起查询(默认值false)
set hive.exec.parallel=true;
-- 一次SQL计算中允许并行执行的job个数的最大值(默认值8)
set hive.exec.parallel.thread.number=8;
-- 开启严格模式(默认为:nonstrict非严格模式)
set hive.mapred.mode=strict;

编辑 .hiverc

set hive.exec.mode.local.auto=true;
set hive.exec.mode.local.auto.inputbytes.max=134217728;
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=8;
set hive.mapred.mode=strict;

b.排序

Cluster By不能通过asc、desc的方式指定排序规则

Cluster By - 相当于 Sort By + Distribute By

select * from psnpartition where age>-1 distribute by age sort by age desc;

c.join

Join计算时,将小表(驱动表)放在join的左边

可以开启自动的mapjoin

-- 开启自动mapjoin(默认为true)
set hive.auto.convert.join=true;
-- 大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行(默认25000000)
set hive.mapjoin.smalltable.filesize=25000000;
-- 是否忽略mapjoin hint 即mapjoin标记(默认为true)
set hive.ignore.mapjoin.hint=true;
-- 将普通的join转化为普通的mapjoin时,是否将多个mapjoin转化为一个mapjoin(默认为true)
set hive.auto.convert.join.noconditionaltask=true;
-- 将多个mapjoin转化为一个mapjoin时,其表的最大值(默认10000000)
set hive.auto.convert.join.noconditionaltask.size=10000000;

编辑 .hiverc

设置的时候,一般只设置前面三个参数,后面两个保持默认

set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize=25000000;
set hive.ignore.mapjoin.hint=true;
set hive.auto.convert.join.noconditionaltask=true;
set hive.auto.convert.join.noconditionaltask.size=10000000;

 手动进行mapjoin 这个时候如果有分区表,因为开启了严格模式,所以这里必须要有 分区条件

SELECT  /*+ MAPJOIN(psn) */ psn.id, psn.name,  psnpartition.name, psnpartition.age, psnpartition.id, psnpartition.address
FROM  psn  JOIN  psnpartition ON  psn.name = psnpartition.name where psnpartition.age>10;

没有分区表,则正常的进行 join on 就行了

SELECT  /*+ MAPJOIN(psn) */ psn.id, psn.name,  psndata.name, psndata.age, psndata.id 
FROM  psn  JOIN  psndata ON  psn.name  =  psndata.name;

sql语句中   /*+ MAPJOIN(psn) */ 这种是固定的写法不能删除

在开启自动mapjoin 后,不需要指定那个是小表,Hive自动对左边的表统计量,如果是小表就加入内存,即对小表使用Map join

SELECT psn.id, psn.name, psndata.name, psndata.age, psndata.id 
FROM psn JOIN psndata ON psn.name = psndata.name;

d.聚合

-- 开启在Map端的聚合(默认为true)
set hive.map.aggr=true;
-- map端group by执行聚合时处理的多少行数据(默认100000)
set hive.groupby.mapaggr.checkinterval=100000;
-- 进行聚合的最小比例(默认0.5)(预先对100000条数据做聚合,若聚合之后的数据量/100000的值大于该配置0.5,则不会聚合)
set hive.map.aggr.hash.min.reduction=0.5;
-- map端聚合使用的内存的最大值(默认0.5)
set hive.map.aggr.hash.percentmemory=0.5;
-- map端做聚合操作是hash表的最大可用内容,大于该值则会触发flush(默认0.9)
set hive.map.aggr.hash.force.flush.memory.threshold=0.9;
-- 是否对GroupBy产生的数据倾斜做优化,默认为false
set hive.groupby.skewindata=true;

编辑 .hiverc 文件 

set hive.map.aggr=true;
set hive.groupby.mapaggr.checkinterval=100000;
set hive.map.aggr.hash.min.reduction=0.5;
set hive.map.aggr.hash.percentmemory=0.5;
set hive.map.aggr.hash.force.flush.memory.threshold=0.9;
set hive.groupby.skewindata=true;

e. map、 reduce 数量

如果进行了分桶操作,则 reduce 的数量等于桶的数量

-- map 数量
-- 一个split的最大值,即每个map处理文件的最大值(默认256000000)
set mapred.max.split.size=256000000;
-- 一个节点上split的最小值(默认1)
set mapred.min.split.size.per.node=1;
-- 一个机架上split的最小值(默认1)
set mapred.min.split.size.per.rack=1;

-- reduce 数量
-- 强制指定reduce任务的数量(默认-1)
set mapred.reduce.tasks=-1;
-- 每个reduce任务处理的数据量(默认256000000)
set hive.exec.reducers.bytes.per.reducer=256000000;
-- 每个任务最大的reduce数(默认1009)
set hive.exec.reducers.max=1009;

修改 .hiverc 文件

set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=1;
set mapred.min.split.size.per.rack=1;
set mapred.reduce.tasks=-1;
set hive.exec.reducers.bytes.per.reducer=256000000;
set hive.exec.reducers.max=1009;

 f. jvm 重用

适用场景: 1、小文件个数过多 2、task个数过多

修改 .hiverc 文件

set mapred.job.reuse.jvm.num.tasks=n;

这个配置默认是没有定义的

 

设置开启之后,task插槽会一直占用资源,不论是否有task运行,直到所有的task即整个job全部执行完成时,才会释放所有的task插槽资源!

 

问题

问题1:NoViableAltException(308@[2389:1: columnNameTypeOrConstraint : ( ( tableConstraint ) | ( columnNameTypeConstraint ) );])

建表的时候, 这里虽然出现了 列名类型或约束 怎么样,但是在sql 语句中没有发现有什么异常的内容

看最后一句的失败原因是在第5行的第4列,找到这个地方,发现列名称写的是  time

time 可能和系统中的字段出现了重复,导致一直报错,将 time 修改为 t_time  正常的运行

CREATE TABLE logtable(
    host string,
    identity string,
    t_user string,
    time string,
    request 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;

NoViableAltException(308@[2389:1: columnNameTypeOrConstraint : ( ( tableConstraint ) | ( columnNameTypeConstraint ) );])
        at org.antlr.runtime.DFA.noViableAlt(DFA.java:158)
        at org.antlr.runtime.DFA.predict(DFA.java:116)
        at org.apache.hadoop.hive.ql.parse.HiveParser.columnNameTypeOrConstraint(HiveParser.java:34044)
        at org.apache.hadoop.hive.ql.parse.HiveParser.columnNameTypeOrConstraintList(HiveParser.java:29840)
        at org.apache.hadoop.hive.ql.parse.HiveParser.createTableStatement(HiveParser.java:6662)
        at org.apache.hadoop.hive.ql.parse.HiveParser.ddlStatement(HiveParser.java:4295)
        at org.apache.hadoop.hive.ql.parse.HiveParser.execStatement(HiveParser.java:2494)
        at org.apache.hadoop.hive.ql.parse.HiveParser.statement(HiveParser.java:1420)
        at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:220)
        at org.apache.hadoop.hive.ql.parse.ParseUtils.parse(ParseUtils.java:74)
        at org.apache.hadoop.hive.ql.parse.ParseUtils.parse(ParseUtils.java:67)
        at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:616)
        at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1826)
        at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1773)
        at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1768)
        at org.apache.hadoop.hive.ql.reexec.ReExecDriver.compileAndRespond(ReExecDriver.java:126)
        at org.apache.hadoop.hive.ql.reexec.ReExecDriver.run(ReExecDriver.java:214)
        at org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:239)
        at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:188)
        at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:402)
        at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:821)
        at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:759)
        at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:683)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.util.RunJar.run(RunJar.java:323)
        at org.apache.hadoop.util.RunJar.main(RunJar.java:236)
FAILED: ParseException line 5:4 cannot recognize input near 'time' 'string' ',' in column name or constraint

 

问题2:User: root is not allowed to impersonate abc (state=08S01,code=0) 

使用 beeline 连接的时候,出现

java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: root is not allowed to impersonate abc (state=08S01,code=0) 

修改 hadoop 的core-site.xml 文件

<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://mycluster</value>
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/var/yang/hadoop/ha</value>
  </property>
  <property>
    <name>hadoop.http.staticuser.user</name>
    <value>root</value>
  </property>
  <property>
   <name>ha.zookeeper.quorum</name>
   <value>yang101:2181,yang102:2181,yang103:2181</value>
  </property>
  <property>
    <name>hadoop.proxyuser.root.hosts</name>
    <value>*</value>
  </property>
  <property>
    <name>hadoop.proxyuser.root.groups</name>
    <value>*</value>
  </property>
</configuration>

将 core-site.xml 分发到其他的节点

关闭hadoop 服务

 stop-dfs.sh 

开启hadoop

start-dfs.hs

开启yarn

start-yarn.sh

问题3:Required field 'serverProtocolVersion' is unset!

Required field 'serverProtocolVersion' is unset!

hive 的版本要和 hive-jdbc 的版本保持一致

<dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>3.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jetty.aggregate</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

 

问题4:Error running 'HiveJdbcClient': Command line is too long. Shorten command line for HiveJdbcClient or also for Application default configuration.

在将 hive-jdbc 的版本修改后,出现下面的问题

Error running 'HiveJdbcClient': Command line is too long. Shorten command line for HiveJdbcClient or also for Application default configuration.

修改 run configuration 的配置信息 

正常执行 

 

问题5:Failure to find org.glassfish:javax.el:pom:3.0.1-b06-SNAPSHOT in

Failure to find org.glassfish:javax.el:pom:3.0.1-b06-SNAPSHOT in

进到本地存储maven 仓库,将这几个的pom 文件的名称,进行修改

 

实践项目:

1. 统计掉话率

a.数据

粘贴部分数据,可以自己伪造更多的数据

record_time:通话时间

imei:基站编号

cell:手机编号

drop_num:掉话的秒数

duration:通话持续总秒数

record_timeimeicellph_numcall_numdrop_numdurationdrop_ratenet_typeerl
2011-07-13 00:00:00+0835696629448-3706200000G0
2011-07-13 00:00:00+0835202429448-5133100000G0
2011-07-13 00:00:00+0835373629448-5133100000G0
2011-07-13 00:00:00+0835373629448-5133300000G0
2011-07-13 00:00:00+0835154529448-5133300000G0
2011-07-13 00:00:00+0835373629448-5134310080G0
2011-07-13 00:00:00+0835968129448-5146200000G0
2011-07-13 00:00:00+0835470729448-5146200000G0
2011-07-13 00:00:00+0835613729448-5147000000G0
2011-07-13 00:00:00+0835273929448-5197100000G0
2011-07-13 00:00:00+0835415429448-5197100000G0
2011-07-13 00:00:00+0812758029448-5197100000G0
2011-07-13 00:00:00+0835426429448-5197300000G0
2011-07-13 00:00:00+0835473329448-51973100360G0
2011-07-13 00:00:00+0835680729448-5197300000G0
2011-07-13 00:00:00+0812547029448-51973100130G0
2011-07-13 00:00:00+0835353029448-52061100460G0
2011-07-13 00:00:00+0835241729448-523110020G0
2011-07-13 00:00:00+0835341929448-523100000G0
2011-07-13 00:00:00+0830641629448-523100000G0
2011-07-13 00:00:00+0835620829448-523300000G0
2011-07-13 00:00:00+0835723829448-5233100210G0
2011-07-13 00:00:00+0835415429448-5254100000G0
2011-07-13 00:00:00+0835866229448-5305000000G0
2011-07-13 00:00:00+0835747029448-5352300000G0
2011-07-13 00:00:00+0835455529448-5352300000G0
2011-07-13 00:00:00+0886430129448-5387100000G0
2011-07-13 00:00:00+0835772729448-5387100000G0
2011-07-13 00:00:00+0835604929448-5387100000G0
2011-07-13 00:00:00+0835656929448-5485300000G0
2011-07-13 00:00:00+0835325729448-5487400000G0
2011-07-13 00:00:00+0835528729448-5567100000G0
2011-07-13 00:00:00+0835867529448-5567200000G0
2011-07-13 00:00:00+0835821229448-5567200000G0
2011-07-13 00:00:00+0835808629448-5567200000G0
2011-07-13 00:00:00+0812547029448-55672100270G0
2011-07-13 00:00:00+0886552429448-5581300000G0
2011-07-13 00:00:00+0886314929448-5582300000G0
2011-07-13 00:00:00+0886013929448-5582300000G0
2011-07-13 00:00:00+0835298329448-5582300000G0

b. 建表

-- 数据表
create table cell_monitor(
record_time string,
imei string,
cell string,
ph_num int,
call_num int,
drop_num int,
duration int,
drop_rate DOUBLE,
net_type string,
erl string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;

-- 结果表
create table cell_drop_monitor(
imei string,
total_call_num int,
total_drop_num int,
d_rate DOUBLE
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;

c. 加载数据

load data local inpath '/hiveData/myData/cell.csv' into table cell_monitor;

d. 进行sql 语句的计算

from cell_monitor cm
insert overwrite table cell_drop_monitor
select cm.imei ,sum(cm.drop_num),sum(cm.duration),sum(cm.drop_num)/sum(cm.duration) d_rate
group by cm.imei
sort by d_rate desc;

e. 结果

select * from cell_drop_monitor limit 10;

 

2. 统计单词

a.数据

hello world hadoop
hadoop hive bash
hive hello nginx
hbash hive hdfs

b. 建表

-- 数据存储
create table docs(line string);

-- 结果表
create table wc(word string, totalword int);

c. 加载数据

load data local inpath '/hiveData/myData/word.txt' into table docs;

d. sql 计算

from (select explode(split(line, ' ')) as word from docs) w
insert into table wc
select word, count(1) as totalword
group by word
order by totalword desc;

e. 查询结果

select * from wc;

 

 

虚引用用来做零拷贝?
弱引用可以用来防止内存泄露
软引用做缓存好像是挺合适的,我去看看
软引用可以用来做本地缓存,弱引用没怎么用过,不过ThreadLocal中有用到,你可以看下,幽灵引用也没用过,好像可以用来观察垃圾回收情况
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值