Hbase 数据模型

1.Hbase数据模型

Table: 一个HBase表由多行组成;

Row:

HBase中的一行包含一个Row-key和一个或多个与其相关的值的列。在存储行时,行按字母顺序排序。出于这个原因,row key的设计非常重要。目地是以相关行相互靠近的方式存储数据。与 NoSQL 数据库一样,Row Key 是用来检索记录的主键。

Column:

HBase中的列由一个列族和一个列限定符 (column qualifier)组成,它们由:(冒号)字符分隔。

列族 (Column Family)

HBase 表中的每个列都归属于某个列族。列族是表的 Schema 的一部分,必须在使用表之前定义。列名都以列族作为前缀,例如 courses:history、courses:math 都属于 courses 这个列族。 每个列族都有一组存储属性,例如其值是否应缓存在内存中,数据如何压缩或其行编码是如何编码的等等。表中的每一行都有相同的列族,但给定的行可能不会在给定的列族中存储任何内容。

列限定符 (column qualifier)

列限定符被添加到列族以提供给定数据的索引。鉴于列族内容,列限定符可能是content:html,另一个可能是content:pdf。表中的每一行都有相同的列族,但每行的列限定符是可变的,并且行与行之间可能差别很大。

Cell

单元格是行,列族和列限定符的组合,并且包含值和时间戳,它表示值的版本。Cell 中的数据是没有类型的,全部是字节码形式存储。每个 Cell 都保存着同一份数据的多个版本。 

时间戳

时间戳与每个值一起编写,是给定版本的值的标识符。默认情况下,时间戳表示写入数据时RegionServer上的时间,但可以在将数据放入单元格时指定不同的时间戳值。版本通过时间戳来索引,时间戳的类型是 64 位整型。时间戳可以由HBase(在数据写入时自动)赋值, 

此时时间戳是精确到毫秒的当前系统时间。时间戳也 可以由客户显示赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个 Cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。

为了避免数据存在过多版本造成的管理(包括存储和索引)负担,HBase 提供了两种数据版本回收方式。 一是保存数据的最后 n 个版本,二是保存最近一段时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。

如上所示,HBase 以表的形式存储数据。表由行和列组成。列划分为若干个列族(dolumn family),如下图所示:

1542117015705292.png

2. HBase的逻辑数据模型

通过下面一个示例,来阐述Hbase 的表是如何实现逻辑存储的。有一个名为webtable的表格,其中包含两行(com.cnn.www和com.example.www)和三个名为content,anchor和people的列族。 对于第一行(com.cnn.www),anchor包含两列(anchor:cssnsi.com,anchor:my.look.ca),content包含一列(contents:html)。 本示例包含具有row key 为com.cnn.www的行有5个版本,具有row key 为com.example.www的行有一个版本。 content:html列限定符包含给定网站的整个HTML。 Anchor column family包含链接到该行所代表的站点的外部站点。如下图所示:

1542117117749860.png

注意: HBase表中,显示为空的单元格不占用空间, 这就是Hbase 存储时,数据稀疏性的表现。

3. HBase的物理数据模型

上述Hbase逻辑视图含有一组稀疏的行,但是在Hbase中,它们是按列族物理存储的,并且随时可以将新的列限定符(column_familycolumn_qualifier)添加到现有的列族。Anchor 表如下:

1542117220705630.png

Content 表如下:

1542117281603441.png

逻辑数据模型中空白cell在物理上是不存储的。 因此,在时间戳t8处请求content:html列的值将不返回任何值。 同样,在时间戳t9请求anchor:my.look.ca值也不会返回任何值。 但是,如果未提供时间戳,则会返回特定列的最新值。 如果存在多个版本,最近的也是第一个找到的,时间戳按降序存储。 

4. 数据模型 Operation

HBase四个主要的数据模型操作是Get,Put,Scan和Delete。 操作通过Table 类来进行。具体可参见 https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/Table.html 详细了解,下面给出一些示例:

Get

获取指定行的返回值。 获取通过Table.get执行。以下get将只检索行的当前版本:

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Get get = new Get(Bytes.toBytes("row1"));
Result r = table.get(get);
byte[] b = r.getValue(CF, ATTR);  // returns current version of value

Put

Put可以将新行添加到表中或者可以更新现有行。 通过Table.put(non-writeBuffer)或Table.batch(non-writeBuffer)来执行PUT.

下面Put示例明确设置的版本时间戳,代码如下:

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Put put = new Put( Bytes.toBytes(row));
long explicitTimeInMs = 555;  // just an example
put.add(CF, ATTR, explicitTimeInMs, Bytes.toBytes(data));
table.put(put);

Scan

Scan允许对指定属性的多行进行迭代。如下Scan table的示例。 假设一个表中具有row key为“row1”,“row2”,“row3”的行,也包含 row key  为“abc1”,“abc2”和“abc3”的另一组行,代码显示如何设置Scan实例以返回以“row”开头的行:

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Table table = ...      // instantiate a Table instance
Scan scan = new Scan();
scan.addColumn(CF, ATTR);
scan.setRowPrefixFilter(Bytes.toBytes("row"));
ResultScanner rs = table.getScanner(scan);
try {
  for (Result r = rs.next(); r != null; r = rs.next()) {
    // process result...
  }
} finally {
  rs.close();  // always close the ResultScanner!
}

Delete

Delete从表中删除行。 通过Table.delete执行,有三种不同类型的内部Delete标记:

? 删除:针对特定版本的列;

? 删除列:针对所有版本的列;

? 删除列族:针对特定ColumnFamily的所有列;

当删除整行时,HBase将为每个ColumnFamily(不是每个单独的列)创建一个逻辑删除(tombstone)。

通过创建逻辑删除标记(tombstone)来标注要删除的数据。例如,假设要删除一行,可以指定一个版本,否则默认使用currentTimeMillis。这意味着删除版本小于或等于此版本的所有单元格。 HBase从不修改数据,删除并不会立即删除存储文件中对应于删除条件的数据,而会创建一个删除标记的tombstone,当HBase进行数据压缩时,Hbase会移除标记为tombstone的值。 如果在删除行时指定的版本大于行中任何值的版本,则可以考虑删除整行。

5 .排序顺序

所有数据模型的操作,HBase以排序的顺序返回数据。首先按行,然后按ColumnFamily,然后是列限定符,最后是时间戳,最新的记录会首先返回。

6. 列元数据

ColumnFamily的内部KeyValue实例之外不存储列元数据,如列限定符的名称,尽管HBase支持每行大量的列,还可以支持行之间的异构列,但用户需要自己跟踪列名。如果需要获得ColumnFamily存在的一组完整列,唯一的方法是遍历所有的行。

 

7 . Join 级联Operation

Hbase 不支持类似于关系型数据库中的 Join 操作,如在RDBMS中的SQL内🔗 连接或外连接等。 HBase中读取的数据模型操作是Get和Scan。这并不意味着应用程序不支持等效的连接功能,在Hbase 中,实现类似操作 必须自己实现。两个主要策略是在写入HBase时对数据进行非规格化,或者在应用程序或MapReduce代码中使用查找表并进行HBase表之间的连接。

Hbase 数据模型

发表评论

邮箱地址不会被公开。 必填项已用*标注

六 × = 12

滚动到顶部