hive值乘以0.01保留一位小数_Hive 0.13到Hive 2.1跨版本升级全姿势与避坑指南

原标题:Hive 0.13到Hive 2.1跨版本升级全姿势与避坑指南

Hive是业界大数据平台使用最广泛的SQL引擎,提供了一层SQL抽象接口和一套元数据规范, 将SQL查询翻译为分布式的计算作业,支持MapReduce/Spark/Tez等多种计算引擎。同时Hive定义的元数据标准已经成为了一种事实标准,业界流行的大数据SQL引擎均对Hive元数据进行了兼容和支持。

前一段时间我们团队对Hive进行了一次从0.13版本到2.1版本的跨版本升级,升级期间遇到了一些问题, 但基本做到了可灰度、可控制和升级期间稳定性保证,同时服务不停这个属性通过我们的分析和实践也可以达到。本文详细介绍一下我们在升级过程前后遇到的一些问题和解决思路,以供大家参考。

平台使用背景

深度使用Hive的各项服务。

生产环境每天SQL查询总量80000+,包含 各种正常的和奇葩的SQL语法和元数据存储。

同时使用Spark和Hive进行ETL,使用Presto、Kylin和Spark进行Adhoc查询加速。

下面从元数据、语法兼容性、Hive2.1新功能、UDF兼容性、Hive2.1的一些不足等几个方面, 来讨论下升级注意事项和升级期间踩过的一些坑。

一、元数据

Hive元数据是Hadoop平台的核心数据,如果只是使用Hive提供的Hive Schema Tools来进行元数据Schema升级的话,整个升级过程是黑盒,并不利于精确控制,在深度使用场景下还有可能爆各种奇葩错误。

例如:如果你同时在用Spark,那么元数据VERSION表中的版本可能被修改为1.2.1(实际版本是0.13),如果使用HiveSchemaMetaTools时候参数不注意设定,这货是会从1.2.1版本开始执行升级脚本,最后会一部分升级脚本成功,一部分失败,然后结果你懂得。

所以首先需要对Hive元数据从0.13到2.1的Schema升级脚本进行详细分析,再确定具体升级方式。

0.13到2.1的元数据Schema升级脚本,位于${HIVE_HOME}/metastore/s/upgrade/${DB_TYPE}/文件夹内,一共17个子升级脚本和对应的issue。

通过查看每一个脚本明细SQL、对应的issue信息以及适用场景,可以将Schema升级脚本分为以下几类:

1、建议升级:hive-13076(涉及到建表和修改表操作)

从代码分析上看不影响Hive正常操作,但是修改内容涉及到建表和修改表操作。另外,这个脚本的升级内容是一个建表操作,不涉及到修改数据库表操作,所以风险较小,建议在灰度2.1客户端之前先进行升级操作。

这个升级目的是让Hive支持表级别主键和外键,从而可以在CBO时候优化join的执行计划。目前社区完成了主键和外键的语法支持和存储,而CBO使用主键和外键功能还处理未开发状态。

Hive 2.1支持的新语法:

2、事务(Hive Transaction)相关修改(不启用Hive事务则不需要升级)

默认事务是不启用的,当通过配置启用Hive事务时候使用到。Hive事务的应用场景比较有限。

5. hive-12807

6. hive-12814

7. hive-12816

8. hive-12818

9. hive-12819

10. hive-12821

11. hive-12822

12. hive-12823

13. hive-12831

14. hive-12832

16. hive-13395

17. hive-13354

3、Hcatalog相关修改(不使用Hcatalog则不需要升级)

增加NOTIFICATION_LOG和NOTIFICATION_SEQUENCE表。支持hcatalog metastore notification机制。

2. hive-9296

4、其它非关键修改(一些特殊场景使用到)

1. hive-7784: 给`PART_COL_STATS`表增加索引,加快CBO查表速度。

3. hive-7018: 删除`TBLS`和`PARTITIONS`表在0.10后不用的`LINK_TARGET_ID`列。 0.13版本schema本身就不含有这个列。Oracle可能会遇到这个问题。不建议执行,因为这个操作危险性比较大。

4. hive-11970: 增加`COLUMNS_V2`等表的`COLUMN_NAME`列名长度到767,防止某些特殊情况例如Avro导出表情况下列名超过128个字符。一般情况遇不到。

5、总结

通过上述分类分析可知,0.13到2.1版本的元数据基本完全兼容,根据公司具体场景进行部分升级即可。

例如,如果不使用以上提到的Hive事务、Hcatalog、Avro导出等特殊功能,完全可以做到只升级Hive相关程序不升级元数据也没有使用问题。 但需要做以下前提工作:

关闭元数据VERISON校验相关功能

设置hive.metastore.schema.verification=false。必要时候修改代码,禁用Hive自身的Check机制。

