- 如何标识一个cell?
- cell tag的设计
- HBase 2.3支持的cell tag种类
- 如何添加和获取cell的tag?
- 添加cell tag
- 获取cell tag
- cell tag和column family attribute的优先级
在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的具体内容。设计如下所示:
此外,每个cell可以包含多组tag,我们对tag array进行进一步细分,可以得到每组tag的数据结构。
<2 byte tag length><1 byte type code>
在HBase 2.3版本中,Cell接口类实现了以下三种方法,帮助外部客户端获取cell的tag。当然这些方法在HBase 2版本中已经被置为deprecated状态,并将在HBase 3中被删除。
@Deprecated byte[] getTagsArray(); @Deprecated int getTagsOffset(); @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(cell tag和column family attribute的优先级)); Result rs = table.get(get); if (rs!=null) { Cell cell = rs.getColumnCells(..); Iterator 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); } } }
默认情况下,HBase不会对cell设置任何tag,因此加入该cell所在的column family设置的attribute会对该cell生效。当cell显式设定了tag之后,cell tag的优先级会高于column family attribute的优先级。



