클라이언트 요청 필터
클라이언트 요청 필터 (Client Request Filters)
Get과 Scan 인스턴스에는 RegionServer에서 적용되는 필터를 선택적으로 구성할 수 있어요. 필터 종류가 많아 헷갈릴 수 있으니, Filter 기능의 그룹을 이해하며 접근하는 것이 좋아요. 구조적 필터부터 컬럼 값 필터, 비교자, KeyValue 메타데이터 필터, 행키 필터, 유틸리티 필터를 살펴볼게요.
출처: 문서
본문
Get과 Scan 인스턴스는 RegionServer에서 적용되는 필터로 선택적으로 구성할 수 있어요.
필터는 종류가 많아 혼란스러울 수 있으니, Filter 기능의 그룹을 이해하며 접근하는 것이 좋아요.
구조적 (Structural)
구조적 필터(Structural Filters)는 다른 필터를 포함해요.
FilterList
FilterList는 필터 간 FilterList.Operator.MUST_PASS_ALL 또는 FilterList.Operator.MUST_PASS_ONE 관계를 가진 필터 목록을 나타내요. 다음 예시는 두 필터 사이에 'or'를 보여줘요(같은 속성에서 'my value' 또는 'my other value'를 확인).
FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);
SingleColumnValueFilter filter1 = new SingleColumnValueFilter(
cf,
column,
CompareOperator.EQUAL,
Bytes.toBytes("my value")
);
list.add(filter1);
SingleColumnValueFilter filter2 = new SingleColumnValueFilter(
cf,
column,
CompareOperator.EQUAL,
Bytes.toBytes("my other value")
);
list.add(filter2);
scan.setFilter(list);
컬럼 값 (Column Value)
SingleColumnValueFilter
SingleColumnValueFilter(https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/SingleColumnValueFilter.html)는 컬럼 값을 동등(CompareOperaor.EQUAL), 부등(CompareOperaor.NOT_EQUAL), 또는 범위(예: CompareOperaor.GREATER)로 테스트하는 데 사용할 수 있어요. 다음은 컬럼을 String 값 "my value"와 동등한지 테스트하는 예시예요...
SingleColumnValueFilter filter = new SingleColumnValueFilter(
cf,
column,
CompareOperaor.EQUAL,
Bytes.toBytes("my value")
);
scan.setFilter(filter);
ColumnValueFilter
HBase-2.0.0 버전에서 SingleColumnValueFilter의 보완으로 도입된 ColumnValueFilter는 매칭된 cell만 가져오는 반면, SingleColumnValueFilter는 매칭된 cell이 속한 전체 행(다른 컬럼과 값 포함)을 가져와요. ColumnValueFilter 생성자의 매개변수는 SingleColumnValueFilter와 동일해요.
ColumnValueFilter filter = new ColumnValueFilter(
cf,
column,
CompareOperaor.EQUAL,
Bytes.toBytes("my value")
);
scan.setFilter(filter);
참고. "family:qualifier:value가 같다" 같은 단순한 질의의 경우, SingleColumnValueFilter나 ColumnValueFilter를 사용하는 대신 다음 방법을 강력히 권장해요.
Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("family"), Bytes.toBytes("qualifier"));
ValueFilter vf = new ValueFilter(CompareOperator.EQUAL,
new BinaryComparator(Bytes.toBytes("value")));
scan.setFilter(vf);
...
이 스캔은 지정된 컬럼 'family:qualifier'로 제한해 관련 없는 패밀리와 컬럼의 스캔을 피하므로 성능이 더 좋고, ValueFilter는 값 필터링을 수행하는 조건이에요.
하지만 질의가 이 책을 넘어 훨씬 더 복잡하다면, 사례별로 좋은 선택을 해 주세요.
컬럼 값 비교자 (Column Value Comparators)
Filter 패키지에는 특별히 언급할 가치가 있는 몇 가지 Comparator 클래스가 있어요. 이 비교자들은 SingleColumnValueFilter 같은 다른 필터와 함께 사용돼요.
RegexStringComparator
RegexStringComparator는 값 비교를 위한 정규식을 지원해요.
RegexStringComparator comp = new RegexStringComparator("my."); // any value that starts with 'my'
SingleColumnValueFilter filter = new SingleColumnValueFilter(
cf,
column,
CompareOperaor.EQUAL,
comp
);
scan.setFilter(filter);
Java에서 지원되는 RegEx 패턴은 Oracle JavaDoc을 참고해 주세요.
SubstringComparator
SubstringComparator는 주어진 부분 문자열(서브스트링)이 값에 존재하는지 판별하는 데 사용할 수 있어요. 비교는 대소문자를 구분하지 않아요.
SubstringComparator comp = new SubstringComparator("y val"); // looking for 'my value'
SingleColumnValueFilter filter = new SingleColumnValueFilter(
cf,
column,
CompareOperaor.EQUAL,
comp
);
scan.setFilter(filter);
BinaryPrefixComparator
BinaryPrefixComparator를 참고해 주세요.
BinaryComparator
BinaryComparator를 참고해 주세요.
BinaryComponentComparator
BinaryComponentComparator는 cell 값 안의 특정 위치에 있는 특정 값을 비교하는 데 사용할 수 있어요. 비교는 ascii와 binary 데이터 모두에서 수행할 수 있어요.
byte[] partialValue = Bytes.toBytes("partial_value");
int partialValueOffset = 0;
Filter partialValueFilter = new ValueFilter(CompareFilter.CompareOp.GREATER,
new BinaryComponentComparator(partialValue,partialValueOffset));
다른 사용 사례와 자세한 내용은 HBASE-22969를 참고해 주세요.
KeyValue 메타데이터 (KeyValue Metadata)
HBase는 내부적으로 데이터를 KeyValue 쌍으로 저장하므로, KeyValue 메타데이터 필터는 이전 섹션의 값이 아니라 행에 대한 키(즉, ColumnFamily:Column qualifier)의 존재를 평가해요.
FamilyFilter
FamilyFilter는 ColumnFamily에 대해 필터링하는 데 사용할 수 있어요. 일반적으로 필터로 하는 것보다 Scan에서 ColumnFamily를 선택하는 것이 더 좋은 아이디어예요.
QualifierFilter
QualifierFilter는 Column(일명 Qualifier) 이름을 기준으로 필터링하는 데 사용할 수 있어요.
ColumnPrefixFilter
ColumnPrefixFilter는 Column(일명 Qualifier) 이름의 앞부분(lead portion)을 기준으로 필터링하는 데 사용할 수 있어요.
ColumnPrefixFilter는 각 행과 관련된 각 컬럼 패밀리에서 접두사와 일치하는 첫 번째 컬럼으로 앞으로 탐색해요. 아주 넓은 행에서 컬럼의 부분 집합을 효율적으로 가져오는 데 사용할 수 있어요.
참고: 같은 컬럼 qualifier가 다른 컬럼 패밀리에 사용될 수 있어요. 이 필터는 일치하는 모든 컬럼을 반환해요.
예시: 행과 패밀리에서 "abc"로 시작하는 모든 컬럼 찾기
Table t = ...;
byte[] row = ...;
byte[] family = ...;
byte[] prefix = Bytes.toBytes("abc");
Scan scan = new Scan(row, row); // (optional) limit to one row
scan.addFamily(family); // (optional) limit to one family
Filter f = new ColumnPrefixFilter(prefix);
scan.setFilter(f);
scan.setBatch(10); // set this if there could be many columns returned
ResultScanner rs = t.getScanner(scan);
for (Result r = rs.next(); r != null; r = rs.next()) {
for (Cell cell : result.listCells()) {
// each cell represents a column
}
}
rs.close();
MultipleColumnPrefixFilter
MultipleColumnPrefixFilter는 ColumnPrefixFilter처럼 동작하지만 여러 접두사를 지정할 수 있어요.
ColumnPrefixFilter처럼 MultipleColumnPrefixFilter는 가장 낮은 접두사와 일치하는 첫 번째 컬럼으로 효율적으로 앞으로 탐색하고, 접두사 사이의 컬럼 범위도 지나쳐 탐색해요. 아주 넓은 행에서 불연속적인 컬럼 집합을 효율적으로 가져오는 데 사용할 수 있어요.
예시: 행과 패밀리에서 "abc" 또는 "xyz"로 시작하는 모든 컬럼 찾기
Table t = ...;
byte[] row = ...;
byte[] family = ...;
byte[][] prefixes = new byte[][] {Bytes.toBytes("abc"), Bytes.toBytes("xyz")};
Scan scan = new Scan(row, row); // (optional) limit to one row
scan.addFamily(family); // (optional) limit to one family
Filter f = new MultipleColumnPrefixFilter(prefixes);
scan.setFilter(f);
scan.setBatch(10); // set this if there could be many columns returned
ResultScanner rs = t.getScanner(scan);
for (Result r = rs.next(); r != null; r = rs.next()) {
for (Cell cell : result.listCells()) {
// each cell represents a column
}
}
rs.close();
ColumnRangeFilter
ColumnRangeFilter는 행 내부(intra row) 스캔을 효율적으로 허용해요.
ColumnRangeFilter는 관련된 각 컬럼 패밀리의 첫 번째 일치 컬럼으로 앞으로 탐색할 수 있어요. 아주 넓은 행의 컬럼 '조각(slice)'을 효율적으로 가져오는 데 사용할 수 있어요. 즉, 행에 100만 개의 컬럼이 있지만 bbbb-bbdd 컬럼만 보길 원하는 경우예요.
참고: 같은 컬럼 qualifier가 다른 컬럼 패밀리에 사용될 수 있어요. 이 필터는 일치하는 모든 컬럼을 반환해요.
예시: 행과 패밀리에서 "bbbb"(포함)와 "bbdd"(포함) 사이의 모든 컬럼 찾기
Table t = ...;
byte[] row = ...;
byte[] family = ...;
byte[] startColumn = Bytes.toBytes("bbbb");
byte[] endColumn = Bytes.toBytes("bbdd");
Scan scan = new Scan(row, row); // (optional) limit to one row
scan.addFamily(family); // (optional) limit to one family
Filter f = new ColumnRangeFilter(startColumn, true, endColumn, true);
scan.setFilter(f);
scan.setBatch(10); // set this if there could be many columns returned
ResultScanner rs = t.getScanner(scan);
for (Result r = rs.next(); r != null; r = rs.next()) {
for (Cell cell : result.listCells()) {
// each cell represents a column
}
}
rs.close();
참고: HBase 0.92에서 도입됨
RowKey
RowFilter
행 선택에는 Scan의 startRow/stopRow 메서드를 사용하는 것이 일반적으로 더 좋은 아이디어지만, RowFilter도 사용할 수 있어요.
BinaryComponentComparator로 구성된 RowFilter로 스캔(유계 및 무계 모두)을 보충해 행을 추가로 걸러내거나 포함시킬 수 있어요. 사용 사례와 자세한 내용은 HBASE-22969를 참고해 주세요.
유틸리티 (Utility)
FirstKeyOnlyFilter
이것은 주로 rowcount 작업에 사용돼요. FirstKeyOnlyFilter를 참고해 주세요.
더 알아보기 (Learn more)
HBase 클라이언트와 Get/Scan 사용법은 Client 문서와 HBase Java API 문서를 이어서 보시길 권해요.