二.Hive问题排查及调优思路

1.使用explain查看HiveSQL的执行计划

2.学习大数据分布式计算的基本原理

其实不仅仅是MapReduce在数据处理时将所有的数据简化成业务无关的键-值对模式,大部分的大数据数计算引擎在底层实现上也是如此,如Spark、Tez和Storm。在进行数据处理时先将计算发往数据所在的节点,将数据以键-值对作为输入,在本地处理后再以键-值对的形式发往远端的节点,这个过程通用叫法为Shuffle,远端的节点将接收的数据组织成键-值对的形式作为输入,处理后的数据,最终也以键-值对的形式输出。

3.学习使用YARN提供的日志

想要知道HiveSQL所有阶段的运行信息,可以查看日志。查看日志的链接,可以在每个作业执行后,在控制台打印的信息中找到。

4.干预SQL的运行方式

  • 4.1.通过改写SQL实现对计算引擎执行过程的干预
  • 4.2. 通过SQL-Hint语法实现对计算引擎执行过程的干预
  • 4.3.通过数据库开放的一些配置开关,来实现对计算引擎的干预

5.调优须知:

调优讲究适时调优,过早进行调优有可能做的是无用功甚至产生负效应,在调优上投入的工作成本和回报不成正比。调优需要遵循一定的原则。

6.代码优化原则:

  • 理透需求原则,这是优化的根本;
  • 把握数据全链路原则,这是优化的脉络;
  • 坚持代码的简洁原则,这让优化更加简单;
  • 没有瓶颈时谈论优化,是自寻烦恼。

7.Hive程序相关规范

一份拥有良好代码风格的程序,有助于开发者发现性能问题,缩短调优的时间,降低维护成本,同时也能促进程序员的自我提高。
规范分为3类:开发规范、设计规范和命名规范。

7.1.开发规范

  • 单条SQL长度不宜超过一屏。 ·SQL子查询嵌套不宜超过3层。

  • 少用或者不用Hint,特别是在Hive
    2.0后,增强HiveSQL对于成本调优(CBO)的支持,在业务环境变化时可能会导致Hive无法选用最优的执行计划。

  • 避免SQL代码的复制、粘贴。如果有多处逻辑一致的代码,可以将执行结果存储到临时表中。

  • 尽可能使用SQL自带的高级命令做操作。例如,在多维统计分析中使用cube、grouping
    set和rollup等命令去替代多个SQL子句的union all。

  • 使用set命令,进行配置属性的更改,要有注释。

  • 代码里面不允许包含对表/分区/列的DDL语句,除了新增和删除分区。

  • HiveSQL更加适合处理多条数据组合的数据集,不适合处理单条数据,且单条数据之间存在顺序依赖等逻辑关系。例如,有A、B、C 3行数据,当A符合某种条件才能处理B行时,只有A、B符合某种条件,才能处理C行。

  • 保持一个查询语句所处理的表类型单一。例如,一个SQL语句中的表都是ORC类型的表,或者都是Parquet表。

  • 关注NULL值的数据处理。

  • SQL表连接的条件列和查询的过滤列最好要有分区列和分桶列。

  • 存在多层嵌套,内层嵌套表的过滤条件不要写到外层,例如:

select a.* from a
left join b
on a.id=b.id
where a.no=1

应当写为:

select a.* from (
select * from a where a.no=1
) a left join b
on a.id=b.id

7.2.设计规范

  • 表结构要有注释。

  • 列等属性字段需要有注释。

  • 尽量不要使用索引。在传统关系型数据库中,通过索引可以快速获取 少部分数据,这个阀值一般是10%以内。但在Hive的运用场景中,经常需要批量处理大量数据,且Hive索引在表和分区有数据更新时不会自动维护,需要手动触发,使用不便。如果查询的字段不在索引中,则会导致整个作业效率更加低下。索引在Hive 3.0后被废弃,使用物化视图或者数据存储采用 ORC格式可以替代索引的功能。

  • 创建内部表(托管表)不允许指定数据存储路径,一般由集群的管理 人员统一规划一个目录并固化在配置中,使用人员只需要使用默认的路径即 可。创建非接口表,只允许使用Orc或者Parquet,同一个库内只运行使用一
    种数据存储格式。接口表指代与其他系统进行交互的数据表,例如从其他系
    统导入Hive时暂时存储的表,或者数据计算完成后提供给其他系统使用的输
    出表。

  • Hive适合处理宽边(列数多的表),适当的冗余有助于Hive的处理性 能。

  • 表的文件块大小要与HDFS的数据块大小大致相等。

  • 分区表分桶表的使用。