配置禁止JDO框架来自动更新元数据schema

设置datanucleus.fixedDatastore=true和datanucleus.autoCreateSchema=false。

二、语法兼容性

Hive版本升级后,给人的感觉是语法要求越来越严格,越来越接近于ANSI SQL标准,所以很多在0.13可以跑成功的SQL,到了2.1会报错。 下面总结升级过程中遇到的一些语法兼容性问题。

1、Hive新增保留字问题

Hive随着版本变迁,保留字越来越多。 保留字的详细情况可以参考:Hive各个版本的保留字。

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-Keywords,Non-reservedKeywordsandReservedKeywords

保留字问题有以下两种:

新增预留字

新的版本Hive会预留更多保留字,如果SQL用到产生语法问题,可以通过参数设置set hive.support.sql11.reserved.keywords=false来取消保留字校验, 达到不需要修改SQL,又能保证线上SQL稳定运行的兼容效果。

新增关键字

当SQL中含有Hive2.1中新增的关键字时候,只能修改SQL进行兼容了,需要将与关键字冲突的属性名用反引号包围。 新版本增加的关键字有:OFFSET、SUBQUERY、REWRITE、PRIMARY、FOREIGN、KEY、 REFERENCES、CONSTRAINT等。

2、其它兼容性问题和解决方法

(1)hive.开头的参数如果不在Hive2.1预定义配置中(可能已经被移除),或者大小写不对,set语句会直接报错。

例如:set hive.auto.convert.JOIN=true,大小写不对,执行会报错。解决方法:规范化语句,或者关闭强制校验参数。

(2)建表时不指定列的具体类型,在2.1会直接报错。

例如:

create table test_table_null_no_type as select null as id, "zhangsan" as name;

解决方法:规范化SQL,指定具体的列类型。

(3)通过函数等运算产生的列,没有指定明确的别名,在2.1会偶尔报错。

例如:

select id, `_c1` from (select id, get_json_object(deliver_geojson,'$.features') from tb) a

解决方法:规范化SQL,指定有业务含义的别名,不以下划线开头。

(4)在使用windows函数时,当列名在多个表都存在时,不指定列所属表,在2.1会报错。

例如:

select row_number() over(partition by user_id order by a.log_time desc) rank from a join b on a.id = b.id;

其中user_id在a表和b表中均存在。

解决方法:规范化SQL,指定列所属表名。

(5)在使用union all时,union起来的多个查询,含有orderBy、clusterBy、distributeBy sortBy、limit语法在2.1会报错。

例如:

select 1 from default.dual limit 1 union all select 2 from default.dual limit 1;

解决方法:只允许在最后一个语句中含有orderBy、clusterBy、distributeBy sortBy、limit语句。

(6)使用windows函数时,窗口的上限和下限必须大于0,否则在2.1会报错。

--错误信息:SemanticException Window Frame Boundary Amount must be a positive integer, provided amount is: 0 select order_date ,order_date_new ,restaurant_id ,phone_1 ,count(phone_1) over(PARTITION BY restaurant_id,phone_1 order by days range between 0 preceding and 30 following) buy_num Hive Schema Tools from tb01;

解决方法:规范化SQL,避免窗口函数上限和下限为0,例如将0 preceding修改为current row。

(7)case when语法中的数据类型不一致,在2.1会报错

解决方法:将case when里类型转换为一致。

3、构建大数据SQL预上线测试环境

语法兼容性问题,可以提前拿到线上一段时间的SQL语句,启动一个2.1版本的HiveServer2, 通过批量Explain去校验是否存在语法兼容性问题,从而把所有问题解决到事前。

我们这边的做法是构建一个通用的大数据SQL测试环境,具体做法是:

数据集和Workload

通过客户端自定义的Hook和重放MapReduceLog/SparkEventlog等方法,拿到生产环境所有的SQL语句。

数据集合使用线上数据,事实一再证明,生产数据+生产SQL才能完全表征一个生产环境。

将数据输出关键字(Create Table/Insert into)统一修改为指向测试库表。按需提取所需要的SQL,例如全集、按照特征提取采样、Adhoc、生产ETL等维度来提取。

一键化测试

可以对比性能、数据质量、执行计划和错误分类等。融合成一个Hive/Spark/Presto新功能上线前的回归测试工具来使用。

三、Hive2.1新feature

1、ORC&Parquet文件格式

0.13对于2.1产生的ORC文件,存在读取兼容性问题。另外hive2.xx之前,ORCInputformat存在一个UGI错误的bug比较严重,在HiveServer2里会遇到, 原因是ORCReader使用了多线程加载ORC文件的footer,而UGI的继承是不能跨线程的。

另外hive2.xx之前,Parquet也存在诸多的bug,可以参考社区相关的issue。

在文件格式的选择上,目前可参考的范例有:

