什么是hive
Hive是基于Hadoop的一个数据仓库工具(E抽取T转换L加载),可以将结构化的数据文件映射为一张表,并提供类SQL查询功能
hive的处理流程
(1)将HQL语句转化为一组操作符
(2)每一个操作符对应一个HDFS操作Mapreduce操作
(3)运行MapReduce操作 , 返回结果
Hive简单操作
启动Hive hive
显示数据库 show databases;
使用default数据库 use default;
显示default数据库中的表 show tables;
创建student表 create table student(id int, name string) ROW FORMAT DELIMITED FIELDS TERMINATEDBY ' ';
加载文件到student数据库表 load data local inpath '/student.txt' into table student;
Hive查询结果 select * from student;
Hive安装以及Hive语句
Hive数据倾斜
(1)合理设置Map数:每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的
(2)小文件进行合并:在map执行前合并小文件,减少map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。HiveInputFormat没有对小文件合并功能
(3)复杂文件增加Map数:当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率 方法:增加切片大小
根本原因:
(1)key分布不均匀
(2)业务数据本身的特性
(3)SQL语句造成数据倾斜
解决方法
1 . hive设置hive.map.aggr=true和hive.groupby.skewindata=true
2 . 大小表join
3.还有其他解决方案
Hive内部表和外部表的区别
Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。
在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。
hive的元数据和存储引擎
hive的元数据存储着通过hive所建的库和表的结构信息, 以及所对应的hdfs上的文件夹
hive可以使用mysql作为存储引擎,也可以使用其他数据库
Hive的特点以及和关系型数据库的区别
hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,
可以将sql语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,
不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
hive导入数据的几种方式
从本地导入: load data local inpath ‘/home/1.txt’ (overwrite)into table student;
从Hdfs导入: load data inpath ‘/user/hive/warehouse/1.txt’ (overwrite)into table student;
查询导入: create table student1 as select * from student;(也可以具体查询某项数据)
查询结果导入:insert (overwrite)into table staff select * from track_log;
hive导出数据的几种方式
用insert overwrite导出方式
导出到本地:
insert overwrite local directory ‘/home/robot/1/2’ rom format delimited fields terminated by ‘ ’ select * from staff;(递归创建目录)
导出到HDFS
insert overwrite directory ‘/user/hive/1/2’ rom format delimited fields terminated by ‘ ’ select * from staff;
Bash shell覆盖追加导出
例如:$ bin/hive -e “select * from staff;” > /home/z/backup.log
Sqoop把hive数据导出到外部
分区
庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。
数据会依照单个或多个列进行分区,通常按照时间、地域或者是商业维度进行分区。为了达到性能表现的一致性,对不同列的划分应该让数据尽可能均匀分布。最好的情况下,分区的划分条件总是能够对应where语句的部分查询条件。
Hive的分区使用HDFS的子目录功能实现。每一个子目录包含了分区对应的列名和每一列的值。但是由于HDFS并不支持大量的子目录,这也给分区的使用带来了限制。我们有必要对表中的分区数量进行预估,从而避免因为分区数量过大带来一系列问题。
Hive查询通常使用分区的列作为查询条件。这样的做法可以指定MapReduce任务在HDFS中指定的子目录下完成扫描的工作。HDFS的文件目录结构可以像索引一样高效利用。
//创建表时加入分区
create table if not exists sopdm.wyp2(id int,name string,tel string)
partitioned by(age int)
row format delimited
fields terminated by ','
stored as textfile;
//加载数据时指定分区 overwrite是覆盖,into是追加
insert into table sopdm.wyp2
partition(age='25')
select id,name,tel from sopdm.wyp;
分桶
桶是通过对指定列进行哈希计算来实现的,通过哈希值将一个列名下的数据切分为一组桶,并使每个桶对应于该列名下的一个存储文件。
分区中的数据可以被进一步拆分成桶,不同于分区对列直接进行拆分,桶往往使用列的哈希值对数据打散,并分发到各个不同的桶中从而完成数据的分桶过程
hive使用对分桶所用的值进行hash,并用hash结果除以桶的个数做取余运算的方式来分桶,保证了每个桶中都有数据,但每个桶中的数据条数不一定相等
桶操作也可以用来实现高效的Map端连接操作。在数据量足够大的情况下,分桶比分区,更高的查询效率。 例如进行两个桶字段join时 , 相同的字段只会在相同的桶里面 , 大大减少索引量
//创建分桶
CREATE TABLE bucketed_user (id INT) name STRING)
CLUSTERED BY (id) INTO 4 BUCKETS;
hive优化
(1)Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算,在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。
(2)本地模式
set hive.exec.mode.local.auto=true; //开启本地mr
//设置local mr的最大输入数据量,当输入数据量小于这个值时采用local mr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
//设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max=10;
(3)表优化
1.避免笛卡尔积
2.行列过滤
(4)避免数据倾斜
(5)设置严格模式 使用了order by语句的查询,要求必须使用limit语句 ,,限制笛卡尔积的查询 JOIN查询的时候不使用ON语句而是使用where语句
Hive中的排序关键字有哪些
sort by ,order by ,cluster by ,distribute by
sort by :不是全局排序,其在数据进入reducer前完成排序
order by :会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序).只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
cluster by : 当distribute by 和sort by的字段相同时,等同于cluster by.可以看做特殊的distribute + sort
distribute by :按照指定的字段对数据进行划分输出到不同的reduce中