大数据面试之Hive

5 篇文章 0 订阅


说明,感谢亮哥长期对我的帮助,此处多篇文章均为亮哥带我整理。以及参考诸多博主的文章。如果侵权,请及时指出,我会立马停止该行为;如有不足之处,还请大佬不吝指教,以期共同进步。

1.Hive

1.1 Hive的架构模型?

用户操作Hive的接口主要有三个:CLI,Client 和 WUI。
其中最常用的是CLI,Cli启动的时候,会同时启动一个Hive副本。

Client是Hive的客户端,用户连接至Hive Server。在启动 Client模式的时候,需要指出Hive Server所在节点,
并且在该节点启动Hive Server。而客户端则又可以分为三种Thrift Client,JDBC Client,ODBC Client。

Web Interface是通过浏览器访问Hive。
Hive将元数据存储在数据库中,如mysql、derby。Hive中的元数据包括表的名字,表的列和分区及其属性,
表的属性(是否为外部表等),表的数据所在目录等。
解释器、编译器、优化器完成HQL查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。
生成的查询计划存储在HDFS中,并在随后由MapReduce调用执行。
Hive的数据存储在HDFS中,大部分的查询、计算由MapReduce完成。

Hive组件

Driver
    实现了session handler,在JDBC/ODBC接口上实现了执行和获取信息的API。

Compiler
    该组件用于对不同的查询表达式做解析查询,语义分析,最终会根据从metastore中查询到的表和分区元数据生成一个execution plain。

Execution Egine
    该组件会执行由compiler创建的execution。其中plan从数据结构上来看,是一个DAG,
    该组件会管理plan的不同stage与组件中执行这些plan之间的依赖。

Metastore
    Hive的metastore组件是hive元数据集中存放地。该组件存储了包括变量表中列和列类型等结构化的信息以及数据仓库中的分区信息
    (包括列和列类型信息,读写数据时必要的序列化和反序列化信息,数据被存储在HDFS文件中的位置)。

    Metastore组件包括两个部分:metastore services和Meta storage database。
        Metastore database的介质就是关系数据库,例如hive默认的嵌入式磁盘数据库derby,还有mysql数据库。
        Metastore services是建立在后台数据存储介质(HDFS)之上,并且可以和hive services进行交互的服务组件。

参考

1.2 Hive配置、启动和访问?

1.安装启动mysql(存储元数据)、过程略
2.添加配置文件$HIVE_HOME/conf/hive-site.xml内容如下:
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
 
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
 
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property>
 
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
<description>password to use against metastore database</description>
</property>
</configuration>
3. 拷贝jdbc链接MySQL的jar到$HIVE_HOME/lib/
4. 启动hive服务
nohup hive --service metastore 1>/dev/null 2>&1 &
jdbc方式 hiveserver2 或者 nohup hiveserver2 1>/dev/null 2>&1 & 或者 hive --service hiveserver2
jdbc客户端连接 beeline -u jdbc:hive2://ip:10000 -n root
5. java通过jdbc连接hive
public static int hiveJDBC_RowCount(String sql,Map<Integer,String> params){
    try {
        ResourceBundle rb = ResourceBundle.getBundle("config");
        Class.forName(rb.getString("hivedriverClassName")).newInstance();
 
        Connection conn = DriverManager.getConnection(rb.getString("hiveurl"),rb.getString("hiveusername"),
        rb.getString("hivepassword"));
        java.sql.PreparedStatement pstsm = conn.prepareStatement(sql);
        for(Integer key : params.keySet()){
            pstsm.setString(key, params.get(key));
        }
        ResultSet resultSet = pstsm.executeQuery();
        int rowNum = 0;
        if(resultSet.next()){
            rowNum = resultSet.getInt(1);
        }
        return rowNum;
    } catch (Exception e) {
        System.out.println(e);
        return 0;
    }
}

config内容如下:
hivedriverClassName=org.apache.hive.jdbc.HiveDriver
hiveurl=jdbc:hive2://ip:10000/default
hiveusername=root
hivepassword=

