在CDH配置使得其支持ACID
原理
ACID说明
何为事务?就是一组单元化操作,这些操作要么都执行,要么都不执行,是一个不可分割的工作单位。
事务(transaction)所应该具有的四个要素:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。这四个基本要素通常称为ACID特性。
-
原子性(Atomicity):一个事务是一个不可再分割的工作单位,事务中的所有操作要么都发生,要么都不发生。
-
一致性(Consistency):事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
-
隔离性(Isolation):多个事务并发访问,事务之间是隔离的,一个事务不影响其它事务运行效果。这指的是在并发环境中,当不同的事务同时操作相同的数据时,每个事务都有各自完整的数据空间。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改后的状态,事务不会查看到中间状态的数据。事务之间的相应影响,分别为:脏读、不可重复读、幻读、丢失更新。
-
持久性(Durability):意味着在事务完成以后,该事务锁对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
ACID的实现原理
事务可以保证ACID原则的操作,那么事务是如何保证这些原则的?解决ACID问题的两大技术点是:
- 预写日志(Write-ahead logging)保证原子性和持久性
- 锁(locking)保证隔离性
这里并没有提到一致性,是因为一致性是应用相关的话题,它的定义一个由业务系统来定义,什么样的状态才是一致?而实现一致性的代码通常在业务逻辑的代码中得以体现。
注:锁是指在并发环境中通过读写锁来保证操作的互斥性。根据隔离程度不同,锁的运用也不同。
限制
- 不支持begin,commit, rollback
- 只支持ORC文件格式
- 表必须分桶
- 不允许从一个非ACID连接写入/读取acid表
配置的参数
- hive.support.concurrency = true
- hive.enforce.bucketing = true
- hive.exec.dynamic.partition.mode = nonstrict
- hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager
- hive.compactor.initiator.on = true
- hive.compactor.worker.threads = 1 (optional)
CDH上面的配置
HIVE 客户端的配置
进行如下配置,就能在hive客户端支持ACID。
beeline 客户端的配置
进行如下配置,就能在beeline客户端支持ACID。
使用
建表
create table test_trancaction
(user_id Int,name String)
clustered by (user_id) into 3 buckets stored as orc TBLPROPERTIES ('transactional'='true');
Hive事务使用建议
- 传统数据库中有三种模型隐式事务、显示事务和自动事务。在目前Hive对事务仅支持自动事务,因此Hive无法通过显示事务的方式对一个操作序列进行事务控制。
- 传统数据库事务在遇到异常情况可自动进行回滚,目前Hive无法支持ROLLBACK。
- 传统数据库中支持事务并发,而Hive对事务无法做到完全并发控制,多个操作均需要获取WRITE的时候则这些操作为串行模式执行(在测试用例中”delete同一条数据的同时update该数据”,操作是串行的且操作完成后数据未被删除且数据被修改)未保证数据一致性。
- Hive的事务功能尚属于实验室功能,并不建议用户直接上生产系统,因为目前它还有诸多的限制,如只支持ORC文件格式,建表必须分桶等,使用起来没有那么方便,另外该功能的稳定性还有待进一步验证。
- CDH默认开启了Hive的Concurrency功能,主要是对并发读写的的时候通过锁进行了控制。所以为了防止用户在使用Hive的时候,报错提示该表已经被lock,对于用户来说不友好,建议在业务侧控制一下写入和读取,比如写入同一个table或者partition的时候保证是单任务写入,其他写入需控制写完第一个任务了,后面才继续写,并且控制在写的时候不让用户进行查询。另外需要控制在查询的时候不要允许有写入操作。
- 如果对于数据一致性不在乎,可以完全关闭Hive的Concurrency功能关闭,即设置hive.support.concurrency为false,这样Hive的并发读写将没有任何限制。
查看事物锁
在hive.support.concurrency = true的情况下,该命令可用。
show locks