View

* Transaction (beta 기능) 

Phoenix는 기존 HBase 의 row-level 의 트랜잭션을 넘어서, Phoenix는 여러 row나 table을 대상으로 트랜잭션을 지원하는데, Apache Tephra를 통해서 ACID를 보장한다. Tephra는 현재의 트랜잭션에 대한 snapshot을 제공하는데, 이는 multi-version의 동시성 제어를 지원한다. 


이 기능을 사용하기 위해서는 phoenix 에서 다음과 같은 두 단계의 설정이 필요하다 


1. hbase-site.xml 에 다음 property 추가 

<property>
  <name>phoenix.transactions.enabled</name>
  <value>true</value>
</property>


2. server-side(hmaster) hbase-site.xml 에 트랜잭션 매니저 설정값 입력. 
(Tephra의 'Transaction Server Configuration' 에서 제공하는 설정값) 

<property>
  <name>data.tx.snapshot.dir</name>
  <value>/tmp/tephra/snapshots</value>
</property>


또한 트랜잭션 타임아웃도 설정 가능하다

<property>
  <name>data.tx.timeout</name>
  <value>60</value>
</property>


3. $HBASE_HOME 환경변수 설정 후 트랜잭션 매니저 실행 

$> ./bin/tephra


트랜잭션 매니저는 일반적으로 하나 이상의 Hbase의 hmaster node 에서 수행되도록 설정될 수 있다. 




일단 설정이 완료되면 테이블 생성 시 'TRANSACTIONAL=true' 옵션을 줌으로써 테이블 기반으로 트랜잭션이 발생할 수 있게된다. 

CREATE TABLE my_table (k BIGINT PRIMARY KEY, v VARCHAR) TRANSACTIONAL=true;



만약 기존에 있던 테이블을 transactional 테이블로 변경하고 싶은 경우는 아래와 같이 수행하면되는데, 한번 transactional 테이블로 변경한 경우 다시 되돌릴 수 없음으로 주의해야 한다. 

ALTER TABLE my_other_table SET TRANSACTIONAL=true;



트랜잭션은 tranactional 테이블에서 쿼리가 수행될때 암묵적으로 발생되며, commit 이나 rollback에 의해서 종료된다. 

일단 시작되면 트랜잭션이 종료되기 이전까지 다른 트랜잭션에게는 커밋된 데이터가 보이지 않으며, commit 되지 않은 데이터가 보이게 된다. 


예를 들면 아래와 같다. 

SELECT * FROM my_table;  # 트랜잭션 시작

UPSERT INTO my_table VALUES (1,'A');

SELECT count(*) FROM my_table WHERE k=1;  # 커밋되기 전의 row

DELETE FROM my_other_table WHERE k=2;

!commit  # 이제 다른 트랜잭션에서도 볼 수 있다. 



만약 트랜잭션이 이미 커밋된 트랜잭션에 덮어쓰는 작업으로 커밋 작업이 충돌나는 경우 예외exception이 발생한다. 


$session A > UPSERT INTO my_table VALUES (1,'A');   # 먼저 수행 후 커밋하지 않음 

$session B > UPSERT INTO my_table VALUES (1,'B');   # 그 다음 수행 후 커밋 

$session B > !commit

$session A > !commit 

java.sql.SQLException: ERROR 523 (42900): Transaction aborted due to conflict with other mutations. Conflict detected for transaction 1454112544975000000.


쿼리들은 오직 완전히 commit 된 데이터만 볼 수 있기 때문에 현재 트랜잭션이 수행되었다 하더라도 커밋 전까지 데이터를 확인할 수 없다. 



Tranactional table에 추가된 인덱스들은 관리 포인트를 증가시키게 된다. 

예를들어 my_table 에 추가된 아래 index는 테이블의 데이터가 변경된다고 하더라도트랜잭션의 일관성을 유지하게 된다. 

CREATE INDEX  my_table (k BIGINT PRIMARY KEY, v VARCHAR) TRANSACTIONAL=true;

commit 이 수행되는 동안, 만약 인덱스나 데이터 테이블 중 하나가 예외로 쓰기작업을 실패한다면 client는 rollback하여 다시 수행할 수 있다. 

만약에 commit 이 실패한다면 index와  data table의 rows 모두 보이지 않을 것이다. 

Tephra 를 통한 외부 transaction은 phoenix connection 설정을 통해서 Phoenix 를 사용할 수 있다. 

setTransactionContext(TransactionContext txContext)



** 제한사항 

- SCN connection 집합을 통한 transaction 의 시작은 허용되지 않는다. 

- Transactional table을 생성하면서 설정하는 동시성 트랜잭션을 위한 최대 property 버전은 제한된다. 

- 만약 클라이언트로부터 롤백할 수 없어 발생하는 트랜잭션 타임아웃의 경우 invalid list 에 추가된다. 이 리스트는 많은 트랜잭션이 취소되는 경우 계속해서 커질수가 있다. 기능향상으로 관리자는 수동으로 이 리스트에서 트랜잭션을 제거할 수 있는데, major compaction이 발생한 후에 가능하다. 

- 'TEPHRA-35' 는 이 트랜잭션과 관련된 모든 데이터가 삭제된 후에 자동으로 이 리스트를 제거하는 방법을 진행중이다. 

- 만약 비동기적으로 기존에 존재하는 Transactional table 에 대해서 인덱스를 추가하는 경우, CREATE INDEX ASYNC 를 수행하기 전에 major compaction을 수행해야 한다. 그렇지 않으면 잘못되거나 커밋되지 않은 트랜잭션이 index에 추가될 수 있다. (PHOENIX-2154) 



Share Link
reply
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31