HBase:HBase如何知道某行是否包含特定列

时间:2015-06-26 19:44:28

标签: hbase

HBase如何知道某行是否包含特定列?例如,考虑以下情况:

假设我们有一个包含一个名为“STAT_FAM”的列族的表,其中包含以下两行:

  • 一行,键“R1”,包含1000列,名为S1到S1000。
  • 另一行带有“R2”键,其中包含另外1000列,从S2000到S3000。

现在,如果我们正在扫描表格,扫描定义如下:

Scan s = new Scan();
s.setStartRow ( Bytes.toBytes(“R1”) );
s.setStopRow ( Bytes.toBytes(“R2”) );
s.addColumn( STAT_FAM, Bytes.toBytes(“S500”) );
s.addColumn( STAT_FAM, Bytes.toBytes(“S2500”) );

当HBase根据rowkey进行扫描时,它会将记录定位在特定区域服务器上的特定文件中。一旦找到,它如何找到行数据中的特定列?

对于行“R1”,没有名为“S2500”的列,那么它是否必须通过该行的完整记录来确定该行不包含所需的列?

提前致谢!

1 个答案:

答案 0 :(得分:2)

让我们先了解HBase如何存储它的数据。 HFile format

Hfile的KeyValue包含:

<keylength> <valuelength> <key> <value>

Key被分解为:

<rowlength> <row> <columnfamilylength> <columnfamily> <columnqualifier> <timestamp> <keytype>

将一起

<keylength> <valuelength> <key> <rowlength> <row> <columnfamilylength> <columnfamily> <columnqualifier> <timestamp> <keytype> <value>

HBase是“以列为导向的系列。”数据实际存储在列族系列中。这意味着给定列族的所有键值都存储在同一组文件中。

HBase不提供任意列的索引,没有连接,也没有多行事务。如果您想根据其列值查询行,则最好为其维护二级索引,或者为全表扫描做好准备

较新版本的Hbase HFile具有内存高效的文件格式。但并不保证在所有行中查找。

HFile V2 Diff encoding

它的证明检查每一行都在这里。

类名:org.apache.hadoop.hbase.filter.SingleColumnValueFilter

if (!keyValue.matchingColumn(this.columnFamily, this.columnQualifier)) {
      return ReturnCode.INCLUDE;
    }

if (filterColumnValue(keyValue.getBuffer(), keyValue.getValueOffset(), keyValue.getValueLength())) {
      return this.latestVersionOnly? ReturnCode.NEXT_ROW: ReturnCode.INCLUDE;
}

来自此方法的 org.apache.hadoop.hbase.KeyValue 类。

  /**
   *
   * @param family column family
   * @param qualifier column qualifier
   * @return True if column matches
   */
  public boolean matchingColumn(final byte[] family, final byte[] qualifier) {
    int rl = getRowLength();
    int o = getFamilyOffset(rl);
    int fl = getFamilyLength(o);
    int ql = getQualifierLength(rl,fl);
    if (!Bytes.equals(family, 0, family.length, this.bytes, o, fl)) {
      return false;
    }
    if (qualifier == null || qualifier.length == 0) {
      if (ql == 0) {
        return true;
      }
      return false;
    }
    return Bytes.equals(qualifier, 0, qualifier.length,
        this.bytes, o + fl, ql);
  }


Image credit: Cloudera-blog