HBase 는 SQL 엔진이 아니므로 SELECT ... WHERE 를 그대로 쓸 수 없다. 셸에서 rowkey 로 찾고, 범위를 자르고, 필터를 걸어 원하는 셀을 꺼내는 방법을 정리한다. SQL 문법이 필요하면 Phoenix 나 Hive 연동을 쓴다.
hbase shell
create 'test_table', 'cf1'
put 'test_table', 'row1', 'cf1:col1', 'value1'
put 'test_table', 'row2', 'cf1:col1', 'value2'
list
list 'test_.*'
describe 'test_table'
RowKey 를 bodname|item 처럼 구분자로 이어 붙이는 설계는 가능하다. HBase 는 그것을 단순 바이트 문자열로 보고 사전순으로 정렬할 뿐이며 | 에 의미를 두지 않는다. 다만 앞부분 값이 한쪽에 몰리면 특정 리전에 쓰기가 집중되는 hotspot 이 생기므로, 접두사에 해시나 salt 를 붙이는 설계를 함께 검토한다.
get 'TBL', 'aaa'
get 'TBL', 'aaa', 'cf1:col1'
get 'TBL', 'aaa', { COLUMN => ['cf1:col1', 'cf1:col2'] }
get 'TBL', 'aaa', { COLUMN => 'cf1:col1', VERSIONS => 3 }
get 은 기본적으로 각 컬럼의 최신 버전만 돌려준다. 이전 버전을 보려면 VERSIONS 를 지정하되, 컬럼 패밀리의 VERSIONS 설정이 그만큼 보존하도록 되어 있어야 한다.
scan 'user'
scan 'user', { LIMIT => 10 }
scan 'user', { COLUMNS => ['info:name', 'info:age'] }
scan 'user', { STARTROW => 'user001', STOPROW => 'user100' }
scan 'user', { FILTER => "PrefixFilter('user00')" }
scan 'user', { FILTER => "RowFilter(=, 'binary:user001')" }
scan 'user', { FILTER => "SingleColumnValueFilter('info', 'age', >=, 'binary:25')" }
STOPROW 는 포함하지 않는다. 필터 문자열 안의 값은 비교자 접두사(binary:, substring:, regexstring:)를 붙여야 한다.
HBase 는 RowKey 의 바이트 오름차순으로만 저장하고 스캔하므로 내림차순 스캔을 지원하지 않는다. 최근 데이터를 먼저 읽어야 한다면 RowKey 설계 단계에서 역순 키(Long.MAX_VALUE - timestamp)를 쓰거나, 읽은 뒤 클라이언트에서 정렬하거나, Phoenix 의 ORDER BY ... DESC 를 쓴다. 참고로 scan 의 REVERSED => true 옵션이 HBase 0.98 이후 존재하지만 성능 특성이 정방향과 다르므로 대량 스캔에는 권하지 않는다.
disable 'test_table'
drop 'test_table'
exists 'test_table'
disable 을 건너뛰면 오류가 난다. 한 줄로 처리하려면 다음처럼 쓴다.
echo "disable 'test_table'; drop 'test_table'" | hbase shell -n
셸에서 scan 을 조건 없이 실행하면 테이블 전체를 훑는다. 대용량 테이블에서는 RegionServer 에 부하를 주므로 LIMIT 또는 STARTROW/STOPROW 를 반드시 건다.
hbase> config 같은 명령으로 설정을 조회하거나 세션 단위로 바꿀 수 있다는 설명이 인터넷에 돌아다니지만, HBase 셸에는 그런 명령이 없다. 설정 확인은 Master/RegionServer 웹 UI 의 Configuration 페이지나 hbase-site.xml 을 본다.