2016-06-18 5 views
4

나는 Hbase 쿼리를 위해 클라이언트로 Java를 사용하고 있습니다.효율적으로 Hbase 쿼리

내 HBase와 테이블은 다음과 같이 설정 :

ROWKEY  |  HOST  |  EVENT 
-----------|--------------|---------- 
21_1465435 | host.hst.com | clicked 
22_1463456 | hlo.wrld.com | dragged 
    .    .    . 
    .    .    . 
    .    .    . 

내가 가장 먼저해야 할 일은 host.hst.com는 그것과 관련된이 모든 ROWKEYs의 목록을 얻을 수 있습니다.

host에 스캐너를 만들 수 있으며 각 행 값에 대해 column value = host.hst.com을 사용하여 해당 ROWKEY을 목록에 추가합니다. 꽤 효율적이라고 보입니다. O(n) 모든 행을 가져옵니다.

이제 어려운 부분입니다. 목록에있는 각 ROWKEY에 해당하는 EVENT을 가져와야합니다. 내가 (ROWKEY, EVENT)에서 셀을 얻기 위해 정상 GET 명령을 사용하는 경우

, 나는 스캐너가 올바른 셀을 찾아 값을 반환하는 O(n) 시간이 소요 EVENT에서 생성됩니다 믿습니다. 각 개인의 시간 복잡성은 꽤 나쁘다. ROWKEY. 두 가지를 결합하면 O(n^2)이됩니다.

이것에 대해 더 효율적인 방법이 있습니까?

사전에 도움을 주셔서 감사합니다.

답변

2

여기에 n은 무엇입니까 ?? RowKey를 사용하여 - HBase rowkey - 일부 수작업이 아닌 것을 의미하는 것으로 추정됩니까? HBase가 빠르고 쉽습니다. 그것이 O (1)라고 생각하십시오. 다음

대신 ROWKEY 실제 열 생성 당신 인 경우 ... 문제입니다. 대신 제공된 HBase 제공된 행키를 사용하십시오.

이제는 (a) 이미 제공된 hbase를 rowkey으로 적절하게 사용하거나 구조를 수정했다고 가정 해 보겠습니다. 다음과 같이

이 경우 당신은 단순히 각 (rowkey, EVENT) 값에 대해 별도의 get을 만들 수 있습니다

Perform a `get` with the given `rowkey`. 
In your result then filter out EVENT in <yourEventValues for that rowkey> 

그래서 당신은 주어진 rowkey에 대한 모든 최근 (최신 타임 스탬프) 항목을 가져 오는 종료됩니다. 이것은 아마도 'n'에 비해 작은 것입니까 ?? 그런 다음 필터링은 하나의 열에 대한 빠른 작업입니다.

일괄 처리 multiget을 실행하여 속도를 향상시킬 수도 있습니다. 절약 효과는 HBase 마스터에 대한 감소 된 왕복 및 마스터/지역 서버에 의한 분석/계획 생성으로 인한 것입니다.

업데이트 OP 덕분에 : 더 명확하게 상황을 이해합니다. 단순히 "호스트 |"를 행키로 사용하는 것이 좋습니다. 그런 다음 범위 스캔을 수행하고 /Scan 단일 항목에서 항목을 가져올 수 있습니다.

HBase와는 rowkey의 프리픽스에 기초하여 다양한 검사를 지원하는 다른 업데이트. 그래서 당신 foobarRow1, foobarRow2, 등 .. (foobarRow, foobarRowz)에서 범위 스캔을 할 수 있고 foobarRow로 시작하는 행키와 모든 영숫자 문자가있는 행을 모두 찾을 수 있습니다. 20110103-120110105-1 검색 할 rowkeys의 범위를 제공하는

SingleColumnValueFilter filter = new SingleColumnValueFilter(
    Bytes.toBytes("columnfamily"), 
    Bytes.toBytes("storenumber"), 
    CompareFilter.CompareOp.NOT_EQUAL, 
    Bytes.toBytes(15) 
); 
filter.setFilterIfMissing(true); 
Scan scan = new Scan(
    Bytes.toBytes("20110103-1"), 
    Bytes.toBytes("20110105-1") 
); 
scan.setFilter(filter); 

