Hive

Hive

Hive简介:

  • 特点:是一个数据仓库工具,将结构化的数据映射为一张表,并提供SQL查询功能,将SQL解析成Job。
  • 本质:数据存储在HDFS上,元数据默认存储在derby上,Hive将HQL语言转化成MapReduce程序,程序运行在yarn上。由于derby仅支持单客户端,并不支持多客户端访问,可以将元数据存储在Mysql中,Hive将HDFS中的一个文件映射为一个库或一个表,文件中存放的是数据。表中的元数据在MySQL中,Hive只作为一个客户端,不存储任何数据。

说明:每张表对应HDFS中的一个目录,Hive是类SQL语言,除了拥有类似的查询语言,与数据库再无类似之处。
注: HIVE不是数据库,不是数据库,不是。而是一个数仓工具,而数据仓库的内容是读多写少。
结构化数据:有一定规律的数据。
表:光有数据不能构成表格, 构成表不能缺少元数据,即描述数据信息的数据 。

Hive缺点:

  1. Hive自动生成MR,不够智能化,基于MR的限制不能实现高效的算法,不擅长数据挖掘。
  2. Hive跑的时MR所以有延时,不能做实时分析;调优困难,粒度较粗。
  3. Hive分析的数据存储在HDFS上,不支持行级别更新,只能追加写,且不能实时查询。

Hive架构:

  1. Client:

    • CLI:用户接口
    • JDBC:JDBC/ODBC 的方式连接
    • Driver:通过驱动JDBC将客户端与服务器进行连接
    • SQL Parser 解析器:将SQL字符串转换成抽象语法树AST,对AST进行语法分析,判断表是否存在、字段是否存在、SQL是否语义错误
    • Physical Plan 编译器:将AST编译生成逻辑执行计划
    • Query Optimizer 优化器:对逻辑执行计划进行优化
    • Execution 执行器:把逻辑执行计划转换成可以运行的物理计划,实质跑MR/Spark.
  2. MapReduce:

    • 编译好的SQL语句最终会在MR上运行计算,Hive的数据分析基于MR。
  3. HDFS:

    一个HDFS目录对应Hive的一张表,用来存储Hive的数据。

  4. Meta Store:

    • 用来存储HIVE的元数据,默认时derby数据库,但是仅支持单窗口模式,推荐MySQL。

Hive 数据更新:

  • Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此Hive中不建议对数据的改写,所有的数据都是在加载的时候确定好的。

Hive 执行延迟:

  • Hive 查询数据的时候,没有索引要扫描整个表,导致延迟较高;
  • 并且Hive的数据分析基于MapReduce也会导致执行延迟高。

Hive 服务:

  • Metastore:用于Hive的元数据服务,默认有元数据服务,如果配置文件中没有配置,不需要开启该服务也可以运行,如果配置文件中配置了,必须要开启。
  • Hiveserver2:用于JDBC连接Hive的服务,开启该服务可以使用第三方工具通过JDBC的方式连接到HIVE。

Hive 常见数据类型:

  • Hive中的String为可变字符串,但不能声明其中最多能存储多少个字符,理论上可以存储2GB字符数。
  • STRUCT: struct<street:string, city:string> 引用:struct.street 结构体只有成员属性的类,直接调用即可。
  • MAP: map<string, int> 引用:string
  • ARRAY: array 引用:[i]

类型转换:

  • Hive的原子数据类型是可以进行隐式转换即自动类型提升,但是Hive不会进行反向转化,若要转可以使用强转CAST。

隐式类型转换规则:

  1. 任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT。

  2. 所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE。

  3. TINYINT、SMALLINT、INT都可以转换为FLOAT。

  4. BOOLEAN类型不可以转换为任何其它的类型。

  5. 使用CAST操作显示进行数据类型转换:数据类型大的转成小的,不成功为null。

    注意:String 可以转换其他数值型,前提是数值型的String。

Hive中创建表的方式:

  1. 直接创建表
  2. 通过查询创建表
  3. Like创建表,创建的表结构完全相同,但是没有数据。

Hive中添加数据的声明:

  • Hdfs -put 这种方式添加的数据相当于走了捷径,Hive中不会添加元数据记录,并且put过的不能再put。
  • load data 这种方式是正统的方式,可以重复load ,它会重新添加一个copy 命名的文件。本地添加进表是复制过去的,Hdfs添加进表是剪切过去的。

Hive 的 4个By :

  • ORDER BY 全局排序:需要将所有的数据放入到一个reduce里面去处理。
  • SORT BY 分区排序:需要有多个reduce,然后随机分区,在区内根据指定字段排序。
  • DISREIBUTE BY 分区:根据指定字段分区,与 sort by 同时使用,根据指定的字段获取hash值,然后与reduce个数取余获取到分区位置。
  • CLUSTER BY:distribute 和 sort 的字段一样时可以使用 cluster by 进行分区排序 。不过根据字段分区在根据字段进行排序没啥用。