Uber: Parquert + snappy

Linkedin: ORC + zlib

Didi: ORC + zlib

GrowingIO: ORC + zlib

我们倾向于主要文件格式选择ORC,因为ORC和Parquet测试下来速度差不多。 但Spark对于Parquet的一些加速特性需要DataSource API,因为不支持混合文件格式表而被我们关闭。而Hive/Presto对于ORC的支持更友好,例如读取速度、向量化、快速合并和统计信息优化等。

至于压缩算法的选择,我们倾向于对不同场景选择不同的压缩算法, 例如对数仓的ODS层,数据量很大、使用频率很低,考虑使用zlib压缩算法,达到最高压缩比。而DM层数据,数据量相对小但访问频率高,则考虑使用snappy压缩算法,在压缩比和解压缩速度之间取得一个tradeoff。

目前文件格式和压缩算法的选择正在逐步推广上线阶段。 我们的推广方法是改表格式+生命周期,使得数据从之前的格式逐渐滚动到ORC格式。

2、CBO

目前我们还在测试阶段。原因是CBO会在某一些生产SQL语句解析时候报错Assert Error。 另外CBO的适用场景主要在于Join顺序的选择上,这个还需要在自己的线上场景上进行测试一番。

3、向量化执行

Hive的向量化执行目前只支持ORC文件格式,Parquet支持正在开发。在和文件格式推广同步测试和推广阶段。

4、Hive On Spark/Tez

On Spark目前看来社区还不成熟,目前发现只有Uber等在维护和使用。Tez目前更加冷清,之前用过一些效果还是很不错的,但一直没有火起来。

我们的方法是逐渐推广SparkSQL加速部分的ETL语句和Adhoc查询,并计划作为未来的主执行引擎,目前我们已经把SparkSQL 对原来HiveSQL的语法兼容性和运行成功率做到92%+,这样让我们的线上ETL SQL可以更加平滑低成本进行迁移。

我们在Spark上进行的一些工作后续会有专门文章进行详细介绍。

5、其他

Hive2.1提供了大量的bug修复。除了上面提到的还有:

HiveServer2的Heap和PermGen内存泄露问题。

大量存储类型bug修复。参考社区的相关的issue list。

四、UDF兼容性

trim函数在2.1不支持string之外的类型

0.13支持,但是2.1不支持,想要兼容的拷贝0.13代码就可以解决。

date_add和date_sub函数2.1和0.13返回的类型不一致

2.1之前返回String类型,2.1之后返回date类型。如果where语句中有data_add函数与String比较,可能导致数据查询不出来。

想要兼容的话,可以回滚到0.13版本的date_add和date_sub代码。具体请参考HiveUDF Date Functions。

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-DateFunctions

五、Hive2.1存在的一些问题

1、Hive Schema Version问题

如果元数据与Hive版本不同步升级,或用到Spark,因为Spark依赖的Hive默认是1.2.1,所以元数据也中的VERSION表, 会被改来改去,导致各种报错。

