Apache Hive(3)

Apache Hive

  • json数据的解析

    • 内置函数

      • get_json_object 一次可以解析出一个json值

      • json_tuple 可以解析出多个

      • 扩展:如果是json数组呢?

        • 思路:想法把json数组转换成为array 交给explode来炸开 结合 json_tuple 来使用
        regexp_replace('json数组', '\\}\\,\\{','\\}\\;\\{')   --把json数组中的分隔符替换成为;
        regexp_replace('asdas','[|]','')   --  |表示or   把json中的[或者]替换成为空
        
  • 窗口函数 分析函数

    • 格式:带有over语句的函数

      over (partition by xxx order by asc|desc)
      
      partition by用于指定根据表中哪个字段进行分 相同的分在一起
      order by用于指定相同分区内根据谁进行排序 默认是正序(升序)
      
    • 普通聚合函数和窗口函数的配合

      • 格式

        sum() avg() max()  over(partition by xxx order by asc|desc)
        
      • 默认是计算从第一行到当前行的操作 在这当中进行聚合操作

      • 还支持window 子句 rows between 用于指定行的范围

      • 如果不加order by asc|desc 只有partition by xxx 这时候聚合分区内所有的数据

    • row_number 、rank、dense_rank、ntile

      • 适用于求分组topN问题 和分组几分之几的问题

