欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2020.9.28(Hive视图、索引、权限管理)

程序员文章站 2022-05-01 12:14:13
...

回顾:上节课讲了hive的参数设置,hive的运行方式,hive的动态分区,分桶,lateral view这五个知识点。遗留了两个问题:
1.看一下hive的源码,现在面试中,hive的源码还从来没有被问到过。在hive这个环节不会浪费太多时间,把源码讲清楚,没有必要。
但是虽然不讲源码的详细知识点,但是会告诉你,如果拿到一个陌生框架之后,应该怎么去找源码,或者怎么去看源码。有同学把源码下载回来了一脸懵逼,连入口都找不到。今天讲一下入口该怎么找:
大部分 不管是hadoop、hive、hbase、spark,大概都是这样一个寻找流程:
如果想看源码的话,给一个建议:在看源码过程中,千万不要每一个方法都点进去!源码是别人写的,写的层次可能非常非常深,如果一层一层往里面点的话,点到最后可能看明白了,回头一想,我刚刚是从哪个地方点进来的,一脸懵逼。如果那一行里面有注释、或者看到方法名称,一些类的名称能大概猜到它是什么意思,没必要往下看了,先遗留下来,之后有时间了可以再慢慢看。
2.在hive2.x的时候已经没有hwi这个web页面了。但在1.x的时候还是有的,现在看一下。

hive --service hwi

hwi就是webUI的接口,打开浏览器:node01:9999/hwi
2020.9.28(Hive视图、索引、权限管理)
change user info 改变用户信息,这里写用户和组,但在hive里面没有用户这个概念,所有随便写,写什么都行。点提交authorization is complete 认证授权已经完成。
怎么写sql语句和执行过程?
create session->随便取个名称,submit
2020.9.28(Hive视图、索引、权限管理)

任何结果都没有,必须要把start query选择成yes,这时候在result bucket里面可以看到对应的结果。
再回来,点击list session->点manager
这时候又回到这个页面了,重新再次提交SQL语句,这时候再去查看,会发现是两遍对应的结果?
为什么?
2020.9.28(Hive视图、索引、权限管理)

上面是第一次查询的结果,而下面是第二次查询的结果。每次查询的时候,并不会把上一次查询的结果消失掉。而是会保留每一次执行的过程。非常不好用。
稍微看一下就完事了,无论用什么版本,这个功能基本上都不会用的,这也是为什么2.x的时候hwi被淘汰掉的原因。

虽然被淘汰掉了,但他提供了一种平台化和可视化的思路。以后所做的项目都应该叫平台

如何查看hive源码?入口在什么地方?
每次在黑窗口里执行的都是hive的脚本,所以找入口,一定要从脚本里面进行查找。

cd /opt/bigdata/hive-2.3.4/bin
ls

beeline ext hive hive-config.sh hiveserver2 hplsql metatool schematool

vi hive

366行,大部分同学都没有耐心看下去,所有从里面开始找东西,找自己想要的,第一次输入hive的时候,相当于输入了hive --service cli默认运行的是命令行的命令,有一堆参数的判断 ,如果什么都不写会默认判断为cli
2020.9.28(Hive视图、索引、权限管理)
只要去对应的目录里面,找cli.sh文件

cat cli.sh

2020.9.28(Hive视图、索引、权限管理)

hive也是用Java写的,所有只要找主类就可以了,一个main函数程序入口
2020.9.28(Hive视图、索引、权限管理)2020.9.28(Hive视图、索引、权限管理)
执行这个run()方法,里面会有一些参数判断,告诉我应该怎么解析,哪些初始化操作,然后慢慢完成相应操作,这地方就是整个程序的入口操作,当把它启动好之后,意味着命令行已经准备好了。提交sql语句的时候,会有服务进行接收,接收完之后进行解析,转化,执行的过程。

hive视图

只要接触关系型数据库,一定会用对应视图的。用的非常非常多。
视图主要用在什么场合?有什么样的用途?在公司里怎么用的?
如果写的sql语句非常简单,只是几张表的关联,这个东西完全没必要,如果语句非常非常复杂,比如说要写一个好几十行的sql语句,这里面包含了N多个子查询,并且有很多子查询都是重复的sql语句,这时候,就必须把它定义成一个视图。这个时候直接写视图就可以了,可以减少整个sql语句的复杂度。
第二种情况,定义一个视图,把它定义成多张表join之后结果表。视图非常简单,就是一个sql语句,每次在使用视图的时候,都会把sql语句提前进行执行。把结果暂存成视图,比如有三张表,每张表里面取一个字段,把这三个字段当成一个视图,视图完成之后可以成一张中间表。用的时候直接拿视图进行运行就可以了。而不需要每次都进行一个join的代码编写。但执行的时候,一定会执行的。

