五万字,Hive知识体系保姆级总结

移动UI设计

  因篇幅有限,获取本文完整的PDF文档(带目录),请私信我,发送:hive

  一. Hive概览

  1.1 hive的简介

  Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。

  其本质是将SQL转换为MapReduce/Spark的任务进行运算,底层由HDFS来提供数据的存储,说白了hive可以理解为一个将SQL转换为MapReduce/Spark的任务的工具,甚至更进一步可以说hive就是一个MapReduce/Spark Sql的客户端

  为什么要使用hive ?

  主要的原因有以下几点:

  学习MapReduce的成本比较高, 项目周期要求太短, MapReduce如果要实现复杂的查询逻辑开发的难度是比较大的。而如果使用hive, hive采用操作接口类似SQL语法, 提高快速开发的能力. 避免去书写MapReduce,减少学习成本, 而且提供了功能的扩展hive的特点:

  可扩展 : Hive可以自由的扩展集群的规模,一般情况下不需要重启服务。延展性 : Hive用户自定义函数,用户可以根据自己的需求来实现自己的函数。容错 : 良好的容错性,节点出现问题SQL仍可完成执行。1.2 hive的架构

  基本组成:

  用户接口:包括CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命令行;JDBC/ODBC是Hive的JAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访问Hive。

  元数据存储:通常是存储在关系数据库如mysql/derby中。Hive 将元数据存储在数据库中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。

  解释器、编译器、优化器、执行器:完成HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS 中,并在随后有MapReduce 调用执行。

  1.3 hive与hadoop的关系

   Hive利用HDFS存储数据,利用MapReduce查询分析数据

  1.4 hive与传统数据库对比

  ​ hive主要是用于海量数据的离线数据分析

  查询语言。由于 SQL 被广泛的应用在数据仓库中,因此,专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL。熟悉 SQL 开发的开发者可以很方便的使用 Hive 进行开发。数据存储位置。Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中的。而数据库则可以将数据保存在块设备或者本地文件系统中。数据格式。Hive 中没有定义专门的数据格式,数据格式可以由用户指定,用户定义数据格式需要指定三个属性:列分隔符(通常为空格、”\t”、”\x001″)、行分隔符(”\n”)以及读取文件数据的方法(Hive 中默认有三个文件格式 TextFile,SequenceFile 以及 RCFile)。由于在加载数据的过程中,不需要从用户数据格式到 Hive 定义的数据格式的转换,因此,Hive 在加载的过程中不会对数据本身进行任何修改,而只是将数据内容复制或者移动到相应的 HDFS 目录中。而在数据库中,不同的数据库有不同的存储引擎,定义了自己的数据格式。所有数据都会按照一定的组织存储,因此,数据库加载数据的过程会比较耗时。数据更新。由于 Hive 是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive 中不对数据的改写和添加,所有的数据都是在加载的时候中确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO ... VALUES 添加数据,使用 UPDATE ... SET 修改数据。索引。之前已经说过,Hive 在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些 Key 建立索引。Hive 要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势。数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特定条件的数据的访问,数据库可以有很高的效率,较低的延迟。由于数据的访问延迟较高,决定了 Hive 不适合在线数据查询。执行。Hive 中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的,而数据库通常有自己的执行引擎。执行延迟。之前提到,Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce 框架。由于 MapReduce 本身具有较高的延迟,因此在利用 MapReduce 执行 Hive 查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive 的并行计算显然能体现出优势。可扩展性。由于 Hive 是建立在 Hadoop 之上的,因此 Hive 的可扩展性是和 Hadoop 的可扩展性是一致的(世界上最大的 Hadoop 集群在 Yahoo!,2009年的规模在 4000 台节点左右)。而数据库由于 ACID 语义的严格限制,扩展行非常有限。目前最先进的并行数据库 Oracle 在理论上的扩展能力也只有 100 台左右。数据规模。由于 Hive 建立在集群上并可以利用 MapReduce 进行并行计算,因此可以很大规模的数据;对应的,数据库可以的数据规模较小。总结:hive具有sql数据库的外表,但应用场景完全不同,hive只适合用来做批量数据统计分析。

  1.5 hive的数据存储

  Hive中所有的数据都存储在 HDFS 中,没有专门的数据存储格式(可Text,SequenceFile,ParquetFile,ORC格式RCFILE等)SequenceFile是hadoop中的一种文件格式: 文件内容是以序列化的kv对象来组织的

  只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。Hive 中包含以下数据模型:DB、Table,External Table,Partition,Bucket。db:在hdfs中表现为hive.metastore.warehouse.dir目录下一个文件夹。table:在hdfs中表现所属db目录下一个文件夹。external table:与table类似,不过其数据存放位置可以在任意指定路径。partition:在hdfs中表现为table目录下的子目录。bucket:在hdfs中表现为同一个表目录下根据hash散列之后的多个文件。二、Hive表类型

  2.1 Hive 数据类型

  Hive的基本数据类型有:TINYINT,SAMLLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBLE,STRING,TIMESTAMP(V0.8.0+)和BINARY(V0.8.0+)。

  Hive的集合类型有:STRUCT,MAP和ARRAY。

  Hive主要有四种数据模型(即表):内部表、外部表、分区表和桶表。

  表的元数据保存传统的数据库的表中,当前hive只Derby和MySQL数据库。

  2.2 Hive 内部表

  Hive中的内部表和传统数据库中的表在概念上是类似的,Hive的每个表都有自己的存储目录,除了外部表外,所有的表数据都存放在配置在hive-site.xml文件的${hive.metastore.warehouse.dir}/table_name目录下。

  创建内部表:

  CREATE TABLE IF NOT EXISTS students(user_no INT,name STRING,sex STRING, grade STRING COMMOT '班级')COMMONT '学生表' ROW FORMAT DELIMITED FIELDS TERMINATED BY ','STORE AS TEXTFILE; 2.3 Hive 外部表

  被external修饰的为外部表(external table),外部表指向已经存在在Hadoop HDFS上的数据,除了在删除外部表时只删除元数据而不会删除表数据外,其他和内部表很像。

  创建外部表:

  CREATE EXTERNAL TABLE IF NOT EXISTS students(user_no INT,name STRING,sex STRING, class STRING COMMOT '班级')COMMONT '学生表' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORE AS SEQUENCEFILE LOCATION '/usr/test/data/students.txt'; 2.4 Hive 分区表

  分区表的每一个分区都对应数据库中相应分区列的一个索引,但是其组织方式和传统的关系型数据库不同。在Hive中,分区表的每一个分区都对应表下的一个目录,所有的分区的数据都存储在对应的目录中。

  比如说,分区表partitinTable有包含nation(国家)、ds(日期)和city(城市)3个分区,其中nation = china,ds = 20130506,city = Shanghai则对应HDFS上的目录为:

  /datawarehouse/partitinTable/nation=china/city=Shanghai/ds=20130506/。

  分区中定义的变量名不能和表中的列相同。

  创建分区表:

  CREATE TABLE IF NOT EXISTS students(user_no INT,name STRING,sex STRING, class STRING COMMOT '班级')COMMONT '学生表' PARTITIONED BY (ds STRING,country STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORE AS SEQUENCEFILE;2.5 Hive 分桶表

  桶表就是对指定列进行哈希(hash)计算,然后会根据hash值进行切分数据,将具有不同hash值的数据写到每个桶对应的文件中。

  将数据按照指定的字段进行分成多个桶中去,说白了就是将数据按照字段进行划分,可以将数据按照字段划分到多个文件当中去。

  创建分桶表:

  CREATE TABLE IF NOT EXISTS students(user_no INT,name STRING,sex STRING, class STRING COMMOT '班级',score SMALLINT COMMOT '总分')COMMONT '学生表' PARTITIONED BY (ds STRING,country STRING) CLUSTERED BY(user_no) SORTED BY(score) INTO 32 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORE AS SEQUENCEFILE; 2.6 Hive 视图

  在 Hive 中,视图是逻辑数据结构,可以通过隐藏复杂数据操作(Joins, 子查询, 过滤,数据扁平化)来于简化查询操作。

  与关系数据库不同的是,Hive视图并不存储数据或者实例化。一旦创建 HIve 视图,它的 schema 也会立刻确定下来。对底层表后续的更改(如 增加新列)并不会影响视图的 schema。如果底层表被删除或者改变,之后对视图的查询将会 failed。基于以上 Hive view 的特性,我们在ETL和数据仓库中对于经常变化的表应慎重使用视图。

  创建视图:

  CREATE VIEW employee_skills ASSELECT name, skills_score['DB'] AS DB,skills_score['Perl'] AS Perl, skills_score['Python'] AS Python,skills_score['Sales'] as Sales, skills_score['HR'] as HR FROM employee;创建视图的时候是不会触发 MapReduce 的 Job,因为只存在元数据的改变。

  但是,当对视图进行查询的时候依然会触发一个 MapReduce Job 进程:SHOW CREATE TABLE 或者 DESC FORMATTED TABLE 语句来显示通过 CREATE VIEW 语句创建的视图。以下是对Hive 视图的 DDL操作:

  更改视图的属性:

  ALTER VIEW employee_skills SET TBLPROPERTIES ('comment' = 'This is a view');重新定义视图:

  ALTER VIEW employee_skills AS SELECT * from employee ;删除视图:

  DROP VIEW employee_skills; 三、Hive数据抽样

  当数据规模不断膨胀时,我们需要找到一个数据的子集来加快数据分析效率。因此我们就需要通过筛选和分析数据集为了进行模式 & 趋势识别。目前来说有三种方式来进行抽样:随机抽样,桶表抽样,和块抽样。

  3.1 随机抽样

  关键词:rand()函数。

  使用rand()函数进行随机抽样,limit关键字限制抽样返回的数据,其中rand函数前的distribute和sort关键字可以保证数据在mapper和reducer阶段是随机分布的。

  案例如下:

  select * from table_name where col=xxx distribute by rand() sort by rand() limit num; 使用order 关键词:

  案例如下:

  select * from table_name where col=xxx order by rand() limit num; 经测试对比,千万级数据中进行随机抽样 order by方式耗时更长,大约多30秒左右。

  3.2 块抽样

  关键词:tablesample()函数。

  tablesample(n percent) 根据hive表数据的大小按比例抽取数据,并保存到新的hive表中。如:抽取原hive表中10%的数据注意:测试过程中发现,select语句不能带where条件且不子查询,可通过新建中间表或使用随机抽样解决。

  select * from xxx tablesample(10 percent) 数字与percent之间要有空格tablesample(nM) 指定抽样数据的大小,单位为M。select * from xxx tablesample(20M) 数字与M之间不要有空格tablesample(n rows) 指定抽样数据的行数,其中n代表每个map任务均取n行数据,map数量可通过hive表的简单查询语句确认(关键词:number of mappers: x)select * from xxx tablesample(100 rows) 数字与rows之间要有空格3.3 桶表抽样

  关键词:tablesample (bucket x out of y [on colname])。

  其中x是要抽样的桶编号,桶编号从1开始,colname表示抽样的列,y表示桶的数量。

  hive中分桶其实就是根据某一个字段Hash取模,放入指定数据的桶中,比如将表table_1按照ID分成100个桶,其算法是hash(id) % 100,这样,hash(id) % 100 = 0的数据被放到第一个桶中,hash(id) % 100 = 1的记录被放到第二个桶中。创建分桶表的关键语句为:CLUSTER BY语句。

  例如:将表随机分成10组,抽取其中的第一个桶的数据:

  select * from table_01 tablesample(bucket 1 out of 10 on rand())四、Hive计算引擎

  目前HiveMapReduce、Tez和Spark 三种计算引擎。

  4.1 MR计算引擎

  MR运行的完整过程:

  Map在读取数据时,先将数据拆分成若干数据,并读取到Map方法中被处理。数据在输出的时候,被分成若干分区并写入内存缓存(buffer)中,内存缓存被数据填充到一定程度会溢出到磁盘并排序,当Map执行完后会将一个机器上输出的临时文件进行归并存入到HDFS中。

  当Reduce启动时,会启动一个线程去读取Map输出的数据,并写入到启动Reduce机器的内存中,在数据溢出到磁盘时会对数据进行再次排序。当读取数据完成后会将临时文件进行合并,作为Reduce函数的数据源。

  4.2 Tez计算引擎

  Apache Tez是进行大规模数据处理且DAG作业的计算框架,它直接源于MapReduce框架,除了能够MapReduce特性,还新的作业形式,并允许不同类型的作业能够在一个集群中运行。

  Tez将原有的Map和Reduce两个操作简化为一个概念——Vertex,并将原有的计算处理节点拆分成多个组成部分:Vertex Input、Vertex Output、Sorting、Shuffling和Merging。计算节点之间的数据通信被统称为Edge,这些分解后的元操作可以任意灵活组合,产生新的操作,这些操作经过一些控制程序组装后,可形成一个大的DAG作业。

  通过允许Apache Hive运行复杂的DAG任务,Tez可以用来处理数据,之前需要多个MR jobs,现在一个Tez任务中。

  Tez和MapReduce作业的比较:

  Tez绕过了MapReduce很多不必要的中间的数据存储和读取的过程,直接在一个作业中表达了MapReduce需要多个作业共同协作才能完成的事情。Tez和MapReduce一样都运行使用YARN作为资源调度和管理。但与MapReduce on YARN不同,Tez on YARN并不是将作业提交到ResourceManager,而是提交到AMPoolServer的服务上,AMPoolServer存放着若干已经预先启动ApplicationMaster的服务。当用户提交一个作业上来后,AMPoolServer从中选择一个ApplicationMaster用于管理用户提交上来的作业,这样既可以节省ResourceManager创建ApplicationMaster的时间,而又能够重用每个ApplicationMaster的资源,节省了资源释放和创建时间。Tez相比于MapReduce有几点重大改进:

  当查询需要有多个reduce逻辑时,Hive的MapReduce引擎会将计划分解,每个Redcue提交一个MR作业。这个链中的所有MR作业都需要逐个调度,每个作业都必须从HDFS中重新读取上一个作业的输出并重新洗牌。而在Tez中,几个reduce接收器可以直接连接,数据可以流水线传输,而不需要临时HDFS文件,这种模式称为MRR(Map-reduce-reduce*)。Tez还允许一次发送整个查询计划,实现应用程序动态规划,从而使框架能够更智能地分配资源,并通过各个阶段流水线传输数据。对于更复杂的查询来说,这是一个巨大的改进,因为它消除了IO/sync障碍和各个阶段之间的调度开销。在MapReduce计算引擎中,无论数据大小,在洗牌阶段都以相同的方式执行,将数据序列化到磁盘,再由下游的程序去拉取,并反序列化。Tez可以允许小数据集完全在内存中处理,而MapReduce中没有这样的优化。仓库查询经常需要在处理完大量的数据后对小型数据集进行排序或聚合,Tez的优化也能极大地提升效率。4.3 Spark计算引擎

  Apache Spark是专为大规模数据处理而设计的快速、通用DAG(有向无环图)作业的计算引擎,类似于Hadoop MapReduce的通用并行框架,可用来构建大型的、低延迟的数据分析应用程序。

  Spark是用于大规模数据处理的统一分析引擎,基于内存计算,提高了在大数据环境下数据处理的实时性,同时保证了高容错性和高可伸缩性,允许用户将Spark部署在大量硬件之上,形成集群。

  Spark运行流程

  Spark运行流程

  Spark具有以下几个特性。

  1.高效性

  Spark会将作业构成一个DAG,优化了大型作业一些重复且浪费资源的操作,对查询进行了优化,重新编写了物理执行引擎,如可以实现MRR模式。

  2.易用性

  Spark不同于MapReducer只提供两种简单的编程接口,它提供了多种编程接口去操作数据,这些操作接口如果使用MapReduce去实现,需要更多的代码。Spark的操作接口可以分为两类:transformation(转换)和action(执行)。Transformation包含map、flatmap、distinct、reduceByKey和join等转换操作;Action包含reduce、collect、count和first等操作。

  3.通用性

  Spark针对实时计算、批处理、交互式查询,提供了统一的解决方案。但在批处理方面相比于MapReduce处理同样的数据,Spark所要求的硬件设施更高,MapReduce在相同的设备下所能处理的数据量会比Spark多。所以在实际工作中,Spark在批处理方面只能算是MapReduce的一种补充。

  4.兼容性

  Spark和MapReduce一样有丰富的产品生态做支撑。例如Spark可以使用YARN作为资源管理器,Spark也可以处理Hbase和HDFS上的数据。

  五、存储与压缩

  5.1 Hive存储格式

  Hive的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、ORC(列式存储)、PARQUET(列式存储)。

  5.1.1 行式存储和列式存储

  上图左边为逻辑表,右边第一个为行式存储,第二个为列式存储。

  行存储的特点: 查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。select *

  列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。 select 某些字段效率更高。

  5.1.2 TEXTFILE

  默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

  5.1.3 ORC格式

  Orc (Optimized Row Columnar)是hive 0.11版里引入的新的存储格式。

  可以看到每个Orc文件由1个或多个stripe组成,每个stripe250MB大小,这个Stripe实际相当于RowGroup概念,不过大小由4MB->250MB,这样能提升顺序读的吞吐率。每个Stripe里有三部分组成,分别是Index Data,Row Data,Stripe Footer:

  Index Data:一个轻量级的index,默认是每隔1W行做一个索引。这里做的索引只是记录某行的各字段在Row Data中的offset。Row Data:存的是具体的数据,先取部分行,然后对这些行按列进行存储。对每个列进行了编码,分成多个Stream来存储。Stripe Footer:存的是各个stripe的元数据信息每个文件有一个File Footer,这里面存的是每个Stripe的行数,每个Column的数据类型信息等;每个文件的尾部是一个PostScript,这里面记录了整个文件的压缩类型以及FileFooter的长度信息等。在读取文件时,会seek到文件尾部读PostScript,从里面解析到File Footer长度,再读FileFooter,从里面解析到各个Stripe信息,再读各个Stripe,即从后往前读。

  5.1.4 PARQUET格式

  Parquet是面向分析型业务的列式存储格式,由Twitter和Cloudera合作开发,2015年5月从Apache的孵化器里毕业成为Apache顶级项目。

  Parquet文件是以二进制方式存储的,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此Parquet格式文件是自解析的。

  通常情况下,在存储Parquet数据的时候会按照Block大小设置行组的大小,由于一般情况下每一个Mapper任务处理数据的最小单位是一个Block,这样可以把每一个行组由一个Mapper任务处理,增大任务执行并行度。Parquet文件的格式如下图所示。

  上图展示了一个Parquet文件的内容,一个文件中可以存储多个行组,文件的首位都是该文件的Magic Code,用于校验它是否是一个Parquet文件,Footer length记录了文件元数据的大小,通过该值和文件长度可以计算出元数据的偏移量,文件的元数据中包括每一个行组的元数据信息和该文件存储数据的Schema信息。除了文件中每一个行组的元数据,每一页的开始都会存储该页的元数据,在Parquet中,有三种类型的页:数据页、字典页和索引页。数据页用于存储当前行组中该列的值,字典页存储该列值的编码字典,每一个列块中最多包含一个字典页,索引页用来存储当前行组下该列的索引,目前Parquet中还不索引页。

  5.2 Hive压缩格式

  在实际工作当中,hive当中处理的数据,一般都需要经过压缩,前期我们在学习hadoop的时候,已经配置过hadoop的压缩,我们这里的hive也是一样的可以使用压缩来节省我们的MR处理的网络带宽

  mr的压缩格式:

  压缩格式 工具 算法 文件扩展名 是否可切分 DEFAULT 无 DEFAULT .deflate 否 Gzip gzip DEFAULT .gz 否 bzip2 bzip2 bzip2 .bz2 是 LZO lzop LZO .lzo 否 LZ4 无 LZ4 .lz4 否 Snappy 无 Snappy .snappy 否

  hadoop的解压缩的类:

  压缩格式 对应的编码/解码器 DEFLATE org.apache.hadoop.io.compress.DefaultCodec gzip org.apache.hadoop.io.compress.GzipCodec bzip2 org.apache.hadoop.io.compress.BZip2Codec LZO com.hadoop.compression.lzo.LzopCodec LZ4 org.apache.hadoop.io.compress.Lz4Codec Snappy org.apache.hadoop.io.compress.SnappyCodec

  压缩性能的比较:

  压缩算法 原始文件大小 压缩文件大小 压缩速度 解压速度 gzip 8.3GB 1.8GB 17.5MB/s 58MB/s bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s LZO 8.3GB 2.9GB 49.3MB/s 74.6MB/s

  Snappy生成的压缩文件要大20%到100%。在64位模式下的core i7处理器的单内核上,Snappy以250 MB/秒或更多的速度压缩,并以500 MB/秒或更多的速度解压。

  实现压缩hadoop需要配置的压缩参数:

  hive配置压缩的方式:

  开启map端的压缩方式:1.1)开启hive中间传输数据压缩功能 hive (default)>set hive.exec.compress.intermediate=true;1.2)开启mapreduce中map输出压缩功能 hive (default)>set mapreduce.map.output.compress=true;1.3)设置mapreduce中map输出数据的压缩方式 hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;1.4)执行查询语句 select count(1) from score;开启reduce端的压缩方式1)开启hive最终输出数据压缩功能 hive (default)>set hive.exec.compress.output=true;2)开启mapreduce最终输出数据压缩 hive (default)>set mapreduce.output.fileoutputformat.compress=true;3)设置mapreduce最终数据输出压缩方式 hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;4)设置mapreduce最终数据输出压缩为块压缩 hive (default)>set mapreduce.output.fileoutputformat.compress.type=BLOCK;5)测试一下输出结果是否是压缩文件 insert overwrite local directory '/export/servers/snappy' select * from score distribute by s_id sort by s_id desc;5.3 存储和压缩相结合

  ORC存储方式的压缩:

  Key Default Notes orc.compress ZLIB 高级压缩(可选: NONE, ZLIB, SNAPPY) orc.compress.size 262,144 每个压缩块中的字节数 orc.stripe.size 67,108,864 每条stripe中的字节数 orc.row.index.stride 10,000 索引条目之间的行数(必须是>= 1000) orc.create.index true 是否创建行索引 orc.bloom.filter.columns "" 逗号分隔的列名列表,应该为其创建bloom过滤器 orc.bloom.filter.fpp 0.05 bloom过滤器的假阳性概率(必须是>0.0和<1.0)

  创建一个非压缩的ORC存储方式:

  1)建表语句 create table log_orc_none( track_time string, url string, session_id string, referer string, ip string, _user_id string, city_id string )ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS orc tblproperties ("orc.compress"="NONE");2)插入数据 insert into table log_orc_none select * from log_text ;3)查看插入后数据 dfs -du -h /user/hive/warehouse/myhive.db/log_orc_none; 结果显示: 7.7 M /user/hive/warehouse/log_orc_none/123456_0创建一个SNAPPY压缩的ORC存储方式:

  1)建表语句 create table log_orc_snappy( track_time string, url string, session_id string, referer string, ip string, _user_id string, city_id string )ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS orc tblproperties ("orc.compress"="SNAPPY");2)插入数据 insert into table log_orc_snappy select * from log_text ;3)查看插入后数据 dfs -du -h /user/hive/warehouse/myhive.db/log_orc_snappy ; 结果显示: 3.8 M /user/hive/warehouse/log_orc_snappy/123456_04)上一节中默认创建的ORC存储方式,导入数据后的大小为 2.8 M /user/hive/warehouse/log_orc/123456_0 比Snappy压缩的还小。原因是orc存储文件默认采用ZLIB压缩。比snappy压缩的小。5)存储方式和压缩总结: 在实际的项目开发当中,hive表的数据存储格式一般选择:orc或parquet。压缩方式一般选择snappy。5.4 主流存储文件性能对比

  从存储文件的压缩比和查询速度两个角度对比。

  压缩比比较:

  TextFile(1)创建表,存储数据格式为TEXTFILE create table log_text ( track_time string, url string, session_id string, referer string, ip string, _user_id string, city_id string )ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE ;(2)向表中加载数据 load data local inpath '/export/servers/hivedatas/log.data' into table log_text ;(3)查看表中数据大小,大小为18.1M dfs -du -h /user/hive/warehouse/myhive.db/log_text; 结果显示: 18.1 M /user/hive/warehouse/log_text/log.dataORC(1)创建表,存储数据格式为ORC create table log_orc( track_time string, url string, session_id string, referer string, ip string, _user_id string, city_id string )ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS orc ;(2)向表中加载数据 insert into table log_orc select * from log_text ;(3)查看表中数据大小 dfs -du -h /user/hive/warehouse/myhive.db/log_orc; 结果显示: 2.8 M /user/hive/warehouse/log_orc/123456_0Parquet1)创建表,存储数据格式为parquet create table log_parquet( track_time string, url string, session_id string, referer string, ip string, _user_id string, city_id string )ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS PARQUET ; 2)向表中加载数据 insert into table log_parquet select * from log_text ;3)查看表中数据大小 dfs -du -h /user/hive/warehouse/myhive.db/log_parquet; 结果显示: 13.1 M /user/hive/warehouse/log_parquet/123456_0数据压缩比结论:

  ORC > Parquet > textFile

  存储文件的查询效率测试

  textFilehive (default)> select count(*) from log_text;_c0100000Time taken: 21.54 seconds, Fetched: 1 row(s) ORChive (default)> select count(*) from log_orc;_c0100000Time taken: 20.867 seconds, Fetched: 1 row(s) Parquethive (default)> select count(*) from log_parquet; _c0100000Time taken: 22.922 seconds, Fetched: 1 row(s)存储文件的查询效率比较:

  ORC > TextFile > Parquet

  六、Hive Sql 大全

  本节基本涵盖了Hive日常使用的所有SQL,因为SQL太多,所以将SQL进行了如下分类: 一、DDL语句(数据定义语句):

  对数据库的操作:包含创建、修改数据库

  对数据表的操作:分为内部表及外部表,分区表和分桶表

  二、DQL语句(数据查询语句):

  单表查询、关联查询

  hive函数:包含聚合函数,条件函数,日期函数,字符串函数等

  行转列及列转行:lateral view 与 explode 以及 reflect

  窗口函数与分析函数

  其他一些窗口函数

  hive的DDL语法

  对数据库的操作

  创建数据库:create database if not exists myhive;说明:hive的表存放位置模式是由hive-site.xml当中的一个属性指定的 :hive.metastore.warehouse.dir创建数据库并指定hdfs存储位置 :create database myhive2 location '/myhive2';修改数据库:alter database myhive2 set dbproperties('createtime'='20210329');说明:可以使用alter database 命令来修改数据库的一些属性。但是数据库的元数据信息是不可更改的,包括数据库的名称以及数据库所在的位置

  查看数据库详细信息查看数据库基本信息hive (myhive)> desc database myhive2;查看数据库更多详细信息hive (myhive)> desc database exted myhive2;删除数据库删除一个空数据库,如果数据库下面有数据表,那么就会报错drop database myhive2;强制删除数据库,包含数据库下面的表一起删除drop database myhive cascade; 对数据表的操作

  对管理表(内部表)的操作:

  建内部表:hive (myhive)> use myhive; -- 使用myhive数据库hive (myhive)> create table stu(id int,name string);hive (myhive)> insert into stu values (1,"zhangsan");hive (myhive)> insert into stu values (1,"zhangsan"),(2,"lisi"); -- 一次插入多条数据hive (myhive)> select * from stu;hive建表时候的字段类型:分类 类型 描述 字面量示例 原始类型 BOOLEAN true/false TRUE TINYINT 1字节的有符号整数 -128~127 1Y SMALLINT 2个字节的有符号整数,-32768~32767 1S INT 4个字节的带符号整数 1 BIGINT 8字节带符号整数 1L FLOAT 4字节单精度浮点数1.0 DOUBLE 8字节双精度浮点数 1.0 DEICIMAL 任意精度的带符号小数 1.0 STRING 字符串,变长 “a”,’b’ VARCHAR 变长字符串 “a”,’b’ CHAR 固定长度字符串 “a”,’b’ BINARY 字节数组 无法表示 TIMESTAMP 时间戳,毫秒值精度 122327493795 DATE 日期 ‘2016-03-29’ INTERVAL 时间频率间隔 复杂类型 ARRAY 有序的的同类型的集合 array(1,2) MAP key-value,key必须为原始类型,value可以任意类型 map(‘a’,1,’b’,2) STRUCT 字段集合,类型可以不同 struct(‘1’,1,1.0), named_stract(‘col1’,’1’,’col2’,1,’clo3’,1.0) UNION 在有限取值范围内的一个值 create_union(1,’a’,63)

  对decimal类型简单解释下:

  用法:decimal(11,2) 代表最多有11位数字,其中后2位是小数,整数部分是9位;如果整数部分超过9位,则这个字段就会变成null;如果小数部分不足2位,则后面用0补齐两位,如果小数部分超过两位,则超出部分四舍五入

  也可直接写 decimal,后面不指定位数,默认是 decimal(10,0) 整数10位,没有小数

  七、Hive执行计划

  Hive SQL的执行计划描述SQL实际执行的整体轮廓,通过执行计划能了解SQL程序在转换成相应计算引擎的执行逻辑,掌握了执行逻辑也就能更好地把握程序出现的瓶颈点,从而能够实现更有针对性的优化。此外还能帮助开发者识别看似等价的SQL其实是不等价的,看似不等价的SQL其实是等价的SQL。可以说执行计划是打开SQL优化大门的一把钥匙。

  要想学SQL执行计划,就需要学习查看执行计划的命令:explain,在查询语句的SQL前面加上关键字explain是查看执行计划的基本方法。

  学会explain,能够给我们工作中使用hive带来极大的便利!

  查看SQL的执行计划

  Hive提供的执行计划目前可以查看的信息有以下几种:

  explain:查看执行计划的基本信息;explain depency:depency在explain语句中使用会产生有关计划中输入的额外信息。它显示了输入的各种属性;explain authorization:查看SQL操作相关权限的信息;explain vectorization:查看SQL的向量化描述信息,显示为什么未对Map和Reduce进行矢量化。从 Hive 2.3.0 开始;explain analyze:用实际的行数注释计划。从 Hive 2.2.0 开始;explain cbo:输出由Calcite优化器生成的计划。CBO 从 Hive 4.0.0 版本开始;explain locks:这对于了解系统将获得哪些锁以运行指定的查询很有用。LOCKS 从 Hive 3.2.0 开始;explain ast:输出查询的抽象语法树。AST 在 Hive 2.1.0 版本删除了,存在bug,转储AST可能会导致OOM错误,将在4.0.0版本修复;explain exted:加上 exted 可以输出有关计划的额外信息。这通常是物理信息,例如文件名,这些额外信息对我们用处不大;1. explain 的用法

  Hive提供了explain命令来展示一个查询的执行计划,这个执行计划对于我们了解底层原理,Hive 调优,排查数据倾斜等很有帮助。

  使用语法如下:

  explain query;在 hive cli 中输入以下命令(hive 2.3.7):

  explain select sum(id) from test1;得到结果:

  STAGE DEPENCIES: Stage-1 is a root stage Stage-0 deps on stages: Stage-1STAGE PLANS: Stage: Stage-1 Map Reduce Map Operator Tree: TableScan alias: test1 Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE Select Operator expressions: id (type: int) outputColumnNames: id Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE Group By Operator aggregations: sum(id) mode: hash outputColumnNames: _col0 Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE Reduce Output Operator sort order: Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE value expressions: _col0 (type: bigint) Reduce Operator Tree: Group By Operator aggregations: sum(VALUE._col0) mode: mergepartial outputColumnNames: _col0 Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE File Output Operator compressed: false Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE table: input format: org.apache.hadoop.mapred.SequenceFileInputFormat output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe Stage: Stage-0 Fetch Operator limit: -1 Processor Tree: ListSink看完以上内容有什么感受,是不是感觉都看不懂,不要着急,下面将会详细讲解每个参数,相信你学完下面的内容之后再看 explain 的查询结果将游刃有余。

  一个HIVE查询被转换为一个由一个或多个stage组成的序列(有向无环图DAG)。这些stage可以是MapReduce stage,也可以是负责元数据存储的stage,也可以是负责文件系统的操作(比如移动和重命名)的stage。

  我们将上述结果拆分看,先从最外层开始,包含两个大的部分:

  stage depencies: 各个stage之间的依赖性stage plan: 各个stage的执行计划先看第一部分 stage depencies ,包含两个 stage,Stage-1 是根stage,说明这是开始的stage,Stage-0 依赖 Stage-1,Stage-1执行完成后执行Stage-0。

  再看第二部分 stage plan,里面有一个 Map Reduce,一个MR的执行计划分为两个部分:

  Map Operator Tree: MAP端的执行计划树Reduce Operator Tree: Reduce端的执行计划树这两个执行计划树里面包含这条sql语句的 operator:

  TableScan:表扫描操作,map端第一个操作肯定是加载表,所以就是表扫描操作,常见的属性: alias: 表名称Statistics: 表统计信息,包含表中数据条数,数据大小等Select Operator: 选取操作,常见的属性 : expressions:需要的字段名称及字段类型outputColumnNames:输出的列名称Statistics:表统计信息,包含表中数据条数,数据大小等Group By Operator:分组聚合操作,常见的属性: aggregations:显示聚合函数信息mode:聚合模式,值有 hash:随机聚合,就是hash partition;partial:局部聚合;final:最终聚合keys:分组的字段,如果没有分组,则没有此字段outputColumnNames:聚合之后输出列名Statistics: 表统计信息,包含分组聚合之后的数据条数,数据大小等Reduce Output Operator:输出到reduce操作,常见属性: sort order:值为空 不排序;值为 + 正序排序,值为 - 倒序排序;值为 +- 排序的列为两列,第一列为正序,第二列为倒序Filter Operator:过滤操作,常见的属性: predicate:过滤条件,如sql语句中的where id>=1,则此处显示(id >= 1)Map Join Operator:join 操作,常见的属性: condition map:join方式 ,如Inner Join 0 to 1 Left Outer Join0 to 2keys: join 的条件字段outputColumnNames: join 完成之后输出的字段Statistics: join 完成之后生成的数据条数,大小等File Output Operator:文件输出操作,常见的属性 compressed:是否压缩table:表的信息,包含输入输出文件格式化方式,序列化方式等Fetch Operator 客户端获取数据操作,常见的属性: limit,值为 -1 表示不限制条数,其他值为限制的条数2. explain 的使用场景

  本节介绍 explain 能够为我们在生产实践中带来哪些便利及解决我们哪些迷惑

  案例一:join 语句会过滤 null 的值吗?

  现在,我们在hive cli 输入以下查询计划语句

  select a.id,b.user_name from test1 a join test2 b on a.id=b.id;问:上面这条 join 语句会过滤 id 为 null 的值吗

  执行下面语句:

  explain select a.id,b.user_name from test1 a join test2 b on a.id=b.id;我们来看结果 (为了适应页面展示,仅截取了部分输出信息):

  TableScan alias: a Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE Filter Operator predicate: id is not null (type: boolean) Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE Select Operator expressions: id (type: int) outputColumnNames: _col0 Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE HashTable Sink Operator keys: 0 _col0 (type: int) 1 _col0 (type: int) ...从上述结果可以看到 predicate: id is not null 这样一行,说明 join 时会自动过滤掉关联字段为 null 值的情况,但 left join 或 full join 是不会自动过滤null值的,大家可以自行尝试下。

  案例二:group by 分组语句会进行排序吗?

  看下面这条sql

  select id,max(user_name) from test1 group by id;问:group by 分组语句会进行排序吗

  直接来看 explain 之后结果 (为了适应页面展示,仅截取了部分输出信息)

   TableScan alias: test1 Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE Select Operator expressions: id (type: int), user_name (type: string) outputColumnNames: id, user_name Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE Group By Operator aggregations: max(user_name) keys: id (type: int) mode: hash outputColumnNames: _col0, _col1 Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE Reduce Output Operator key expressions: _col0 (type: int) sort order: + Map-reduce partition columns: _col0 (type: int) Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE value expressions: _col1 (type: string) ...我们看 Group By Operator,里面有 keys: id (type: int) 说明按照 id 进行分组的,再往下看还有 sort order: + ,说明是按照 id 字段进行正序排序的。

  案例三:哪条sql执行效率高呢?

  观察两条sql语句

  SELECT a.id, b.user_nameFROM test1 aJOIN test2 b ON a.id = b.idWHERE a.id > 2;SELECT a.id, b.user_nameFROM (SELECT * FROM test1 WHERE id > 2) aJOIN test2 b ON a.id = b.id;这两条sql语句输出的结果是一样的,但是哪条sql执行效率高呢?

  有人说第一条sql执行效率高,因为第二条sql有子查询,子查询会影响性能;

  有人说第二条sql执行效率高,因为先过滤之后,在进行join时的条数减少了,所以执行效率就高了。

  到底哪条sql效率高呢,我们直接在sql语句前面加上 explain,看下执行计划不就知道了嘛!

  在第一条sql语句前加上 explai。

标签: 移动UI设计