메뉴 건너뛰기

Cloudera, BigData, Semantic IoT, Hadoop, NoSQL

Cloudera CDH/CDP 및 Hadoop EcoSystem, Semantic IoT등의 개발/운영 기술을 정리합니다. gooper@gooper.com로 문의 주세요.


hbase HBASE Client API : 기본 기능 정리

구퍼 2013.04.01 13:24 조회 수 : 3781

출처 : http://www.cyworld.com/duetys/14467821

 

3-1. 일반정보<?XML:NAMESPACE PREFIX = O />

HBase에 접근하는 주요 client 인터페이스는 HTable 클래스이다.

org.apache.hadoop.hbase.client 패키지 à Class HTable

, 메소드의 SUMMARY / DETAIL 정보는 아래 URL을 참조하면 된다.
http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/HTable.html

[일반사항]

- 데이터 변경하는 로우 단위 작업은 원자성이 보장 (모든 read & write), 자세한 설명은 ch8

- HTable 인스턴스 생성 시 비용 발생하여 단 한번만 생성

- 스레드 당 하나씩 생성 하여 재사용 한다. (여러 개 필요 시에는 HTablePool 사용 287page)

3-2. CRUD 기능

- CREATE, READ, UPDATE, DELETE HTable Class에서 제공된다.

3.2.1. Put 메소드

- 단일 로우 vs 여러 로우 대상으로 동작하는 기능으로 분리

1). 단일 Put

- Put 인스턴스를 생성하기 위해서는 로우키를 제공해야 한다.

- 로우키 타입은 java 데이터 타입인 바이트배열타입으로 저장됨

- put 할때 타임스탬프를 지정가능하고 명시 하지 않으면 리전 서버의 시스템 date를 사용한다.

- hbase의 기본설정은 하나의 값 버전을 세개까지 저장한다. ( scan ‘테이블명’, {versions => 3} )

[샘플]

public class PutExample {

public static void main(String[] args) throws IOException {

Configuration conf = HBaseConfiguration.create(); ➊ 필요한 설정 객체 생성

HTable table = new HTable(conf, "testtable"); ➋ 인스턴스화한다.

Put put = new Put(Bytes.toBytes("row1")); Put 객체 생성

put.add(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"),Bytes.toBytes("val1")); colfam1:qual1

put.add(Bytes.toBytes("colfam1"), Bytes.toBytes("qual2"),Bytes.toBytes("val2")); colfam1:qual2

table.put(put); testtable이라는 hbase 테이블에 저장

}

}

2). Keyvalue 클래스

: ROW 단위가 아닌 특정 셀 단위의 모든 정보를 반환한다.

: 시스템 내부 용도로 개발되었음. 주로 KEY 데이터간의 비교 / 검증 / 복제 등에 사용

: 대부분 ROW단위로 처리 되기에 실제 어플에서 사용할 경우는 거의 없을 것으로 판단됨.

3). 클라이언트 측 쓰기 버퍼

- round-trip-time을 줄이기 위하여 RPC를 최소화 해야 한다.

- HBase APIclient단에 쓰기 버퍼를 제공함( Default는 비활성화)

- table.setAutoFlush(false) 로 버퍼 enable

- Default Buffer size : 2MB, hbase-site.xml 설정으로 일괄 적용 가능

<property>

<name>hbase.client.write.buffer</name>

<value>20971520</value>

</property>

- Buffer flush

명시적 : flushcommits() 사용

묵시적 : setAutoFlush(true) 일 경우 put 실행시, setWriteBufferSize() 실행 시,

HTable close() 메소드 사용 시 묵시적인 flush 발생 됨

- 클라이언트 버퍼는 cell 데이터가 작을 경우 효과를 볼 수 있음.

4). Put 리스트

- 연산을 일괄로 한데 묶어서 처리 함, SQL INSERT SELECT 구문이라고 생각

- 리스트 기반의 입력은 서버 측에서 입력 연산이 적용 되는 순서를 제어 할 수 없음

데이터 입력 순서를 보장해야 하는 경우 작게 나눈 후 Write cache를 명시적으로 flush 필요함

5). 원자적 확인 후 입력 연산 ( checkAndPut )

- 조건 확인 성공 시 입력 연산이 실행 됨 실패하면 연산은 버려진다.

- A 세션이 작업하는 동안 B세션이 동일한 작업을 실행하여 데이터 변경이 없음을 확인 후 적용

- 동일한 로우에서만 확인하고 수정한다. (원자성은 로우 하나에만 보장됨)

3.2.2. Get 메소드

- 단일 로우 vs 여러 로우 대상으로 동작하는 기능으로 분리

1) 단일 GET

- 특정 로우 하나를 대상으로 수행되지만, 로우 내에서는 컬럼/셀 제한 없음

