原标题:Hive事务管理避坑指南
1 简介
Hive作为Hadoop家族历史最悠久的组件之一,一直以其优秀的兼容性支持和稳定性而著称,越来越多的企业将业务数据从传统数据库迁移至Hadoop平台,并通过Hive来进行数据分析。但是我们在迁移的过程中难免会碰到如何将传统数据库的功能也迁移到Hadoop的问题,比如说事务。
事务作为传统数据库很重要的一个功能,在Hive中是如何实现的呢?Hive的实现有什么不一样的地方呢?我们将传统数据库的应用迁移到Hive如果有事务相关的场景我们该如何去转换并要注意什么问题呢?
本文会通过很多真实测试案例来比较Hive与传统数据库事务的区别,并在文末给出一些在Hive平台上使用事务相关的功能时的指导和建议。
2 ACID与实现原理
为了方便解释和说明后面的一些问题,这里重提传统数据库事务相关的概念,以下内容来源于网络。
2.1 ACID说明
何为事务?
就是一组单元化操作,这些操作要么都执行,要么都不执行,是一个不可分割的工作单位。
事务(transaction)所应该具有的四个要素:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。这四个基本要素通常称为ACID特性。
原子性(Atomicity):一个事务是一个不可再分割的工作单位,事务中的所有操作要么都发生,要么都不发生。
一致性(Consistency):事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
隔离性(Isolation):多个事务并发访问,事务之间是隔离的,一个事务不影响其它事务运行效果。这指的是在并发环境中,当不同的事务同时操作相同的数据时,每个事务都有各自完整的数据空间。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改后的状态,事务不会查看到中间状态的数据。
事务之间的相应影响,分别为:脏读、不可重复读、幻读、丢失更新。
持久性(Durability):意味着在事务完成以后,该事务锁对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
2.2 ACID的实现原理
事务可以保证ACID原则的操作,那么事务是如何保证这些原则的?解决ACID问题的两大技术点是:
预写日志(Write-ahead logging)保证原子性和持久性
锁(locking)保证隔离性
这里并没有提到一致性,是因为一致性是应用相关的话题,它的定义一个由业务系统来定义,什么样的状态才是一致?而实现一致性的代码通常在业务逻辑的代码中得以体现。
注:锁是指在并发环境中通过读写锁来保证操作的互斥性。根据隔离程度不同,锁的运用也不同。
3 测试环境
4 Hive的ACID测试
4.1 Hive中的锁(不开启事务)
Hive中定义了两种锁的模式:共享锁(S)和排它锁(X),顾名思义,多个共享锁(S)可以同时获取,但是排它锁(X)会阻塞其它所有锁。在本次测试中,CDH5.9的Concurrency参数是默认开启的(hive.support.concurrency=true),以下分别对开启Concurrency和关闭进行相关测试。
首先在测试之前,创建一个普通的hive表:
向test_transaction表中插入测试数据:
查看插入的数据:
(点击放大图像)
4.1.1 开启Concurrency
(1) 对catalog_sales表进行并发select操作
执行的sql语句