HBase如何知道某行是否包含特定列?例如,考虑以下情况:
假设我们有一个包含一个名为“STAT_FAM”的列族的表,其中包含以下两行:
现在,如果我们正在扫描表格,扫描定义如下:
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”的列,那么它是否必须通过该行的完整记录来确定该行不包含所需的列?
提前致谢!
答案 0 :(得分:2)
让我们先了解HBase如何存储它的数据。
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具有内存高效的文件格式。但并不保证在所有行中查找。
它的证明检查每一行都在这里。
类名: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