- 버전개수는 1로 최근 값만 리턴 받음 / setMaxVersions() 매소드를 통하여 지정가능

Configuration conf = HBaseConfiguration.create(); 인스턴스 생성

HTable table = new HTable(conf, "testtable"); 테이블 참조를 인스턴스화

Get get = new Get(Bytes.toBytes("row1")); row1 GET 인스턴스 생성

get.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1")); get instance에 컬럼추가

Result result = table.get(get); hbase에서 row1 colfam1:qual1 컬럼을 읽어 들인다.

byte[] val = result.getValue(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1")); 컬럼의 값을 가져온다.

System.out.println("Value: " + Bytes.toString(val)); ➐ 자바 데이터타입을 string으로 변환하여 결과 출력

2) Result 클래스

- get() 메소드를 통하여 데이터를 읽어 들일 때 get 조건에 만족하는 모든 셀을 담고 있는

Result 클래스의 인스턴스를 반환한다.

- 서버에서 반환한 모든 컬럼패밀리, 퀄리파이어, 타임스탬프 접근 수단을 제공한다.

3) GET List

- 하나의 요청으로 하나 이상의 로우를 요청 시 사용됨

- get 인스턴스와 동일한 배열을 반환하던지 예외발생 둘 중 하나로만 동작한다.

- API에서 일괄처리 진행 중에 부분 실패를 처리하는 방법은 batch() 메소드를 사용해야 한다.

3.2.3. Delete 메소드

1) 단일 delete

- delete 클래스를 생성하려면 삭제 대상 row key를 입력해야한다.

- rowlock 파라미터를 추가 선택하여 동일한 로우를 두번 이상 변경하고자 할 때 사용자 자신의 락을 설정 한다.

- 전체 패밀리 및 그에 석한 모든 컬럼 삭제 / 타임스탬프 지정 가능

[샘플]

Delete delete = new Delete(Bytes.toBytes("row1")); ➊ 특정로우 지정하여 delete 인스턴스생성

delete.setTimestamp(1); ➋ 타임스탬프지정

delete.deleteColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"), 1); ➌컬럼 하나의 특정 버전을 삭제

delete.deleteColumns(Bytes.toBytes("colfam2"), Bytes.toBytes("qual1")); ➍컬럼 하나의 모든 버전을 삭제

delete.deleteColumns(Bytes.toBytes("colfam2"), Bytes.toBytes("qual3"), 15); ➎컬럼 하나의 특정버젼 및 이전버전 모두삭제

delete.deleteFamily(Bytes.toBytes("colfam3")); ➏ 컬럼패밀리 및 그에 속한 모든 컬럼 및 버전 삭제

delete.deleteFamily(Bytes.toBytes("colfam3"), 3); ➐ 지정된 버전 및 그 이전 버전을 모두 삭제

table.delete(delete); HBase 테이블에서 데이터 삭제 진행

table.close();

2) delete 리스트

- put list 와 유사하게 동작한다.

- 리모트 서버에서는 데이터가 삭제되는 순서를 보장할 수 없다는 것을 명심해야 한다.

- table.delete(deletes) 수행 시 실패한 작업은 deletes에 남게 되며,

Exception 처리는 try/catch 구문을 이용하여 예외처리를 한다.

Delete delete4 = new Delete(Bytes.toBytes("row2"));

delete4.deleteColumn(Bytes.toBytes("BOGUS"), Bytes.toBytes("qual1"));

deletes.add(delete4);

try {

table.delete(deletes);

} catch (Exception e) {

System.err.println("Error: " + e);

}

table.close();

System.out.println("Deletes length: " + deletes.size());

for (Delete delete : deletes) {

System.out.println(delete);

}

3) 원자적 확인 후 삭제 연산

- checkAndDelete() 서버측에서 읽은 후 수정 기능 제공

- 동일한 로우에서만 수행 가능함.

3-3. 일괄처리연산 ( batch () )

- delete list, get list 등의 대부분이 batch() 메소드를 기반으로 하고 있어 batch() 권장함

- 동일한 row put, delete 연산을 사용하면 각 연산들은 최적성능을 보장하는 순서로 적용 되기 때문에 경합 발생 등의 불안정한 결과를 야기 할 수 있다.

- batch() 메소드 사용시에는 PUT 인스턴스가 클라이언트 쓰기 버퍼에 저장되지 않고

서버에서 직접 처리 된다.

- 일괄처리 메소드

Void batch(actions, results) : 성공한 연산 결과 및 실패한 연산정보 함께 반환

Object[] batch(actions) : 실패 발생하면 아무것도 return 되지 않는다.

3-4. 로우락