hive的数据压缩

  • 压缩的优缺点

    • 优点:减少带宽 减少磁盘空间
    • 缺点:浪费时间 增加cpu处理压力
  • 压缩方式

    • hive中间结果压缩(map输出的压缩)
    • hive的最终结果压缩(reduce输出的压缩)
  • 压缩算法选择

    • 推荐:snappy
  • 栗子:

    --没有开启压缩
    create table student_no_compress(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',';
    
    insert into table student_no_compress select * from student;
    
    
    --开启压缩
    create table student_compress(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',';
    
    --首先开启map压缩功能
    0: jdbc:hive2://node-1:10000> set hive.exec.compress.intermediate=true;
    No rows affected (0.004 seconds)
    0: jdbc:hive2://node-1:10000> set mapreduce.map.output.compress=true;
    No rows affected (0.004 seconds)
    0: jdbc:hive2://node-1:10000> set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
    
    --然后开启reduce压缩功能
    0: jdbc:hive2://node-1:10000> set hive.exec.compress.output=true;
    No rows affected (0.006 seconds)
    0: jdbc:hive2://node-1:10000> set mapreduce.output.fileoutputformat.compress=true;
    No rows affected (0.005 seconds)
    0: jdbc:hive2://node-1:10000> set mapreduce.output.fileoutputformat.compress.codec =org.apache.hadoop.io.compress.SnappyCodec;
    No rows affected (0.003 seconds)
    0: jdbc:hive2://node-1:10000> set mapreduce.output.fileoutputformat.compress.type=BLOCK;
    
    insert into table student_compress select * from student;
    
  • 注意:snappy压缩的文件 属于二进制格式数据 不可以直接观察 hive在操作的时候可以自解析。


hive的存储格式

  • 语法

    create table 
    
    stored as file-foramat
    
  • 说明:

    • 如果不指定语法 默认hive使用textfile格式存储 普通文本文件 行存储
    • 此外还支持其他的文件存储格式:ORC Parquet格式
    • ORC Parquet格式属于二进制格式的文件 不可以直接观察 hive可以自解析
    • 文件存储格式结合数据压缩 可以带来更加棒棒的体验
  • 文件存储格式对比

    • 存储空间效果

      orc > parquet >textfile
      
  • 注意事项

    • ORC格式文件和PARQUET格式文件都不能通过直接load加载的方式从普通text文件转成。
    • 必须通过insert+select方式 底层通过mr程序把普通文件格式转化成orc等格式。
    • 企业中要想把一批普通文本文件变成orc等二进制格式存储 首先存储成普通文件 然后通过insert+select得到
    • 如果已经是orc等格式文件存储格式 直接load即可

hive 调优

  • fetch抓取

    • 能不使用mr程序处理数据的,尽量不使用。

    • 默认实现:more模式

      hive.fetch.task.conversion=more
      以下三种情况不走mr程序
      
      全表扫描查询
      字段查询
      limit查询
      
  • hive本地执行模式

    • 建议在开发环境中开启
    正常情况下:
    hive sql--->mapreduce--->yarn(分布式执行)--->hdfs结构化数据--->处理结果
    
    本地执行模式:
    hive sql--->mapreduce--->local mode(本地模式 单机执行)--->hdfs结构化数据--->处理结果
    
     hive> SET mapreduce.framework.name=local; 该参数决定了hive中最终的mr程序是什么执行模式
     如果是local 所有的mr程序都走本地 如果yarn 都走yarn.
     
     0.7版本之后:
     SET hive.exec.mode.local.auto=false; 该参数可以自动决定是否切换本地模式。默认不开启
     如果设置为true,会根据下述三个标准进行自动切换
     
     切换标准:
     总共的数据量小于128M
     maptask个数小于4个
     reducetask个数要么为0  要么为1
    
  • join中的map side join

    • 通常认为进行数据的join 应该把相关联的数据发送到同一个reduce 在reduce中完成关联的判断 这种称之为common join(reduce join)

    • 当下hive版本中 默认开启了map端的join 如果可以转化满足map端join的条件 hive将会自动转化

      何谓map 端join?
       首先启动第一个mr程序把小表的文件读取 变成hashtable 做分布式缓存发送
       
       然后启动一个只有mapper阶段的mr程序 通过maptask读取一条记录和上一步的缓存做关联  在map端就完成了join的操作
      
    • 在实际使用中,通过下面这个参数设置小表阈值。

      set hive.mapjoin.smalltable.filesize= 25000000;  设置多大以下为小表
      
  • 大表join大表

    • 如果有空值 空值过滤可以优化查询时间

    • 空值转换

      • 把空值转换成某一个非空字符串

        CASE WHEN a.id IS NULL THEN 'hive' ELSE a.id END = b.id
        
        弊端如果这样的空值过多  会造成reduce数据倾斜
        
      • 把空值转换成若干个随机的非空字符串

        CASE WHEN a.id IS NULL THEN concat('hive', rand()) ELSE a.id END 
        
    • 大小表之间的join

      不管是大join小 还是小join大 当下的hive版本已经自动处理好了 不需要额外的特别设置。

      hive老的版本中  把小表写在前面 提高join的速度
      
  • group by优化

    • 如果数据都发送到reduce进行分组后的操作 容易产生数据倾斜

    • 记住如果数据本身不平衡 可能会导致数据倾斜 请开启下面的选项

      有数据倾斜的时候进行负载均衡(默认是 false)
      set hive.groupby.skewindata = true;
      
  • maptask个数调整

    • 小文件场景(想法进行合并)

      • 上传hdfs之前进行本地合并 Java IO—>block size
      • 上传中间进行合并 appendToFile
      • 上传之后使用hadoop archive小文件归档
    • 大文件场景(想法进行拆分)

      • 在设置hdfs存储block size的时候进行改变

      • 使用distribute by把原来表的数据随机分散成若干个部分 set mapreduce.job.reduces =10;

        然后在针对数据进行处理 就可以增加maptask个数

        create table a_1 as
        select * from a
        distribute by rand(123);
        
  • reducetask个数调整

    • set mapreduce.job.reduces = -1 默认hive自己会根据任务情况进行决定

    • 当然用户可以手动指定个数 不一定生效 hive会保证某些逻辑能够正常执行

      order by  全局排序 意味着只能有一个reducetask   hive为了满足能够正常执行 自己决定
      
  • hive的并行执行机制

    • hive中sql会最终编译成若干个不同的阶段stage执行 如果当中某些阶段没有依赖 可以尝试开始并行执行

    • 默认是没有开启的 需要开启该机制 并且指定最大可以通过并行执行的个数

      set hive.exec.parallel=true; //打开任务并行执行
      set hive.exec.parallel.thread.number=16; //同一个 sql 允许最
      大并行度,默认为 8
      
    • 注意:并行执行意味着短时间内资源的大量消耗 通常在集群空闲时期开启

  • 严格模式

    • 默认情况下 hive执行的是非严格模式

    • 可以通过下面的参数开启严格模式

      set hive.mapred.mode = strict;
      
    • 如果是严格模式,以下三种操作被禁止

      • 分区表查询必须指定where分区条件 禁止全表扫描
      • order by查询必须跟limit语法 限制返回的条数
      • 禁止笛卡尔积查询
  • jvm重用机制

    • 默认情况下在mr中,不管是maptask还是reducetask 本质都是jvm进程
    • 默认一个jvm运行一个task 运行完毕 释放资源 销毁jvm
    • 如果开启重用机制 就可以在本次job中多次重复使用该同一个jvm 避免资源频繁的申请销毁
    • 对其他job来说 就会形成一直霸占资源的场景
  • mr推测执行机制

    • 默认maptask reducetask都是开启的
    • 找出拖后腿的task 为其启动备份task 两个同时处理同一份数据。谁先执行完,谁的结果最为最终结果。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值