例如:MetaException(message:Hive Schema version 2.1.0 does not match metastore's schema version 1.2.0 Metastore is not upgraded or corrupt)

一种方法是设置hive.metastore.schema.verification=false。还有一种彻底的方法是把Hive启动时候检查Schema的功能屏蔽掉。

2、Metastore Server内存泄露问题

BoneCP+DirectSql开启时,Metastore Server内存泄露问题, 参考HIVE-15551,这个issue在2.2才完全解决,在Metastore Server端长期运行可能遇到,可以提前打patch来解决。

3、HiveServer2的多用户模拟问题

2.1后的HS2模拟多用户代码里,UGI的impersonation方式从CreateRemoteUser变为CreateProxyUser。

好处是服务端可以获取到代理用户和被代理用户的信息,缺点是这种机制需要在Namenode端为每个被代理用户进行配置。 具体请参考:Hadoop Impersonation 。

https://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/Superusers.html。

如果不想这么麻烦,可以从CreateProxyUser方式回滚到CreateRemoteUser的方式,具体实现可以参考Hive1.2.1相关代码实现。

4、HiveServer2的operationlog不打印到客户端问题

参考HIVE-14183,设置hive.async.log.enabled=false来解决。

https://issues.apache.org/jira/browse/HIVE-14183

5、Hive客户端PermGen OOM的问题

hive-env.sh设置export HADOOP_OPTS="$HADOOP_OPTS -XX:MaxPermSize=128m"解决。

6、HiveServer2的性能问题

hive.driver.parallel.compilation参数默认为false,导致HS2只允许同时一个Query编译, 有操作元数据比较多的查询编译读取元数据会比较慢,全局锁会卡住所有其他查询。 需要设置为false,打开允许多个Query同时编译。

7、基于Database的Stats收集策略被弃用

Hive2.1的Stats收集只能使用基于HDFS的策略,而StatsTask是单线程运行读取HDFS上的统计文件(文件数量等于Mapper数量),因为HDFS抖动导致了很多性能问题。 极端情况下,发现过一个statsTask会执行1个小时之久。

我们正在考虑把Stats Task禁掉,或者切换回基于Database的Stats收集策略。

8、Column Pruning时候导致列顺序错误问题

Column Pruning时导致列顺序错误,造成处理时ArrayIndexOutOfBoundsException。 在一些复杂的SQL里增加limit会发生,参考HIVE-14564来解决。

9、我们Team回馈社区的一些patch

Alter table Cascade时候的NPE问题:HIVE-16877

https://issues.apache.org/jira/browse/HIVE-16877

Drop掉分区后执行insert overwrite报错问题(这个问题比较严重,有可能不报错,但是会引入脏数据):HIVE-17063

https://issues.apache.org/jira/browse/HIVE-17063

非当前库内Alter partition的异常问题:HIVE-17309

https://link.zhihu.com/?target=https%3A//issues.apache.org/jira/browse/HIVE-17309

六、其它一些踩过的坑

1、元数据数据库连接数打满问题

元数据直连数据库方式下,当并发服务量非常巨大时候,MySQL默认连接数是4000,比较容易打满。

解决方法:

(1)直连使用BoneCP连接池方式下,maxConnectionsPerPartition默认值为10,一个客户端会建立20个连接,可以降低为2,并且降低连接池的活跃度。 可以考虑在$HIVE_CONF_DIR下增加一个bonecp-config.xml:

512true

(2)提升数据库连接数最大值,可能会有稳定性风险。

(3)使用Metastore Server,这是比较通用的做法,一个Metastore Server扛10000+个客户端连接,后端400个数据库连接毫无压力。

Metastore Server生产化实践可以参考我们的另一篇文章,请Google搜索《Hive Metastore Server生产化实践》。

七、总结

1、升级流程

总结之前的分析,从0.13升级到2.1版本,升级过程可以达到完全灰度和平滑。

具体的升级流程如下:

元数据schema备份。

提前批量校验线上SQL,解决语法兼容性问题。

元数据只升级hive-13076中的脚本,建立KEY_CONSTRAINTS表和表上的索引。

定制化Hive代码,根据使用场景解决2.1里面存在的UDF和其他的一些问题。

开始灰度升级Hive 2.1客户端,HiveServer2,最后是Metastore Server。

Hive2.1客户端稳定后,根据需要部分或者全量来将元数据schema升级到2.1.1版本。

最后依次升级Hive JDBC连接客户端。(非必需)

2、未来计划

未来对于Hive On MapReduce执行慢的问题,我们计划逐渐把主要SQL引擎切换SparkSQL,Hive只承担兜底和降级的角色。

同时我们计划实现一个统一的大数据平台SQL引擎,在计算引擎层,合并Kylin、Presto、SparkSQL和Hive等几种引擎, 提供一个统一的路由层,发挥各个引擎的最佳性能; 在数据缓存层,结合SQL画像和历史执行情况,缓存中间热表数据,自动建立Kylin Cube。 在数据存储层,引入CarbonData文件格式,做数据层索引加速。 同时由于Hive定义的元数据规范已经成为大数据平台的事实标准,我们会继续沿用这种标准,所以在和社区一起推动CarbonData和Hive元数据的兼容,欢迎关注CarbonData。

目前正在开发阶段,敬请期待后继的介绍文章。

八、附录

1、Hive JDBC客户端和HiveServer2各版本之间兼容性

2、从0.13开始的元数据Schema升级明细和影响分析

github gist

https://link.zhihu.com/?target=https%3A//gist.github.com/ericsahit/9622411305e42bf6735197fdec612794返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hive中,有几种方法可以保留两位小数。一种方法是使用round函数,它可以返回一个DOUBLE类型的近似保留指定的小数位数。例如,使用round函数可以将645342.875645342保留两位小数,结果为645342.88。\[1\]另一种方法是使用cast函数,将列名转换为DECIMAL类型,并指定保留小数位数。例如,使用cast函数可以将列名转换为DECIMAL(10,2)类型,保留两位小数。\[2\]还有一种方法是使用floor函数,它可以将一个数向下取整。但是,这种方法不是保留两位小数的最佳选择,因为它只是将小数部分舍去,而不是四舍五入。\[3\]综上所述,推荐使用cast函数来保留两位小数。 #### 引用[.reference_title] - *1* *3* [hive-sql查询结果保留特点小数位数的方法](https://blog.csdn.net/helloxiaozhe/article/details/103578666)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [hive数据保留小数点两位小数](https://blog.csdn.net/qq_36039236/article/details/118677119)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值