- 리전서버는 row locks 기능 제공하여 한 개의 로우에 대한 exclusive lock 가능

- hbase lock 만료기한은 default 1, hbase-site.xml base.regionserver.lease.period 파라미터

- 클라이언트 측에서 lockRow() 명시적인호출 시 unlockRow() 를 통하여 반드시 해제해야 한다.

3-5. SCAN

1) 특성

- SCAN의 경우 HBase 테이블에서 탐색할 시작/종료 로우키를 지정할 수 있다.

- 시작 로우는 탐색에 포함되고 종료 로우는 대상에서 제외된다.

( START ROW KEY =< 스캔대상 < END ROW KEY )

- 시작 로우 KEY가 지정되지 않으면 테이블의 맨 처음에서 시작(ENDKEY 없어도 마지막까지 실행)

- addFamily(), addColumn() 등을 사용하여 지정한 컬럼값만 탐색 스캔범위를 좁히는 역할을 수행

스캔범위 제외된 컬럼은 읽지 않아도 되어 Column based의 장점을 극대화 가능.

2) ResultScanner Class

- 스캔 되어 진 로우들을 RPC로 클라이언트에 전송할때는 로우 단위로 반환된다.

- 스캔된 결과가 아주 큰 경우를 대비하여 ResultScanner를 통하여 각 로우에 대한 Result 인스턴스를 이터레이트 할 수 있도록 감싼 형태이다.

3) 캐싱 vs 일괄처리

- 스캐너캐싱 : 한번의 RPC에서 여러 개의 로우를 전송하는 방식

- 테이블 단위의 캐싱과 스캔단위의 캐싱으로 나뉘어 짐

RDBMS에서 테이블에 DEGREE 적용 VS 쿼리 HINT PARALLEL적용 정도의 차이일듯

- 스캐너 캐싱의 최적값은 전송 데이터양과 클라이언트 단의 MAX HEAP 메모리를 검토해야 함

- 일괄처리 : 로우 단위 동작이 아닌 컬럼 단위로 동작 한다.

, 일괄처리가 3이면 서버에서 컬럼 3개를 하나의 RESULT 로 묶는다는 얘기이며,

- RPCs = (Rows * Cols per Row) / Min(Cols per Row, Batch size) / Scanner Caching

[샘플]

<?-ml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?XML:NAMESPACE PREFIX = V />

download?fid=64223d19b27d14e3ec123d8bedd

download?fid=64223d19b27d14e3d3253d8beeb

* 샘플 예제를 그림으로 설명하면,

Caching:2, Batch=10 으로 했을 경우 200/10=20 result 20개 필요

RPC = 10 + Scan 완료를 위한 RPC 1회 추가 = 11회 발생됨

download?fid=64223d19b27d14e35cb03d8beeb

번호 제목 날짜 조회 수
30 scan의 startrow, stoprow지정하는 방법 2015.04.08 1147
29 SASL configuration failed: javax.security.auth.login.LoginException: java.lang.NullPointerException 오류 해결방법 2015.04.02 1049
28 root가 localhost에서 mysql로 접근하지 못하는 경우의 해결방법(패스워드) 2014.09.10 793
27 hadoop의 data디렉토리를 변경하는 방법 2014.08.24 1127
26 access=WRITE, inode="staging":ubuntu:supergroup:rwxr-xr-x 오류 2014.07.05 1846
25 org.apache.hadoop.security.AccessControlException: Permission denied: user=hadoop, access=WRITE, inode="":root:supergroup:rwxr-xr-x 오류 처리방법 2014.07.05 2989
24 banana pi에(lubuntu)에 hadoop설치하고 테스트하기 - 성공 file 2014.07.05 2865
23 hadoop및 ecosystem에서 사용되는 명령문 정리 2014.05.28 3890
22 hbase shell에서 컬럼값 검색하기(SingleColumnValueFilter이용) 2014.04.25 2755
21 column family삭제시 Column family 'delete' does not exist오류 발생하는 경우 2014.04.14 1058
20 hadoop설치시 오류 2013.12.18 2731
19 hbase에 필요한 jar들 2013.04.01 2254
18 Hbase Shell 명령 정리 2013.04.01 3479
» HBASE Client API : 기본 기능 정리 file 2013.04.01 3781
16 하둡 분산 파일 시스템을 기반으로 색인하고 검색하기 2013.03.15 5781
15 HBase, BigTable, Cassandra Schema Design file 2013.03.15 2904
14 HBase shell로 작업하기 2013.03.15 5982
13 org.apache.hadoop.hbase.PleaseHoldException: Master is initializing 2013.03.15 3093
12 Cacti로 Hadoop 모니터링 하기 file 2013.03.12 2732
11 HBase 설치하기 – Fully-distributed 2013.03.12 4018
위로