Apache hive - transaction
<개요>
Apache Hive는 HDFS에 저장되어 있는 파일데이터를 SQL 기반으로 처리할 수 있도록 하는 오픈소스이다. (모든 SQL을 지원하는 것은 아니며, 파일시스템 특성상 UPDATE, DELETE는 권장하지 않는다. )
그러나 지속적으로 DataWareHouse 트랜잭션 처리에 대한 요구사항이 꾸준히 생겨서 Hive에서도 트랜잭션을 지원하기 위한 기능이 개발되었다.
이에 대해서 내부구조를 간략히 살펴본다. (원문해석 + 개인이해/경험추가 )
<ACID>
database transaction의 4대 속성이라고도 하는데 다음과 같다.
https://ko.wikipedia.org/wiki/ACID
Atomicity(원자성)
트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다. 예를 들어, 자금 이체는 성공할 수도 실패할 수도 있지만 보내는 쪽에서 돈을 빼 오는 작업만 성공하고 받는 쪽에 돈을 넣는 작업을 실패해서는 안된다. 원자성은 이와 같이 중간 단계까지 실행되고 실패하는 일이 없도록 하는 것
Consistency(일관성)
트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미한다. 무결성 제약이 모든 계좌는 잔고가 있어야 한다면 이를 위반하는 트랜잭션은 중단
Isolation(고립성)
트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다. 이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다. 은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다. 공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미한다. 성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다
Durability(지속성)
공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다. 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다. 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.
<Hive-ACID>
그러나 아직은 제약사항이 좀 있다.
1. 제약사항
- BEGIN, COMMIT, ROLLBACK을 지원하지 않는다. 모두다 auto-commit이다
그렇다 보니 Spring과 연계하여 사용할 때 약간의 불편함이 있다. Spring 에서 지원하는 @JdbcTest 를 사용할 경우 단위테스트 작성시 rollback기능등을 이용하여 각 메소드별 테스트시 데이터정합성이 깨지지 않도록 보장해주는 기능이 있는데 해당 기능이 사용불가능 하다.
- ORC포멧만 지원한다.
- Bucket설정이 되어야 한다. 또한 External Table의 경우 compactor가 제어할 수 없기 때문에 ACID테이블로 만들 수 없다.
- non-ACID session에서는 ACID Table에 대한 읽기/쓰기를 할 수 없다.
어찌보면 당연하다. ACID를 사용하기 위해서는 org.apache.hadoop.hive.ql.lockmgr.DbTxnManager 로 hive transaction manager를 변경해야 한다.
- Dirty read, read committed, repeatable read, serializable의 isolation level은 지원하지 않는다.
- 기존의 zookeeper나 in-memory 락 메커니즘은 호환불가능
2. 기본 설계
처음에 이야기한 것처럼 HDFS는 오직 통으로 움직이는 것을 좋아한다.
그래서 transaction들의 특징을 만족시키기 위해서 아래와 같이 설게되었다.
테이블이나 파티션은 Base 파일의 집합으로 저장하고, 새로운 레코드나 update, delete에 대해서는 Delta 파일로 저장한다. 델타파일들의 집합이 만들어지면 읽는 시점에 합친다.
<Compactor>
ACID를 지원하기 위해서 Meatastore에서 수행되고 있는 background processes들을 compactor라고 한다.
Hive는 Base File과 Delta File을 이용한 Compaction으로 ACID를 지원하기 때문에 Table을 생성할때
STORED AS ORC 와
CLUSTERED BY XXX INTO N BUCKETS 를 반드시 추가해야 한다.
apache orc 사이트에 가면 Hive ACID를 어떤 형태로 Support 하고 있는지 상세하게 설명이 되어있다.
<그림 1 : Hive Table>
<그림 2 : Major & Minor compaction>
Delta파일들이 늘어나게 되면 성능을 위해서 compaction을 수행하게 되는데 유형은 다음과 같다.
- minor compaction : Delta파일들을 모아서 Bucket당 하나의 Delta파일로 rewrite한다.
- major compaction : 하나이상의 Delta파일과 Bucket당 Base파일을 가지고 Bucket당 새로운 Base파일로 rewrite한다.
실제로 YARN 에서 조회하면 UPDATE,DELETE를 수행할때마다 YARN Application이 수행되지는 않으며
주기적으로 수행되는 compactor작업을 확인할 수 있다.
<Transaction/Lock Manager>
추후 상세설명
3. Configuration
Client Side
- hive.support.concurrency – true
- hive.enforce.bucketing – true (Not required as of Hive 2.0)
- hive.exec.dynamic.partition.mode – nonstrict
- hive.txn.manager – org.apache.hadoop.hive.ql.lockmgr.DbTxnManager
Server Side (Metastore)
- hive.compactor.initiator.on – true (See table below for more details)
- hive.compactor.worker.threads – a positive number on at least one instance of the Thrift metastore service
4. Table Properties
ACID를 사용하기 위해서는 (update,delete) "transactional=true" 를 설정해야 한다.
그리고 한번 ACID테이블로 생성하면 되돌릴 수 없으니 주의해야 한다.
또한 hive-sitem.xml등에서 hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager 로 지정해야 하며 이 txManager가 없이는 ACID테이블을 사용할 수 없다.
그리고 2번에서 설명한 것처럼 compaction으로 ACID를 지원하기 때문에 compator에 대한 많은 상세설정이 있으며 compactor에 대한 설정은 ALTER문을 통해서 변경할 수 있다.
<참고사이트>
https://cwiki.apache.org/confluence/display/Hive/Hive+Transactions
https://orc.apache.org/docs/acid.html