7.3.命名规范

库/表/字段命名要自成一套体系:

  • ·表以tb_开头。
  • ·临时表以tmp_开头。
  • ·视图以v_开头。
  • ·自定义函数以udf_卡头。
  • ·原始数据所在的库以db_org_开头,明细数据所在库以db_detail_开头,数据仓库以db_dw_开头。

3 总结调优的一般性过程
首先,要明白所有的优化是相对的,例如程序运行需要2个小时,看似
很慢,但如果需求的目标是3个小时,即可正常作业,无特别情况,可以不
进行优化。
优化的基本流程如下:

  • 第一,选择性能评估项及各自目标,常见的评估性能指标有程序的时延和吞吐量;
  • 第二,如果系统是由多个组件和服务构成,需要分组件和服务定义性能目标;
  • 第三,明确当前环境下各个组件的性能;
  • 第四,分析定位性能瓶颈;
  • 第五,优化产生性能瓶颈的程序或者系统;
  • 第六,性能监控和告警。
  • 上面的流程是优化的基本流程,前面三点可以结合各自的实际应用场
    景,结合运维意见及业务的要求自行设定,本书焦点在后面三点。

分析定位性能瓶颈:在Hive中最常见的是磁盘和网络I/O的瓶颈,其次是内存会成为一个性能瓶颈。CPU一般比I/O资源相对富余。为什么是前面三点最有可能出现瓶颈?要解释这个问题,需要了解Hive执行计划,以及计算引擎的基本原理,并借助作业监控工具优化产生性能瓶颈的程序或者系统。

在Hive中,优化方式可以归结为3点,即优化存储、优化执行过程和优化作业的调度。·性能监控和告警:建立性能监控和告警,在操作系统和硬件层面可以借助Linux或UNIX系统提供的系统工具,也可以借助一些开源的工具,例如Zabbix和Ganglia;可以记录服务器运行时的历史过程,也可以定制化监控很多细粒度指标。软件层面,大数据组件可以借助cloudera或者Ambari监控工具,或者借助开源工具Prometheus和Grafana定制监控大数据组件。作业层面借助YARN Timeline提供的查看作业信息的服务信息进行监控。虽然本书的焦点在后面三点,但需要强调一点,对当前服务或者组件所在的环境有一个良好的认知,对业务有一定的理解是优化的前提。
为了强调这一点,我们引入下面的说明。
有这样一个案例,在同步数据的讨论会议上,业务方说有些数据库表每日都有数据更新,怎么同步更新的数据?程序员A认为目前数据日志解析工具可以捕捉数据更新。程序员B认为还有一个比较简单的方法,可以用支持事务机制的表,只是这些表使用起来有特殊限制,需要升级系统环境。资历较老的程序员会问到每日更新的数据有多少,表数据总共有多少,这些数据从开始同步到最后的数据使用,可以支持多久的等待时间。业务方说数据每日更新增量1万以内,最大的表数据量不超过10万,整体数据量不到100MB,这些数据从同步到使用允许24小时的等待时间。程序员C认为简单数据量总量不多,可以全量同步,不会对现有的系统造成太大的压力,也 不会对同步作业造成多大压力,如果不需要历史数据,可以每日覆盖对应的表,如果需要历史数据,就采用表分区的方式,按日分区,每个分区同步当日所有的数据。比较3个程序员的方案,程序员A需要引入更多的同步组件,且解析工具的部署维护是一个问题,在数据库的日志格式变更后,同步又是一个问题,并且耗时长,后期维护难度较高。程序员B需要对生产环境的软件进行升级,需要评估软件是否对现有生产环境有影响,稳定情况如何。而程序员C解了业务的整体情况后,采用的就是一般的方式——全量同步。在业务要求范围内也能快速完成业务需求。很显然,程序员C的方案对程序员A和程序员B的方案来说都是一个极大的优化,而且从源头尽可能地掐断了因一个小需求引入众多操作所带来的性能问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值