1.3 hive中存放的是什么?

存的是和hdfs的映射关系,hive是逻辑上的数据仓库,实际操作的都是hdfs上的文件,HQL就是用SQL语法来写的MR程序。

1.5 Hive建表语句

直接建表法
查询建表法
like建表法

1.直接建表法
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name   
-- (Note: TEMPORARY available in Hive 0.14.0 and later)
  [(col_name data_type [COMMENT col_comment], ... [constraint_specification])]
  [COMMENT table_comment]
  [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
  [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
  [SKEWED BY (col_name, col_name, ...)                  -- (Note: Available in Hive 0.10.0 and later)]
     ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
     [STORED AS DIRECTORIES]
  [
   [ROW FORMAT row_format] 
   [STORED AS file_format]
     | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]  -- (Note: Available in Hive 0.6.0 and later)
  ]
  [LOCATION hdfs_path]
  [TBLPROPERTIES (property_name=property_value, ...)]   -- (Note: Available in Hive 0.6.0 and later)
  [AS select_statement];   -- (Note: Available in Hive 0.5.0 and later; not supported for external tables)
TEMPORARY:临时表
EXTERNAL:外部表,删除时,数据文件不会删除
PARTITIONED BY: 分区表
CLUSTERED BY:语句声明的字段中相同的内容会被分配到同一个reduce处理,并且为分桶提供依据
2. 查询建表法
通过AS 查询语句完成建表:将子查询的结果存在新表里,有数据 
CREATE TABLE new_key_value_store
   ROW FORMAT SERDE "org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe"
   STORED AS RCFile
   AS
SELECT (key % 1024) new_key, concat(key, value) key_value_pair
FROM key_value_store
SORT BY new_key, key_value_pair;
3. like建表法
会创建结构完全相同的表,但是没有数据。 
CREATE TABLE empty_key_value_store
LIKE key_value_store;

1.6 Hive内部表,外部表的区别

内部表:加载数据到hive所在的hdfs目录,删除时,元数据和数据文件都删除

外部表:不加载数据到hive所在的hdfs目录,删除时,只删除表结构。

1.7 Hive如何导入数据?

1,通过hadoop -put的方式
hadoop fs -put student.txt /user/hive/warehouse/hive.db/t_student/
2,在hive中通过 load data local inpath 从本地服务器导入
load data local inpath '/home/gugu/hive/student1.txt' into table t_student; 
3,在hive中通过 load data inpath 从hdfs导入
load data inpath '/test/tt/student1.txt' into table t_student; 

1.8 Hive如何导出数据?

1. 数据导出到本地
hive> insert overwrite local directory '/data/hive/hstudent1'
    > row format delimited fields terminated by '\t'
    > select * from t_student;
2.  Hadoop命令导出到本地
hive> dfs -get /user/hive/warehouse/student/month=201709/000000_0
/data/hive/hstudent1;

3. hive 命令导出
$ bin/hive -e 'select * from default.student;' >
 /data/hive/hstudent1/student4.txt;

4. export 导出
hive> export table student to '/hstudent2';
hive> import table student5 from  '/hstudent2';

5. 数据导出到hdfs(没有local)
hive> insert overwrite directory '/hstudent1'
    > row format delimited fields terminated by '\t'
    > select * from student;

1.9 Hive的数据倾斜

1. 什么是数据倾斜?
    由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点

2. 产生数据倾斜的原因
    A:key 分布不均匀
  B:业务数据本身的特性
  C:建表考虑不周全
  D:某些 HQL 语句本身就存在数据倾斜
  
3.数据倾斜处理
    (1) 空值产生的数据倾斜
        解决方案 1:user_id 为空的不参与关联
        解决方案 2:赋予空值新的 key 值
        
    (2) 不同数据类型关联产生数据倾斜
        解决方案: 把数字类型 id 转换成 string 类型的 id
        
    (3) 大小表关联查询产生数据倾斜 
        直接提供了能够在 HQL 语句指定该次查询使用 map join,map join 的用法是 在查询/子查询的SELECT关键字后面添加
        /*+ MAPJOIN(tablelist) */提示优化器转化为map join(早期的 Hive 版本的优化器是不能自动优化 map join 的)。
        其中 tablelist 可以是一个 表,或以逗号连接的表的列表。tablelist 中的表将会读入内存,
        通常应该是将小表写在 这里。
     
        MapJoin 具体用法:
        select /* +mapjoin(a) */ a.id aid, name, age from a join b on a.id = b.id;
        select /* +mapjoin(movies) */ a.title, b.rating from movies a join ratings b on a.movieid =
        b.movieid;
     

参考

1.10 Hive分区、分桶如何实现?优缺点

1,Hive分区。
是指按照数据表的某列或某些列分为多个区,每个区从形式上可以理解为文件夹。
第一,创建分区表并将本地文件中的数据加载到分区表中
create table t_test(user_id int)partitioned by(name string) row format delimited fields terminated by ",";
关键字 partitioned by (name  string)声明该表是分区表,向分区表导入数据的时候,要通过关键字partition(name=“jack”)
显示声明数据要导入到表的哪个分区.
分区,这是将满足某些条件的记录打包,做个记号,在查询时提高效率,相当于按文件夹对文件进行分类,文件夹名可类比分区字段。
这个分区字段形式上存在于数据表中,在查询时会显示到客户端上,但并不真正在存储在数据表文件中,是所谓伪列。
查看分区信息
show partitions t_test;
查看分区数据
select * from t_test where name='aa';
向分区中插入数据
insert table t_test partition(name="aa") select id from user_info where name="aa";

2,分桶
分桶是相对分区进行更细粒度的划分。分桶将整个数据内容安装某列属性值得hash值进行区分,如要安装name属性分为3个桶,就是对name属性值的hash值对3取模,按照取模结果对数据分桶。
如何分桶:
hive > set hive.enforce.bucketiong=true;
hive > create table t_test(id int, name string) clustered by(id) into 3 buckets row format delimited fields termanited by ",";
第一,分桶之前要执行命令hive.enforce.bucketiong=true;
要使用关键字clustered by 指定分区依据的列名,还要指定分为多少桶,这里指定分为3桶
与分区不同的是,分区依据的不是真实数据表文件中的列,而是我们指定的伪列,但是分桶是依据数据表中真实的列而不是伪列。所以在指定分区依据的列的时候要指定列的类型,因为在数据表文件中不存在这个列,相当于新建一个列。而分桶依据的是表中已经存在的列,这个列的数据类型显然是已知的,所以不需要指定列的类型。
向桶中插入数据:
insert table t_test select * from user_info;
查看桶信息:
dfs -ls /usr/hive/warehouse/t_test/
查看分桶数据:
select * from t_test tablesample(bucket 1 out of 3 on id);
要指定关键字tablesample。
数据分桶的适用场景:
分区提供了一个隔离数据和优化查询的便利方式,不过并非所有的数据都可形成合理的分区,
尤其是需要确定合适大小的分区划分方式,(不合理的数据分区划分方式可能导致有的分区数据过多,而某些分区没有什么数据的尴尬情况)
分桶是将数据集分解为更容易管理的若干部分的另一种技术。
数据分桶的原理:
跟MR中的HashPartitioner的原理一模一样
MR中:按照key的hash值去模除以reductTask的个数
Hive中:按照分桶字段的hash值去模除以分桶的个数
Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。

好处:
1、方便抽样
2、提高join查询效率

参考
参考
参考

1.11 请说明hive中Sort By、Order By、Cluster By,Distribute By各代表什么意思

order by:会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)。
    只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。

sort by:不是全局排序,其在数据进入reducer前完成排序。

distribute by:按照指定的字段对数据进行划分输出到不同的reduce中。

cluster by:除了具有 distribute by 的功能外还兼具 sort by 的功能。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值