Hive进阶

原创
2017/04/28 17:13
阅读数 62

Hive表模式设计

理想的分区方案不应该导致产生太多的分区和文件夹目录,而且每个分区下包含文件大小分布均匀。对Hive表进行join操作时,需要考虑连接键值是否是表的唯一键。在按天调度的任务中,中间表尽可能采用按天分区的方案。分区表分桶的优点:因为桶的数量是固定的,所以它没有数据波动;如果两个表都是按照user_id分桶,那么两个表可以执行高效的map-side JOIN。

Hive提供了SerDe[序列化和反序列化]抽象,用于从输入中提取数据、输出数据。通过指定的分隔符将行分解成列,SerDe通常是非常宽松的,如果某行的字段个数比预期的要少,那么缺少的字段将返回null;如果要多,那么多出来的字段将被省略。添加新字段只需要一条alter table add column命令。如果有足够多的行,且具有重复数据的列较多、或者查询通常只会使用到一个字段或者很少的一组字段,使用列式存储[RCFile]会使分析表数据执行的更快。Hive可以无缝地使用很多压缩格式,唯一可信的不使用压缩的理由是产生的数据用于外部系统或者非压缩格式是最兼容的。压缩可以降低I/O提高查询执行速度,但是压缩和解压都会消耗CPU资源,而通常MR任务都是I/O密集型。不过对于CPU密集型任务场景,例如一些机器学习算法,压缩实际上可能会占用宝贵的CPU资源,从而降低性能。

Hive性能调优

Hive调优可能涉及到调整配置参数的值,或者启用/禁用某些特定的特性。使用explain和explain extended分析Hive如何将查询转化成MR任务。limit语句在很多情况下还是需要执行整个查询语句,可以通过设置 hive.limit.optimize.enable=true,开启对数据源进行抽样。Map side JOIN优化中需要清楚哪个表是最大的,并将最大的表放置在JOIN语句的最右边,或者直接使用streamable(table_name)语句指出。如果有一个表足够小,是可以载入内存中的,那么这时HIve可以执行一个map-side JOIN,减少reduce过程。有时候即使某些表不适合载入内存也可以使用mapJOIN,因为减少reduce阶段可能比将不太大的表分发到每个map task中会带来更多的好处。

通过hive.mapred.mode=strict设置Hive进入严格模式,禁止以下3种类型的查询:对于分区表必须在where语句中指定分区字段过滤条件;使用了order by语句的查询必须结合使用limit语句,因为order by执行全局排序时会将所有的结果数据分发到同一个reducer中处理;限制笛卡尔积查询。

Hive按照输入数据量的大小来确定reducer个数,属性hive.exec.reducers.bytes.per.reducer默认值是1GB。默认值通常情况下是比较合适的,但是有些情况下查询的map阶段会产生比实际输入数据量要多得多的数据,这时如果根据map阶段输入数据量来确定reducer个数就显得比较少;同理map阶段也有可能会过滤掉数据集中很大一部分数据这时少量reducer就满足计算需求。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部