Hive 分区分桶:

  • 分区表:加快查询速度,分区分的是目录,在源头上将数据以文件夹的形式进行分区,由于分区后各分区会在查询结果中以列的形式显示,类似一个伪列,而原数据中并不含该字段,所以分区字段一定是表中没有的字段。
  • 分桶表:加快查询速度,分桶分的是具体的数据,以表中的某个字段进行分桶,同一个区的数据分文件进行管理。
    说明:批量添加分区时不加逗号,批量删除分区时必须加逗号。

表的侧写:

  • Lateral View : 侧写表等级相当于from,后面可以直接加where 筛选。

窗口函数:

  • 窗口函数 = 聚合函数 + over()开窗。

    说明:分组后不开窗,对分最后组内的元素进行聚合;分组后开窗,对分完组后的的结果进行聚合。

    • 有Order by没有窗口子句时 默认rows从前无边界到当前行
    • 没有Order by 和 窗口子句 默认从rows从前无边界到后无边界。
    • Rank()、Dense_rank()、Row_number()不负责排序,只负责排好序的数据进行编号。
    • RANK、ROW_NUMBER、DENSE_RANK、PERCENT_RANK、NTILE 后都无窗口子句。

    注意:当over() 中不写字段时窗口默认所有的key都是null会进入同一个区,出环形缓冲区时会反向溢写。

自定义函数:

  1. UDF:一进一出,普通函数,在哪里用都可以。
  2. UDTF:一进多出,生成。
  3. UDAF:多进一出,聚合。

临时函数和永久函数:

  • 临时函数只跟当前会话有关系,与库无关,在那个库下面都可以使用,其他会话全部不能使用。
  • 永久函数将库名挂在自定义的函数前面,默认只在当前库,只能再该库中使用,跨库不可以使用,若想跨库使用需要添加库名,但是虽然是永久函数不会被删除,但是当下一次会话开启时该自定义函数还是不可用,因为 add jar linux_jar_path 时临时生效的。需要自己手动添加,可以创建该函数jar包的hdfs路径, 也可以添加到配置文件中每次启动hive自动加载。

文件的存储格式:

  1. 行存:将表中的数据以行的顺序进行存储。

    • 特点:查询整行信息是行存快。如select * 。
      TEXTFILE和SEQUENCEFILE的存储格式都是基于行存储的。
  2. 列存:将表中的数据以列的顺序进行存储。

    • 特点:查询某个字段的信息列存快。如select 字段。

      ORC和PARQUET是基于列式存储的。

说明:
  • Hive中列存更好,因为频繁的查询多个字段的数据,但不需要所有的数据。
  • 内部表采用列存储格式,查询速度更高,数据通常引入到外部表,再将外部表中的数据插入到内部表,外部表通常不占HDFS空间。
TextFile:
  • 默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可以采用压缩进行存储
Orc:
  • 每个Orc文件由1个或多个stripe组成,每个stripe一般为HDFS的块大小,每一个stripe包含多条记录,这些记录按照列进行独立存储。

Stripe组成:

  1. Index Data:轻量级索引,每一万行做一个索引,该索引只记录某行的各字段在Row Data中的offset。
  2. Row Data:存储具体数据,先取部分行按列进行存储,对每个列进行编码,分成多个Stream存储。
  3. Stripe Footer:存储Stream的类型、长度信息。
说明:
  • 每个ORC文件都有一个File Footer和一个Postscript,File Footer用来存储每个Stream的行数和每个Column的数据类型,PostScript用来记录文件的压缩类型和File Footer的长度。
  • 读取ORC文件时,会最先Seek尾部读取Postscript从中解析到File Footer的长度,再读File Footer从中解析到Stripe信息,从后往前读。
  • 查询ORC文件比较快,因为ORC中带有的索引以及累计了总行数。
Parquet:
  • Parquet是以二进制的形式进行存储的,不可直接读取,文件中包含了数据和元数据信息,因此Parquent格式文件都是自解析的。

压缩与存储效率:

  1. 不压缩存储:TextFile 18.1; orc 7.7 ;parquet 13.1 所占空间效率:ORC > Parquet > textFile。
  2. 查询速度:TextFile 10.52s , orc 11.49 parquet 11.45 查询效率大差不差。
  3. 压缩存储:Orc_zlib 2.78; Orc_snappy 3.75 parquet_snappy 6.39。

Fetch 模式:

文件抓取的三个等级:

  • None:默认所有的查询都走mapreduce。
  • Minimal: select * 、filter on partition 以及 limit 不走mapreduce,其他都走。
  • More时:全局查找、字段查找、limit 都不走mapreduce。

Hive 优化:

  1. MapJoin。

  2. 行列过滤。

  3. 列式存储。

  4. 分区分桶。

  5. 合理设置map、Reduce个数。

  6. 小文件的产生与处理。

    说明:JVM重用:默认 map 9个、reducer1个、块大小128M只能往下调。

  7. 开启map端Combiner。

  8. 压缩存储。

  9. 使用Spark引擎。

  10. 当某个块128M只有1个字段时,一个map 处理他一行一行的读也非常的慢,所以用 nlineInputformat。

posted @ 2021-05-30 21:31  yuexiuping  阅读(227)  评论(0编辑  收藏  举报