주의 사항 :

는 여기에 몇 가지 예시 코드는이 HBase (Easy): How to Perform Range Prefix Scan in hbase shell

를 살펴 보자.

+0

답변 해 주셔서 감사합니다. 나는'HOST' 컬럼을 스캔하고'host = x'를 가진 모든 대응'ROWKEYs '의 String리스트를 리턴하는 메소드를 작성했다. 3 초가 걸립니다. 그런 다음이 모든 행크 키와'이벤트 '를 모두 반복하는 방법을 썼습니다. 이것은 aound 120 초가 걸립니다. 'GET '에 대해 이것이 어떻게'O (1) '이 될 수 있습니까? –

+0

'n'은 행 수를 의미합니다. 또한 내 자신의 사용자 정의 컬럼이 아닌 기본 Rowkeys를 사용하고 있습니다. –

+0

@GregPeckory 이제 "얻으십시오". 그래서 제안한 답변을 업데이트했습니다 : " ROWKEY"로 구성된 연결된 Rowkey를 사용하십시오. 이 경우 "", ""에서 범위 검색을 수행하면 해당 호스트의 모든 항목 중 **가 하나의'get '에 반환됩니다. – javadba

3

가장 먼저해야 할 일은 행키 디자인이 완벽해야 액세스 패턴을 정의 할 수 있다는 것입니다. 당신은 당신이 다음과 같은 방법을 사용할 수있는 경우

선행 acccess 수 rowkeys 알고있는 경우

1) 취득이 좋은, 그것은 결과의 배열을 반환합니다. 우리가 완벽 rowkey 디자인을 해달라고하면 HBase를 스캔 성능과 내 경험에

/** 
    * Method getDetailRecords. 
    * 
    * @param listOfRowKeys List<String> 
    * @return Result[] 
    * @throws IOException 
    */ 
    private Result[] getDetailRecords(final List<String> listOfRowKeys) throws IOException { 
     final HTableInterface table = HBaseConnection.getHTable(TBL_DETAIL); 
     final List<Get> listOFGets = new ArrayList<Get>(); 
     Result[] results = null; 
     try { 
      for (final String rowkey : listOfRowKeys) {// prepare batch of get with row keys 
    // System.err.println("get 'yourtablename', '" + saltIndexPrefix + rowkey + "'"); 
       final Get get = new Get(Bytes.toBytes(saltedRowKey(rowkey))); 
       get.addColumn(COLUMN_FAMILY, Bytes.toBytes(yourcolumnname)); 
       listOFGets.add(get); 
      } 
      results = table.get(listOFGets); 

     } finally { 
      table.close(); 
     } 
     return results; 
    } 

2)

은 조금 낮다. 위에서 언급 한 시나리오에 대한 스캔을 선택하는 것이 좋습니다.

FuzzyRowFilter(see hbase-the-definitive) This is really useful in our case 우리는 같은 대량 클라이언트를 사용했을지도-감소뿐만 아니라 독립 HBase를 클라이언트 행 키에

이 필터 역할을하지만, 퍼지 방식이다. 그것은 리턴되어야하는 행 키 목록과 행 키의 각 Y이트의 중요성을 나타내는 Y이트 [] 배열이 필요합니다. 생성자 등이다

FuzzyRowFilter(List<Pair<byte[], byte[]>> fuzzyKeysData) 

fuzzyKeysData 두 개의 값 중 하나를 취함으로써, 로우 키 바이트의 한 의미를 지정

0 표시하는 행에있는 동일 위치의 바이트 키는 일치해야합니다 ( ). 1 해당 행 키 Y이 이 아니며 항상 허용됨을의 L합니다.

예 : 화합물 키 내부보다는 대체로 왼쪽에서 오른쪽으로 행 주요 부분 매칭 가능한 예는 아니지만, 키 부분과 일치한다. _의 행 키 형식을 고정 길이 파트로 가정 할 때 4는 2이고 4는 2 바이트 길이입니다. 이제 응용 프로그램은 매년 1 월에 특정 작업 (99로 인코딩 됨)을 수행 한 모든 사용자를 요청합니다. 이어서 행 퍼지 키와 데이터의 쌍이 될 다음 "?"

