HBase Cell Tag介绍


在HBase 0.98版本之后,HBase引入了一种额外的元数据(meta data)——tag来标识一个cell( HBASE-8496)。本文就主要介绍一下什么是cell tag。

如何标识一个cell?

首先,先来介绍一下HBase是如何来定位一个cell的。HBase通过以下几个要素来定位一个cell:表(table),行(rowkey),列族(column family),列标识(column qualifier),时间戳(timestamp)。这存在的一个问题是,无法对每个cell单独进行细粒度的参数设置,比如无法对某个cell设置TTL,无法对某个cell设置ACL,无法对某个cell设置visibility。对于cell的所有设置必须都是基于行或者列进行的。

cell tag的设计

为了解决以上的问题,HBase 0.98版本之后,引入了HBase cell tag这一设计。首先,重新设计了HFile,将HFile的版本升级到了version 3。HFileV3兼容了之前的HFile版本,只是在key-value存储结构之后增加了tag length和tags array两端。tag length标明了tag array的长度,tag array则是tag的具体内容。设计如下所示:

<keylength><valuelength><keyarray><valuearray><taglength><tagarray>

此外,每个cell可以包含多组tag,我们对tag array进行进一步细分,可以得到每组tag的数据结构。

<2 byte tag length><1 byte type code><tag>

在HBase 2.3版本中,Cell接口类实现了以下三种方法,帮助外部客户端获取cell的tag。当然这些方法在HBase 2版本中已经被置为deprecated状态,并将在HBase 3中被删除。

  /**
   * Contiguous raw bytes representing tags that may start at any index in the containing array.
   * @return the tags byte array
   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. Tags are are now internal.
   */
  @Deprecated
  byte[] getTagsArray();

  /**
   * @return the first offset where the tags start in the Cell
   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. Tags are are now internal.
   */
  @Deprecated
  int getTagsOffset();

  /**
   * HBase internally uses 2 bytes to store tags length in Cell.
   * As the tags length is always a non-negative number, to make good use of the sign bit,
   * the max of tags length is defined 2 * Short.MAX_VALUE + 1 = 65535.
   * As a result, the return type is int, because a short is not capable of handling that.
   * Please note that even if the return type is int, the max tags length is far
   * less than Integer.MAX_VALUE.
   *
   * @return the total length of the tags in the Cell.
   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. Tags are are now internal.
   */
  @Deprecated
  int getTagsLength();

HBase 2.3支持的cell tag种类

根据HBase 2.3 TagType类代码所示,HBase当前支持7种Tag,用户可以从客户端显式设定cell的ACL,TTL,Visibility等属性。

public final class TagType {
  // Please declare new Tag Types here to avoid step on pre-existing tag types.
  public static final byte ACL_TAG_TYPE = (byte) 1;
  public static final byte VISIBILITY_TAG_TYPE = (byte) 2;
  // public static final byte LOG_REPLAY_TAG_TYPE = (byte) 3; // deprecated
  public static final byte VISIBILITY_EXP_SERIALIZATION_FORMAT_TAG_TYPE = (byte)4;

  // mob tags
  public static final byte MOB_REFERENCE_TAG_TYPE = (byte) 5;
  public static final byte MOB_TABLE_NAME_TAG_TYPE = (byte) 6;

  // String based tag type used in replication
  public static final byte STRING_VIS_TAG_TYPE = (byte) 7;
  public static final byte TTL_TAG_TYPE = (byte)8;
}

如何添加和获取cell的tag?

在默认情况下,HBase不会为cell添加任何tag,并且目前HBase shell客户端也不支持添加和获取cell tag。因此,假如我们需要单独为某个cell添加tag,或者获取某个cell tag的时候,必须通过HBase Java客户端进行。

添加cell tag

我们以设定cell TTL tag为例,如下所示,在创建put对象的时候,只需要调用setTTL方法即可对这个put对象中的所有cell设置TTL。

Put putExample = new Put("rowkey".getBytes())
	.addColumn("columnfamily".getBytes(), "column qualifier".getBytes(), "value".getBytes());
putExample.setTTL(TTL_time);
table.put(putExample);

获取cell tag

当我们创建get请求获取HBase result之后,可以通过如下代码获取cell的tag。

Get get = new Get(Bytes.toBytes(<key>));
Result rs = table.get(get);
if (rs!=null) {
	Cell cell = rs.getColumnCells(..);
	Iterator<Tag> i = CellUtil.tagsIterator(cell.getTagsArray(), cell.getTagsOffset(), cell.getTagsLength());
	while (i.hasNext()) {
		Tag t = i.next();
		if (TagType.TTL_TAG_TYPE == t.getType()) {
			long ts = cell.getTimestamp();
			assert t.getTagLength() == Bytes.SIZEOF_LONG;
			long ttl = Bytes.toLong(t.getBuffer(), t.getTagOffset(), t.getTagLength());
			System.out.println(ttl);
		}
	}
}

cell tag和column family attribute的优先级

默认情况下,HBase不会对cell设置任何tag,因此加入该cell所在的column family设置的attribute会对该cell生效。当cell显式设定了tag之后,cell tag的优先级会高于column family attribute的优先级。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值