【问题标题】:SingleColumnValueFilter not returning proper number of rowsSingleColumnValueFilter 没有返回正确的行数
【发布时间】:2012-06-11 17:58:23
【问题描述】:

在我们的 HBase 表中,每一行都有一个名为 crawl identifier 的列。使用 MapReduce 作业,我们只想随时处理给定爬网中的行。为了更有效地运行作业,我们为扫描对象提供了一个过滤器,(我们希望)将删除除具有给定爬网标识符的行之外的所有行。但是,我们很快发现我们的作业处理的行数不正确。

我编写了一个测试映射器来简单地计算具有正确爬网标识符的行数,没有任何过滤器。它遍历表中的所有行并计算正确的预期行数(~15000)。当我们做同样的工作,为扫描对象添加一个过滤器时,计数下降到约 3000。在这两个工作期间或之间没有对表本身进行任何操作。

由于添加扫描过滤器导致可见行发生如此巨大的变化,我们预计我们只是错误地构建了过滤器。

我们的 MapReduce 作业具有单个映射器:

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 手动添加所有列族,但我很确定扫描默认包含所有族。

【问题讨论】:

  • 您能否也显示您手动进行过滤的原始映射器?
  • 是同一个映射器;唯一的区别是我没有为扫描对象分配过滤器(在第二个代码块中)。当然,您所说的手动过滤只是 map() 方法中的 if() 块。
  • @whiterook6 - 你解决过这个问题吗?谢谢
  • 对不起,我不知道。这差不多是两年前的事了。我不记得了。

标签: filter mapreduce hbase


【解决方案1】:

过滤器看起来是正确的,但在某些情况下,可能导致这种情况的一种情况与字符编码有关。您的过滤器正在使用使用 UTF8 [1] 的 Bytes.toBytes(String),而您可能在 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()

【讨论】:

  • 不久前我们确实发现了一个与这个问题相关的错误。我们烧了一大段代码来寻找 String.toBytes() 并将它们全部替换。编写爬虫标识符的代码是正确的。
猜你喜欢
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
相关资源
最近更新 更多