로우 키 "???? 99 _ 01 ????"어디 무시되기 때문에 임의의 문자입니다. 퍼지 데이터 = "\ x01 \ x01 \ x01 \ x01 \ x00 \ x00 \ x00 \ x00 \ x01 \ x01 \ x01 \ x01 \ x00 \ x00 \ x00" 즉, 퍼지 데이터 배열은 "012"가 일치하는 모든 행 키를 찾으십시오. "012"는 "?"0190 " 어떤 문자라도 받아 들일 것입니다.

이 필터의 장점은 일치하는 행 키의 끝에 오는 다음 일치하는 행 키를 계산할 가능성이 높다는 것입니다. 이 메소드는 getNextCellHint() 메소드를 구현하여 서버가 일치 할 수있는 다음 행 범위로 빨리 감기하도록 도와줍니다. 특히 건너 뛴 범위가 상당히 큰 경우 스캔 속도가 빨라집니다. 예제 4-12는 필터를 사용하여 테스트 데이터 세트에서 특정 행을 가져옵니다. 테이블

추가 행 ... 스캔 결과 열 접두사 필터링

List<Pair<byte[], byte[]>> keys = new ArrayList<Pair<byte[], byte[]>>(); 
keys.add(new Pair<byte[], byte[]>(
    Bytes.toBytes("row-?5"), new byte[] { 0, 0, 0, 0, 1, 0 })); 
Filter filter = new FuzzyRowFilter(keys); 

Scan scan = new Scan() 
    .addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")) 
    .setFilter(filter); 
ResultScanner scanner = table.getScanner(scan); 
for (Result result : scanner) { 
    System.out.println(result); 
} 
scanner.close(); 

예 코드는 단지 짧은 출력을 유지하기 위해, 주사에 필터링 열을 추가 :

keyvalues={row-05/colfam1:col-01/1/Put/vlen=9/seqid=0, 
      row-05/colfam1:col-02/2/Put/vlen=9/seqid=0, 
      ... 
      row-05/colfam1:col-09/9/Put/vlen=9/seqid=0, 
      row-05/colfam1:col-10/10/Put/vlen=9/seqid=0} 
keyvalues={row-15/colfam1:col-01/1/Put/vlen=9/seqid=0, 
      row-15/colfam1:col-02/2/Put/vlen=9/seqid=0, 
      ... 
      row-15/colfam1:col-09/9/Put/vlen=9/seqid=0, 
      row-15/colfam1:col-10/10/Put/vlen=9/seqid=0} 

테스트 코드 배선은 row-01에서 row-20까지 20 개의 행을 테이블에 추가합니다. 패턴 row-5에 일치하는 모든 행, 즉 숫자 5로 끝나는 모든 행을 검색하려고합니다. 위 출력은 올바른 결과를 확인합니다.

+0

자세한 답변을 보내 주셔서 감사합니다. 1)의 경우, ROWKEY를 안다면 GET이 좋다는 말을들 수 있습니다. 나도 그래. 약 70000 개의 행에서 GET을 실행하는 데 2 ​​분이 걸리는 이유를 알고 계십니까? 그러나 열 값을 기반으로 ROWKEY를 필터링하는 데는 3 초가 걸립니다. HBase가 열 지향적이기 때문에 이것이 올바른 것이라고 생각했습니다. 그러나 모든 사람들은 GET이 매우 효율적이며'O (1)' –

+0

이라고 말하고 있습니다. 위와 같은 방법으로 일괄 처리 할 때 7000 개의 rowkeys를 전달하면 속도가 빨라집니다. 검색하는 열 값을 기준으로 전체 테이블 스캔을 수행하여 그 값을 찾습니다 (느리지 만 않으면 ...덧붙여 말하자면 모든 행이 같은 지역에 있음) –

+1

엄지 손가락 규칙은 항상 행 기반 액세스 (행 필터)가 열 값 기반 액세스 (열 필터)보다 빠릅니다. –