hive里面也支持了对应的视图操作。
2020.9.28(Hive视图、索引、权限管理)
hive View视图
– 和关系型数据库中的普通视图一样,hive也支持视图
– 特点:
不支持物化视图:视图是虚拟表,虚拟表表示不是实实在在存在数据的表,物理表表示实实在在存在数据文件的,比如在数据库里看到的那些表都是物理表。视图每次在做的时候,都需要优先先执行sql语句,然后把结果当成虚拟视图。素有视图也可以被当成表。物化视图的概念:MySQL里面是不支持物化视图的,只有在Oracle里面是支持的,物化视图是什么意思?比如现在有个t1 t2 t3每次从里面取c1 c2 c3三个字段,这时候,这三个字段也要被当成一张物理表,进行一个实实在在的存储。这叫物化视图。如果把这三个表进行join操作,把这个结果也缓存了一下,这时候如果t1 t2 t3改变了,物化视图会刷新,这其实分了两种策略,一种叫uncommit,一种叫undemand,一种是只要t1 t2 t3发生改变,物化视图也跟着变,第二种是每次查询的时候才会把数据进行更新。不查询就不更新了。有这么两种方式,现在在公司企业里面,Oracle已经不像以前那么流行了。以前在阿里有一个去IOE的概念,o就表示Oracle
只能查询,不能做加载数据操作:MySQL里面定义的视图,可以往里面插入数据么?如果只是操作一张表是可以往视图里面更新数据的,但多表的时候是有问题的。但hive里面是都不可以的。
视图的创建,只是保存一份元数据,查询视图时才执行对应的子查询:视图就是一个sql语句,每次在执行的视图的时候,会优先把视图的sql语句先执行,再执行自己定义的SQL语句
view定义中若包含了ORDER BY/LIMIT语句,当查询视图时也进行ORDER BY/LIMIT语句操作,view当中定义的优先级更高:每次定义的时候,视图里面的东西会优先执行,视图执行完成之后,外面的才会执行
view支持迭代视图:视图里面可以嵌套视图

可以在MySQL里面查看

mysql -uroot -pok
mysql> use hive_remote
select * from TBLS;

里面的字段不是managered_table就是external_table。不是内部表就是外部表,没有视图概念,创建一个新的视图
Create/Drop/Alter View

CREATE VIEW [IF NOT EXISTS] [db_name.]view_name [(column_name [COMMENT column_comment], ...) ]
  [COMMENT view_comment]
  [TBLPROPERTIES (property_name = property_value, ...)]
  AS SELECT ...;
hive> create view v_psn as select * from psn where id > 5
show tables;
show views;  // 在2.x中是有这样的操作的,但是在1.x的时候没有,所有不要这样查

视图也是一张虚拟表,所有去MySQL里面进行查看

mysql> select * from TBLS;

可以看到最后一行多了一个VIRTUAL_VIEW

hive> select * from psn;

可以查询对应的视图,有对应的结果了。查询的是视图里的数据,而不是对应表里的数据。

注意:现在只有单表,所有看不出来有什么效果,如果有多表的话,可以把中间的结果进行缓存,这是视图最基本的应用。

hive的索引

2020.9.28(Hive视图、索引、权限管理)

经常会听到一级索引、二级索引。索引是做什么用的?
是为了帮助我们提高检索的效率用的
MySQL里面的索引是自动创建的么?
主键可以拆开了说,唯一且非空。建索引是唯一键,而不是对应的主键。
对应hive而言,和MySQL就不太一样了。它并不会自动帮助我们来创建索引。索引的目的,优化查询以及对应的检索性能。
创建索引的语句:
Create/Drop/Alter Index

CREATE INDEX index_name
  ON TABLE base_table_name (col_name, ...)
  AS index_type
  [WITH DEFERRED REBUILD]
  [IDXPROPERTIES (property_name=property_value, ...)]
  [IN TABLE index_table_name]
  [
     [ ROW FORMAT ...] STORED AS ...
     | STORED BY ...
  ]
  [LOCATION hdfs_path]
  [TBLPROPERTIES (...)]
  [COMMENT "index comment"];

选择哪张表base_table_name ,对表里的哪个列col_name 建立索引
[IN TABLE index_table_name]
如果是你来设计数据库的话,你觉得索引应该保存什么信息?
现在有一个非常大的文件,想从里面获取到单词该怎么获取?
有一个非常重要的点:偏移量
想建立索引,保存的是那个列对应的偏移量的信息。而对应到hdfs里面,也是某个文件的偏移量。同时,因为一张表可能对应的是多个文件,所以要保存文件所在的存储目录,以及对应的偏移量。
offset也好,文件也好,都是数据。意味着这个数据也要进行存储,要使用表来存,所以在建的时候,要保存索引信息到某一张固定的表里面,index_table_name是表的的名称,索引信息的这张表。而不是元数据表。

