HBase 에 SQL 로 접근해야 할 때 Apache Phoenix 를 쓴다. JDBC 드라이버를 제공하므로 DBeaver 같은 클라이언트나 애플리케이션에서 일반 RDBMS 처럼 다룰 수 있다.
ZooKeeper 쿼럼을 그대로 적는다. 포트는 마지막에 한 번만 쓴다.
jdbc:phoenix:zk1,zk2,zk3:2181
HBase 의 znode 경로가 기본값(/hbase)이 아니면 뒤에 붙인다. Cloudera 배포판은 보안 여부에 따라 /hbase 또는 /hbase-secure 를 쓴다.
jdbc:phoenix:zk1,zk2,zk3:2181:/hbase-secure
Kerberos 환경이면 principal 과 keytab 을 이어 붙인다.
jdbc:phoenix:zk1,zk2,zk3:2181:/hbase-secure:hbase@KRB.EXAMPLE.NET:/etc/security/keytabs/hbase.keytab
sqlline.py zk1,zk2,zk3:2181
!tables
SELECT TABLE_SCHEM, TABLE_NAME
FROM SYSTEM.CATALOG
WHERE TABLE_TYPE = 'u'
ORDER BY TABLE_SCHEM, TABLE_NAME;
SELECT * FROM MY_TABLE LIMIT 10;
SELECT NAME, AGE FROM MY_TABLE WHERE ID = 1001;
드라이버 관리자에서 새 드라이버를 만들고 클래스명을 org.apache.phoenix.jdbc.PhoenixDriver 로 둔다. JAR 은 클러스터 버전에 맞는 phoenix-client 를 쓴다. 서버와 클라이언트 버전이 어긋나면 접속 직후 coprocessor 관련 오류가 난다. URL 템플릿은 위 접속 문자열과 같다. 테이블이 보이지 않으면 연결을 새로고침하고, 그래도 없으면 SYSTEM.CATALOG 조회로 실제 등록 여부를 확인한다.
Phoenix 는 따옴표 없는 식별자를 모두 대문자로 올린다. HBase 쪽 테이블명이 소문자라면 Phoenix 에서는 큰따옴표로 감싸야 찾는다.
SELECT * FROM "my_lower_table" WHERE "ROWKEY" = 'aaa';
기존 HBase 테이블을 Phoenix 로 읽으려면 CREATE TABLE 대신 뷰를 만들어 매핑하는 편이 안전하다. Phoenix 가 테이블을 직접 만들면 자체 인코딩 규칙으로 값을 저장하므로, 기존 데이터의 바이트 표현과 어긋날 수 있다.
Phoenix 로 만든 테이블을 HBase Master UI 에서 보면 coprocessor$1 부터 여러 항목이 붙어 있다.
| 키 | 클래스 | 역할 |
|---|---|---|
coprocessor$1 |
org.apache.phoenix.coprocessor.ScanRegionObserver |
SELECT/스캔의 projection 과 filter 를 RegionServer 에서 처리 |
coprocessor$2 |
org.apache.phoenix.coprocessor.UngroupedAggregateRegionObserver |
GROUP BY 없는 집계 |
coprocessor$3 |
org.apache.phoenix.coprocessor.GroupedAggregateRegionObserver |
GROUP BY 집계 |
coprocessor$4 |
org.apache.phoenix.coprocessor.ServerCachingEndpointImpl |
조인용 서버 측 캐시 |
이 항목들은 Phoenix 가 자동으로 붙인 것이며 손으로 지우면 Phoenix 쿼리가 깨진다. HBase 를 업그레이드할 때 Phoenix 버전을 함께 맞추지 않으면 coprocessor 클래스 로딩 실패로 RegionServer 가 뜨지 않는 사고가 생긴다.