• Hbase 之KeyValue结构详解


    源码

    在这里插入图片描述

    • 源码注释部分翻译
    HBase 键值。这是基本的 HBase 类型。
    
    KeyValue 包装一个字节数组,并将偏移量和长度放入传递的数组中,从哪里开始将内容解释为 KeyValue。
    字节数组中的 KeyValue 格式为: <keylength> <valuelength> <key> <value> 
    Key 进一步分解为: <rowlength> <row> <columnfamilylength> <columnfamily> <columnqualifier> <timestamp> <keytype> 
    行长最大值为 Short.MAX_SIZE,
    列族长度最大值为 Byte.MAX_SIZE,
    列限定符 + 键长度必须 < Integer.MAX_SIZE。
    该列不包含 familyqualifier 分隔符 COLUMN_FAMILY_DELIMITER
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    KeyValue结构

    在这里插入图片描述

    • 在KeyValue中,其中的KeyLength为4B:
    • ValueLength标识Value在字节数组中所占的长度,为4B:
    • Row Length:存储rowkey的长度,为2B
    • TimeStamp是Long型,肯定就是占8B:
    • KeyType为1B:

    从ColumnQualifier开始内容前面不在带有长度了。TimeStamp和KeyType因为所占的长度是固定的,所以不用包含长度信息。而Qualifier的长度信息,则用以下的方式可以得出:

    new Ordering[(ImmutableBytesWritable, KeyValue)] {
          override def compare(x: (ImmutableBytesWritable, KeyValue), y: (ImmutableBytesWritable, KeyValue)): Int = {
            x._2.getFamilyLength()
            x._2.getQualifierLength
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    KeyValue的实现

    Hbase中,所有数据都是以Byte的形式存在的。在KeyValue中,使用的是byte数组来存储实际内容。

     // KeyValue core instance fields.
      private byte [] bytes = null;  // an immutable byte array that contains the KV
      private int offset = 0;  // offset into bytes buffer KV starts at
      private int length = 0;  // length of the KV starting from offset.
    
    • 1
    • 2
    • 3
    • 4

    其中,bytes数组用来存储KeyValue中的实际内容,offset表示KeyValue在数组bytes中的起始位置length则是KeyValue在数组bytes中自起始位置offset后的长度

    KeyValue提供了一系列的Offset方法在数组中定位各个字段的的起始位置,如getValueOffset,getRowOffset等。也提供了一系列的length方法来获取KeyValue中各个字段的大小。


    操作KeyValue

    把keyValue 数据取出放到Map里

     Map<String, Object> stringMap = new HashMap<>();
     stringMap.put("row", Bytes.toStringBinary(getRowArray(), getRowOffset(), getRowLength()));
     stringMap.put("family",Bytes.toStringBinary(getFamilyArray(), getFamilyOffset(), getFamilyLength()));
     stringMap.put("qualifier",Bytes.toStringBinary(getQualifierArray(), getQualifierOffset(), getQualifierLength()));
     stringMap.put("timestamp", getTimestamp());
     stringMap.put("vlen", getValueLength());
     Iterator<Tag> tags = getTags();
     if (tags != null) {
      List<String> tagsString = new ArrayList<String>();
      while (tags.hasNext()) {
       tagsString.add(tags.next().toString());
      }
      stringMap.put("tag", tagsString);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    elasticsearch 8.X新特性
    diff算法原理解析
    steam搬砖项目,csgo游戏搬砖熟练操作后,可以月入过万~
    JNI 使用案例详解(一)
    优盘格式化了怎么恢复里面的数据?
    【活动回顾】Rust:构建新时代基础设施的首选语言 @Qcon
    Cut-Off Wavelength in fiber(光纤的截止波长)
    Mysql(库操作)
    毕业设计 基于stm32的智能平衡小车 - 单片机 物联网嵌入式
    C语⾔内存函数
  • 原文地址:https://blog.csdn.net/Lzx116/article/details/126609986