通过 shell 命令和 mapreduce 扫描 HBase 会给出两种不同的结果

Posted

技术标签:

【中文标题】通过 shell 命令和 mapreduce 扫描 HBase 会给出两种不同的结果【英文标题】:HBase scanning through shell command and mapreduce gives two different rersult 【发布时间】:2014-10-02 06:20:23 【问题描述】:

我有 HBase 表,它有超过十亿条记录。当我使用某些 ValueFilter 查询扫描 HBase 表时,我得到 41820 条记录,但是给出结果需要超过 35 分钟,但是当我使用 mapreduce 程序扫描同一个 HBase 表时,我在 2 分钟内得到了计数但给了我41035 条记录。我不知道。

这是我使用的 shell 命令:

scan 'permhistory', COLUMNS => 'h:e_source', FILTER => "ValueFilter( =, 'binaryprefix:AC_B2B' )"

结果:41820

这是 mapreduce 中的 Scan 对象:

    Scan scan = new Scan();
    scan.setCaching(2000);
    scan.setCacheBlocks(false);
    scan.addFamily(Bytes.toBytes("h"));
    scan.addColumn(Bytes.toBytes("h"), Bytes.toBytes("e_source"));
    SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("h"),
                    Bytes.toBytes("e_source"),CompareOp.EQUAL,Bytes.toBytes("AC_B2B"));
    filter.setLatestVersionOnly(false);
    scan.setFilter(filter);

有什么想法吗?这是我在这里的第一篇文章。各位高手,能帮帮我吗?我有点坚持自动化我们的系统

【问题讨论】:

【参考方案1】:

在 mapreduce 中你正在使用这个构造函数

public SingleColumnValueFilter(byte[] family,
                       byte[] qualifier,
                       CompareFilter.CompareOp compareOp,
                       byte[] value)

这意味着您使用默认比较器实例化过滤器,但在您使用的 hbase shell 中

"ValueFilter( =, 'binaryprefix:AC_B2B' )"

二进制前缀比较器,所以你应该试试这个

SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("h"),
                    Bytes.toBytes("e_source"),
                    CompareOp.EQUAL,
                    new BinaryPrefixComparator(Bytes.toBytes("AC_B2B")));

此外,在 hbase shell 中您使用 ValueFilter,而在 mapreduce 中您使用 SingleColumnValueFilter。供您参考:

单列值过滤器

此过滤器用于根据值过滤单元格。它需要一个 CompareFilter.CompareOp 运算符(等于、大于、不等于等),以及 字节 [] 值或 ByteArrayComparable。如果我们有一个字节 [] value 那么我们只是做一个字典比较。例如,如果通过 值是'b'并且单元格有'a'并且比较运算符是LESS,然后 我们将过滤掉这个单元格(返回真)。如果这还不够 (例如,您想反序列化一个 long,然后将其与固定的 long 进行比较 value),然后你可以传入你自己的比较器。

您还必须指定族和限定符。只有这个值 列将被测试。在指定的扫描上使用此过滤器时 输入,要测试的列也应添加为输入 (否则过滤器会认为该列缺失)。

如果列不存在,则防止发出整行 在一行中找到,使用 setFilterIfMissing(boolean)。否则,如果 找到列,仅当值时才会发出整行 通过。如果值失败,该行将被过滤掉。

值过滤器

此过滤器用于根据列值进行过滤。它需要一个 运算符(等于、大于、不等于等)和一个字节 [] 比较器 单元格值。

在这种情况下,由于您专门设置了要扫描的列,因此它的行为方式相同。 ValueFilter 将过滤所有列,SingleColumnValueFilter 将仅过滤特定列,如果未通过过滤器,则完全忽略该行。

【讨论】:

以上是关于通过 shell 命令和 mapreduce 扫描 HBase 会给出两种不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

如何在shell脚本中执行cd命令

shell调用mapreduce结束后无法获取结束状态

mapreduce、hbase 和扫描

如何将 HBase 的扫描限制在 MapReduce 作业的相关(未过滤)区域

针对不同映射器的 HBase MapReduce 拆分扫描

Linux下nmap扫描端口shell脚本