HIVE 新特性 ACID 初试

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: <div class="markdown_views"><p>在 Hive 0.14 之前,Hive QL 一直不支持insert、update、delete 操作,这显然很不方便,尤其是在构建数据仓库的过程中,一个比较常见的例子是<code>维度表</code>经常需要更新某列,在 Hive 中需要更新历史所有数据,这显然是不合理的。</p><p>在 Hive 0.14

在 Hive 0.14 之前,Hive QL 一直不支持insert、update、delete 操作,这显然很不方便,尤其是在构建数据仓库的过程中,一个比较常见的例子是维度表经常需要更新某列,在 Hive 中需要更新历史所有数据,这显然是不合理的。

在 Hive 0.14 版本,支持了行级别的 ACID 与 Transactions,这也就解决了上面的问题。

本文主要讲解如何在 Hive 0.14 配置,使得支持上述两个特性,相关原理及性能分析后面再单独写一篇文章来分析。

相关软件说明:

  • Hive 1.1.0
  • mysql 5.6(存储 metastore )

1. 初始化数据库

mysql> create database metastore_db;
mysql> USE metastore_db;  
mysql> SOURCE $HIVE_HOME/scripts/metastore/upgrade/mysql/hive-schema-1.1.0.mysql.sql
mysql> SOURCE $HIVE_HOME/scripts/metastore/upgrade/mysql/hive-txn-schema-0.13.0.mysql.sql
mysql> CREATE USER 'hive'@'localhost' IDENTIFIED BY 'mypassword';  
mysql> grant all privileges on metastore_db.* to hive@'%' identified by 'hive';
mysql> FLUSH PRIVILEGES;  
mysql> quit;  

这里需要注意的是,必须source txn相关的表,否则后面创建表是会报下面几种错误:

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:javax.jdo.JDODataStoreException: Schema Transaction threw exception "Add classes to Catalog "metastore_db", Schema """
    at org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:451)
    at org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:732)
    at org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:752)
    at org.apache.hadoop.hive.metastore.ObjectStore.createTable(ObjectStore.java:794)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.hadoop.hive.metastore.RawStoreProxy.invoke(RawStoreProxy.java:98)
    at com.sun.proxy.$Proxy6.createTable(Unknown Source)
    at org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.create_table_core(HiveMetaStore.java:1393)
    at org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.create_table_with_environment_context(HiveMetaStore.java:1426)

2. 配置 hive-site.xml

<property>
    <name>hive.support.concurrency</name>
    <value>true</value>
</property>
<property>
    <name>hive.txn.manager</name>
    <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
</property>
<property>
    <name>hive.enforce.bucketing</name>
    <value>true</value>
</property>
<property>
    <name>hive.compactor.initiator.on</name>
    <value>true</value>
</property>
<property>
    <name>hive.compactor.worker.threads</name>
    <value>2</value>
</property>
<property>
    <name>hive.exec.dynamic.partition.mode</name>
    <value>nonstrict</value>
</property>
<property>
    <name>hive.compactor.initiator.on</name>
    <value>true</value>
</property>

<!-- mysql 相关 -->
<property>  
   <name>javax.jdo.option.ConnectionURL</name>  
   <value>jdbc:mysql://localhost:3306/metastore?createDatabaseIfNotExist=true</value>  
    <description>Enter your JDBC connection string. </description>  
</property>  
<property>  
    <name>javax.jdo.option.ConnectionDriverName</name>  
    <value>com.mysql.jdbc.Driver</value>  
</property>  
<property>  
    <name>javax.jdo.option.ConnectionUserName</name>  
    <value>hive</value>
</property>  
<property>  
    <name>javax.jdo.option.ConnectionPassword</name>  
    <value>hive</value>  
</property>  
<property>  
    <name>datanucleus.autoCreateSchema</name>  
    <value>false</value>  
</property>  
<property>  
    <name>datanucleus.fixedDatastore</name>  
    <value>true</value>  
</property>

3. 创建具备ACID及Transactions的表

这里的表需要具备下面几个条件:
1. 必须以 ORC 格式存储
2. 必须分 bucket,且不能 sort
3. 必须显式声明transations

大致如下面模版所述:

create table T(...) 
clustered by (a) into 2 buckets
stored as orc TBLPROPERTIES ('transactional'='true');

知道了限定条件,我们来创建一个表做个测试:

create table goods_info (
    shop_id int,
    created_time string,
    title string
)
clustered by (shop_id) into 3 buckets
stored as orc TBLPROPERTIES ('transactional'='true');

之后insert两条数据

insert into table goods_info values (1, '2016-04-02 21:00:00', 'HIVE 7天入门'), (2, '2016-04-02 21:01:00', 'SICP');

回车后,会运行一个MR去插入数据,之后就可以查询了

hive (default)> select * from goods_info;
OK
1   2016-04-02 21:00:00 HIVE 7)e�
2   2016-04-02 21:01:00 SICP
Time taken: 0.116 seconds, Fetched: 2 row(s)

这里的中文貌似有乱码问题,这里先不做处理了。
在 hdfs 上生产的文件为:

210  /user/hive/warehouse/goods_info/delta_0000005_0000005/bucket_00000
810  /user/hive/warehouse/goods_info/delta_0000005_0000005/bucket_00001
781  /user/hive/warehouse/goods_info/delta_0000005_0000005/bucket_00002

在创建表时,我遇到了下面的问题

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:javax.jdo.JDODataStoreException: An exception was thrown while adding/validating class(es) : Specified key was too long; max key length is 767 bytes
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Specified key was too long; max key length is 767 bytes
    at sun.reflect.GeneratedConstructorAccessor31.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.Util.getInstance(Util.java:360)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:978)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2526)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2484)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:848)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:742)
    at com.jolbox.bonecp.StatementHandle.execute(StatementHandle.java:254)

这时由于 mysql 自身对索引字段字符长度的限制,我数据库用的是utf8编码,767/3=255.6,这也就是说索引字段的varchar不能大于255,对于 mysql5.6以及以后的版本,可以通过在/my/etc.conf中添加如下配置解决

[mysqld]
innodb_file_format=BARRACUDA
innodb_large_prefix=on
innodb_file_per_table=true

相关原理可见:

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
SQL 存储 资源调度
Hive3新特性 2
Hive3新特性
228 0
Hive3新特性 2
|
SQL 存储 关系型数据库
为什么不能使用 datax 直接读写 hive acid 事务表?
为什么不能使用 datax 直接读写 hive acid 事务表?
|
SQL 分布式计算 Hadoop
Hive3新特性 1
Hive3新特性
244 0
|
SQL 存储 缓存
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (1)
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (1)
209 0
|
SQL 存储 分布式计算
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (2)
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (2)
151 0
|
SQL 分布式计算 Java
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (3)
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (3)
164 0
|
SQL HIVE
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (4)
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (4)
142 0
|
SQL 分布式计算 Hadoop
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (5)
《CDP企业数据云平台从入门到实践》——Hive3 新特性 (5)
133 0
|
SQL 存储 缓存
【阿里云 CDP 公开课】 第九讲:Hive3 新特性
本文整理自 Cloudera 生态资深解决方案工程师王雪峰在 阿里云CDP公开课 上的分享。
【阿里云 CDP 公开课】 第九讲:Hive3 新特性
|
SQL 存储 缓存
CDP中的Hive3系列之Apache Hive3的特性
CDP中采用的是Apache Hive3版本,该版本相比Hive1/2在事务和安全性等方面有重大改进,了解这些版本之间的主要差异对于 SQL 用户至关重要,包括使用 Apache Spark 和 Apache Impala 的用户。
1022 0