2012-06-07 2 views
0

HBase 테이블에서 각 행에는 크롤링 식별자라는 열이 있습니다. MapReduce 작업을 사용하여 주어진 크롤링의 행을 한 번에 처리하기를 원합니다. 작업을보다 효율적으로 실행하기 위해 검색 개체에 주어진 크롤링 식별자가있는 행을 제외하고 모든 행을 제거하는 필터를 제공했습니다. 그러나 우리는 작업이 정확한 행 수를 처리하지 못한다는 것을 빨리 알았습니다. SingleColumnValueFilter가 적절한 행 수를 반환하지 않음

나는 어떤 필터없이, 단순히 올바른 크롤링 식별자 행의 수를 계산하기 위해 테스트 매퍼를 썼다. 그것은 테이블의 모든 행을 반복하고 예상되는 행 수 (~ 15000)를 계산합니다. 동일한 작업을 수행 할 때 검색 개체에 필터를 추가하면 개체 수가 3000 개로 줄어 들었습니다. 이 두 작업 사이 또는 사이에 테이블 자체의 조작이 없었습니다. 검색 필터를 추가하는 것은 눈에 보이는 행이 극적으로 변하게 때문에

, 우리는 우리가 단순히 잘못 필터를 내장 기대합니다.

public static class RowCountMapper extends TableMapper<ImmutableBytesWritable, Put>{ 

    public String crawlIdentifier; 

    // counters 
    private static enum CountRows { 
     ROWS_WITH_MATCHED_CRAWL_IDENTIFIER 
    } 

    @Override 
    public void setup(Context context){ 
     Configuration configuration=context.getConfiguration(); 
     crawlIdentifier=configuration.get(ConfigPropertyLib.CRAWL_IDENTIFIER_PROPERTY); 

    } 

    @Override 
    public void map(ImmutableBytesWritable legacykey, Result row, Context context){ 
     String rowIdentifier=HBaseSchema.getValueFromRow(row, HBaseSchema.CRAWL_IDENTIFIER_COLUMN); 
     if (StringUtils.equals(crawlIdentifier, rowIdentifier)){ 
      context.getCounter(CountRows.ROWS_WITH_MATCHED_CRAWL_IDENTIFIER).increment(1l); 
     } 
    } 
} 

필터 설정은 다음과 같이이다 :

String crawlIdentifier=configuration.get(ConfigPropertyLib.CRAWL_IDENTIFIER_PROPERTY); 
if (StringUtils.isBlank(crawlIdentifier)){ 
    throw new IllegalArgumentException("Crawl Identifier not set."); 
} 

// build an HBase scanner 
Scan scan=new Scan(); 
SingleColumnValueFilter filter=new SingleColumnValueFilter(HBaseSchema.CRAWL_IDENTIFIER_COLUMN.getFamily(), 
    HBaseSchema.CRAWL_IDENTIFIER_COLUMN.getQualifier(), 
    CompareOp.EQUAL, 
    Bytes.toBytes(crawlIdentifier)); 
filter.setFilterIfMissing(true); 
scan.setFilter(filter); 

우리가 잘못된 필터를 사용하고, 또는 우리가 잘못 설정 한

우리의 맵리 듀스 작업이 하나의 매퍼 기능?

편집 : 우리가 직접보고 https://issues.apache.org/jira/browse/HBASE-2198에 따라 모든 열 가족을 추가하지만 스캔은 기본적으로 모든 가족을 포함 확신하고 있습니다.

+0

당신은 또한 수동으로 필터링을 한있는 원래 매퍼를 게재 할 수 있습니까? –

+0

그것은 동일한 매퍼였습니다. 유일한 차이점은 내가 두 번째 코드 블록에서 스캔 객체에 필터를 할당하지 않았다는 것입니다. 물론 수동 필터링이라고하는 것은 map() 메소드의 if() 블록입니다. – whiterook6

+0

@ whiterook6 - 혹시이 문제를 해결 했습니까? thx – hba

답변

0

필터는 올바른 보이지만, 특정 조건에서 발생할 수있는 하나 개의 시나리오는이 문자 인코딩에 관한 것이다. 필터는 Bytes.toBytes을 사용하고 UTF8을 사용합니다 (문자열) [1], 반면에 당신 수도 HBaseSchema에 기본 문자 인코딩을 사용하거나하는 String.getBytes를 (사용하는 경우) 기록을 작성할 때 [2]. crawlIdentifier가 원래 HBase에 작성되었는지 확인하려면 다음을 사용하여 필터가 필터링 된 검색과 유사하게 비교되는지 확인하십시오.

Bytes.toBytes(crawlIdentifier) 

[1] http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/util/Bytes.html#toBytes(java.lang.String) [2] http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#getBytes()

+0

얼마 전에이 문제와 관련된 버그를 발견했습니다. 우리는 String.toBytes()를 찾는 코드를 불 태워서 모두 바꿉니다. 크롤링 식별자를 작성하는 코드가 올바르게 작성되었습니다. – whiterook6

관련 문제