create index t1_index on table psn2(name)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild
in table t1_index_table;

一旦是单引号引起来的,一定是表示的我们jar包的对应的某一个类,也就是有对应的索引处理列,来帮助我们记录对应的offset信息,以及对应的数据文件的信息。由对应的类来完成对应的工作。
as:指定索引器,可以自己写jar包替换;
in table:指定索引表,若不指定默认生成在default__psn2_t1_index__表中

如果公司技术实力比较强,不可能直接免费用这些开源的东西,一定是在开源的基础之上做二次开发。如果需要做二次开发,一定要对源码足够了解,同时要知道什么时候能去修改。理论上什么都可以修改,实际一些核心的组件没必要修改。

create index t1_index on table psn2(name)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild;

这个语句和刚才的语句差不多,只不过少了in table 保存的是索引信息所存在的那张表,没写意味着有个默认表,会默认帮我们创建`default__psn2_t1_index__``

show tables;

2020.9.28(Hive视图、索引、权限管理)

这两张表都创建好了,这两张表里有没有数据?
没有。我现在就9行数据,如果想给他创建对应的索引,意味着必须要把整个文件先读进来,读进来之后找到对应的列,记录下那个列所在的值所在的偏移量,意味着必然对这个文件进行处理了,在文件处理的过程中,刚刚创建索引的时候用了1秒钟,这么短的时间内,有可能把所有的数据文件优先读进来么?连读取的时间都没有。

select * from t1_index_table;

会发现这里面没有任何一条记录。没有所有
hive里面有索引的知识点,但是hive并不会默认帮我们创建对应的索引。需要自己来完成。
自己需要手动来创建索引,需要MR来执行所有的构建过程

2020.9.28(Hive视图、索引、权限管理)

ALTER INDEX t1_index ON psn REBUILD;

2020.9.28(Hive视图、索引、权限管理)

应该申请对应的资源来进行执行,如果MapReduce没有开始执行,说明整个资源一定是有问题的,怎么判断?
打开对应的resourcemanager的webUI
node03:8088 刷新不出来说明没有启动,启动resourcemanager, 如果还没有资源,检查nodemanager有没有启动

yarn-deman.sh start resourcemanager
start-yarn.sh

现在有资源立马开始执行了。
2020.9.28(Hive视图、索引、权限管理)要把对应的数据结果放到t1_index_table这张表里。

select * from t1_index_table

现在有数据了,保存的是表的列名,来自哪个文件,偏移量,把数据对应成功了。
数据增加了,还需要重新构建索引,

load data local inpath '/root/data/data' into table psn;

意味着又要重新进行构建了,是非常麻烦的。所以在企业里面,索引这个点几乎不用,但是每次在进行查询的时候,hive是数据仓库,保存历史时刻的每一个状态,比如说今天的数据到凌晨12点的时候执行完了,当一天的数据都执行完了,我对这张表里所有的数据都来一次构建索引的过程。知乎再来的数据是另一天的数据,不属于当前数据了,这没问题了。分需求,有时候会用,有时候不会用,一般情况下比较少。

只存偏移量怎么让查询加快,查询条件不是要挨个进行过滤么?
在进行查询的时候也一样,既然设置索引了,一定当where条件里包含这个字段的时候才会加快。在遍历某一个文件里数据的时候,一定有一个类似于指针的东西,一般叫Cursor 翻译过来叫游标,游标有个seek方法,它可以直接挪动对应的位置。比如读10个字符,读完之后想跨10个再读,这时候可以移动seek指针,就是对应的偏移量的值,根据偏移量来定位读取,速度一定是快的。

在数据量比较小的时候会发现,建了索引了没有不建索引速度快。能解释为什么么?每次在进行查找的时候,如果数据量比较小的话,第一次要先遍历这张索引表的数据,第二次再找对应的数据表。这涉及到MySQL里面的东西了,MySQL里面有索引,为什么MySQL索引比较快,它是在内存里进行读取的,内存里结构叫B+树。B+树这个数据结构先不管,什么叫树,一个节点后面有N多个分支,假如我现在存的数据首字母是从a到z这样,在进行操作的时候可以挨个进行排列,当我在查找的时候,一定找的是内存。不是磁盘。而无论内存还是磁盘都有一个4k的空间,(在装固态的时候要求4k对齐,光盘有磁道,里面是一个个对应的小格子,每个小格子都是4k这样的大小,页大小,是最小的空间,每次最小要占4k的大小)内存里也一样的,每次只保存4k数据,加载一堆4k连续块,内存读取索引文件是非常快的,在MySQL里面整体索引是非常快的。

相关标签: 再遇见