Hive表数据量统计原理和源码分析

本文深入探讨了Hive如何统计执行计划中的数据量和行数。在优化阶段,Hive通过Statistics规则收集表的统计信息,包括从Hive metastore获取rawdatasize或totaldatasize,或者直接统计HDFS文件大小。对于行数统计,若无法直接获取,则采用估算方式,根据列的类型和容量估算每行的数据大小。整个过程兼顾效率和容错性,确保统计的准确性。
摘要由CSDN通过智能技术生成

在Hive explain获得执行计划时,经常会看到如下图所示的表数据量统计:

那么这个数据量,Hive是如何统计出来的呢?

一、Data size统计

1.1、Hive源码

在Hive通过Antlr语法解析器获取到SQL的抽象语法树(AST)并生成校验过元数据的逻辑执行计划后,在优化阶段会使用Statistics统计的规则(rule),如下图所示:

AnnotateWithStatistics这个类中,在对执行计划进行转化(transform)时会调用TableScanStatsRule这个规则,如下图所示:

在TableScanStatsRule匹配规则中,在拿到裁剪后涉及的分区范围(PrunedPartitionList)后,会调用collectStatistics()方法开始正式统计表Statistics信息,如下图所示:

获取到select语句等涉及的列信息后,调用同名的重载方法,如下图所示:

在最终重载的collectStatistics()方法中,会调用getDataSize()方法来统计数据量(当然也有统计行数的函数调用),如下图所示:

可以看到统计数据量的逻辑是先从Hive metastore(存在MySQL中)的parameters信息中拿到raw data size,如果没拿到就还是从metastore中拿total data size信息,再没拿到就直接去统计HDFS目录文件的大小,并且乘以反序列化因子(因为表文件可能被压缩编码和序列化过,实际容量大小比原来小)。

1.2、Hadoop源码

那么Hive是如何去HDFS统计表目录下的文件大小的呢?在getDataSize()函数中,会调用Hadoop HDFS上的方法,如下图所示:

去Hadoop源码看看,可以看到如果是文件就会直接计算文件长度,如果是目录就递归统计,如下图所示:

那么这个length是如何计算出来的?getLen()函数会用到一个length变量,这个变量最终是在这里被设置的:

这样最后就到JDK层面了,会返回字节大小,如下图所示:

二、Num rows统计

上面Hive的collectStatistics()函数中,调用了getNumRows()统计表的行数,可以看到如果没能从Hive metastore中拿到行数信息,那么就采用估算的方式,如下图所示:

estimateRowSizeFromSchema()函数中,Hive在拿到表的每一列的信息后,会判断该列的字段类型,从而累加该类型的一个字段值所代表的不同容量大小,分为string、varchar、struct、map等可变长类型和int、double、boolean等固定长度类型两种情况,如下图所示:

累加好表的所有列的一个字段值的容量大小,即估算的一行容量大小后,回到一开始的getNumRows()函数,会把统计的表容量大小除以估算的一行数据的容量大小,最终得到估算的行数,如下图所示:

如果这样都没拿到行数统计(比如之前没拿到表容量等),就返回行数是一行。可以看到Hive的统计方法是有较严谨的响应速度(优先从metastore拿)和容错(万一统计不出来)考虑的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值