• 【Hive三】Hive理论


    1. Hive基础

    Hive基本概念

    引入原因:

    • – 对存在HDFS上的文件或HBase中的表进行查询时,是要手工写一堆MapReduce码
    • – 对于统计任务,只能由动MapReduce的程序员才能搞定
    • – 耗时耗力,更多精力没有有效的释放出来

    Hive是什么

    • Hive基于一个统一的查询分析层,通过SQL语句的方式对HDFS上的数据进行查询、统计和分析

    • Hive是一个SQL解析引擎,将SQL语句转译成MR然后再Hadoop平台上运行,达到快速开发的目的

    • Hive中的表是 纯逻辑 表,就只是表的定义等,即表的元数据。本质就是Hadoop的目录/文件,达到了元数据与数据存储分离的目的

    • Hive本身不存储数据,它完全依赖HDFS和MapReduce。

    • Hive的内容是读多写少,不支持对数据的改写和删除(0.14版本之后,Hive支持更新删除功能,但需要手动进行配置 )

    • Hive中没有定义专门的数据格式,由用户指定,需要指定三个属性:

      • 列分隔符

        • ****
      • 行分隔符

        • 空格、 、01
      • 读取文件数据的方法

        • TextFileSequenceFile(二进制,是hadoop提供的一种二进制文件,<key,value>形式序列化到文件中,java writeable接口进行序列化和反序列化)、RCFile(是Hive专门推出的一种面向列的数据格式)
    • 为什么选择Hive

      因为简单!!

      select word, count(*)
      from (
      select
      explode(split(sentence, ' ')) as word
      from article
      ) t
      group by word
      
    • Hsql与传统sql区别

      Hsql sql
      数据存储 HDFS、 Hbase Local FS
      数据格式 用户自定义 系统决定
      数据更新 不支持(把之前的数据覆盖) 支持
      索引 有(0.8版之后增加)
      执行 MapReduce Executor
      执行延迟
      可扩展性 高(UDF、 UDAF,UDTF)
      数据规模 大(数据大于TB)
      数据检查 读时模式 写时模式
    • UDF,UDAF,UDTF

      1. UDF:直接应用于select语句,通常查询的时候,需要对字段做一些格式化处理(大小写转换),特点:一进一出,1比1

      2. UDAF:多对一场景,group by

      3. UDTF:一对多场景

    • 读时模式 vs 写时模式

      1. 读时模式:只有hive读的时候才会检查、解析字段和schema,优点:加载数据很迅速,因为在写的过程中是不需要解析数据

      2. 写时模式:缺点:写的慢,需要建立一些索引、压缩、数据一致性、字段检查等,优点:读的时候会得到优化

    • 与传统关系型数据库特点比较

      1. hive和关系数据库存储文件的系统不同,hive使用的是hadoop的HDFS(hadoop的分布式文件系统),关系数据库则是服务器本地的文件系统;

      2. hive使用的计算模型是mapreduce,而关系数据库则是自己设计的计算模型

      3. 关系数据库都是为实时查询的业务进行设计的,而hive则是为海量数据做数据挖掘设计的,实时性很差

      4. Hive很容易扩展自己的存储能力和计算能力,这个是继承hadoop的,而关系数据库在这个方面要比数据库差很多。

    Hive数据管理

    四种数据模型

    • Table(默认表,也称内部表)
    • External Table(外部表)
    • Partition(分区表)
    • Bucket(分桶表)
      1. Hive会针对某一个列进行桶组织,通常对列值做hash
      2. 优化查询、方便采样

    Hive内部表和外部表

    • Hive的create创建表的时候,选择的创建方式:

      1. create table(内部表)
      2. create external table(外部表)
    • 内部表 vs 外部表

      1. 差别:在对内部表操作的时候如果通过Hive对表进行删除,那么表结构和表中的数据也会删除,反之使用外部表的的话做删除操作时不会删除数据,只会删除表结构,所以尽量使用外部表

    Hive数据类型

    • 原生数据类型

      • TINYINT
      • SMALLINT
      • INT
      • BIGINT
      • BOOLEAN
      • FLOAT
      • DOUBLE
      • STRING
      • BINARY(Hive 0.8.0以上才可用)
      • TIMESTAMP(Hive 0.8.0以上才可用)
    • 复合类型

      • Arrays:ARRAY<data_type>
      • Maps:MAP<primitive_type, data_type>
      • Structs:STRUCT<col_name: data_type[COMMENT col_comment],……>
      • Union:UNIONTYPE<data_type, data_type,……>
    • 复合类型的作用

    • Hive Sql -- join in MR

    Hive的优化

    Map的优化:

    • – 作业会通过input的目录产生一个或者多个map任务。 set dfs.block.size(=128)

    • – Map越多越好吗?是不是保证每个map处理接近文件块的大小?

    • – 如何合并小文件,减少map数?

      set mapred.max.split.size=100000000;
      set mapred.min.split.size.per.node=100000000;
      set mapred.min.split.size.per.rack=100000000;
      set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHive`InputFormat;
    
    • – 如何适当的增加map数?
      set mapred.map.tasks=10;
    
    • – Map端聚合 hive.map.aggr=true ,Mr中的Combiners

    Reduce 的优化

    • hive.exec.reducers.bytes.per.reducer;reduce任务处理的数据量

    • 调整reduce的个数:

      • 设置reduce处理的数据量

      • set mapred.reduce.tasks=10

      select pt,count(1)
      from popt_tbaccountcopy_mes
      where pt = '2012-07-04' group by pt;
      写成
      select count(1)
      from popt_tbaccountcopy_mes
      where pt = '2012-07-04';
      

    一个Reduce:

    • 没有group by

    • order by(可以使用distribute by和sort by)

    • 笛卡尔积

    分区裁剪(partition)

    • – Where中的分区条件,会提前生效,不必特意做子查询,直接Join和GroupBy

    笛卡尔积

    • – join的时候不加on条件或者无效的on条件,Hive只能使用1个reducer来完成笛卡尔积

    Map join

    • /*+ MAPJOIN(tablelist) */,必须是小表,不要超过1G,或者50万条

    • 假设有A表、B表,有A.join(B),如果A表示小表的话,可考虑是否将A表放入到内存中(小表尽量少于1G),

    Union all

    • 先做union all再做join或group by等操作可以有效减少MR过程,尽管是多个Select,最终只有一个mr,数据不去重

    • union操作不会产生重复记录但效率稍低一些,union all会产生重复数据但效率比union高一些

    Multi-insert & multi-group by

    • – 从一份基础表中按照不同的维度,一次组合出不同的数据

    • – FROM from_statement

    • – INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1)]select_statement1 group by key1

    • – INSERT OVERWRITE TABLE tablename2 [PARTITION(partcol2=val2 )]select_statement2 group by key2

    Automatic merge

    • – 当文件大小比阈值小时,hive会启动一个mr进行合并

    • – hive.merge.mapfiles = true 是否和并 Map 输出文件,默认为 True

    • – hive.merge.mapredfiles = false 是否合并 Reduce 输出文件,默认为 False

    • – hive.merge.size.per.task = 25610001000 合并文件的大小

    Multi-Count Distinct

    • – 必须设置参数:set hive.groupby.skewindata=true;

    • – select dt, count(distinct uniq_id), count(distinct ip)

    • – from ods_log where dt=20170301 group by dt

    Hive优化-- 大小表关联

    • 原因

      • Hive在进行join时,按照join的key进行分发,而在join左边的表的数据会首先读入内存,如果左边表的key相对分散,读入内存的数据会比较小,join任务执行会比较快;而如果左边的表key比较集中,而这张表的数据量很大,那么数据倾斜就会比较严重,而如果这张表是小表,则还是应该把这张表放在join左边。
    • 思路

      • 将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率
      • 使用map join让小的维度表先进内存。
    • 方法

      • Small_table join big_table

    Hive优化-- 大大表关联

    • 原因

      • 日志中有一部分的userid是空或者是0的情况,导致在用user_id进行hash分桶的时候,会将日志中userid为0或者空的数据分到一起,导致了过大的斜率。
    • 思路

      • 把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
    • 方法

      • on case when (x.uid = '-' or x.uid = '0‘ or x.uid is null) then concat('dp_hive_search',rand()) else x.uid end = f.user_id;
  • 相关阅读:
    写代码随想
    学生管理系统
    自定义栈
    位运算符加密
    自定义Vector
    二叉树排序
    双向循环链表
    双向链表
    加载properties文件
    通讯录
  • 原文地址:https://www.cnblogs.com/screen/p/9102576.html
Copyright © 2020-2023  润新知