专栏首页实时计算Hbase入门(三)——数据模型

Hbase入门(三)——数据模型

Hbase最核心但也是最难理解的就是数据模型,由于与传统的关系型数据库不同,虽然Hbase也有表(Table),也有行(Row)和列(Column),但是与关系型数据库不同的是Hbase有一个列族(Column Family)的概念,它将一列或者多列组织在一起,HBase必须属于某一个列族。

行和列交叉点称为单元格(Cell),单元格时版本化的。单元格的内容,也就是列的值是不可分割的字节数组。

HBase没有数据类型,任何列值都被转换成字节数组进行存储。

HBase表中的行是通过行键(Rowkey)进行区分的。行键也是用来唯一确定一行的标识。

HBase中的行按Rowkey排序,排序方式采用字典顺序。

这些都是HBase的逻辑结果,他的物理结构也和传统关系型数据库有很大不同。

逻辑模型

HBase的逻辑模型源自Google的BigTable模型。可以理解为一个稀疏的,长期存储的,多维度的和排序的映射表。

以下示例是 BigTable 论文第 2 页上的一个略微修改的形式。有一个名为webtable的表包含两行(com.cnn.wwwcom.example.www)和三个列族,名为contentsanchorpeople

在此示例中,对于第一行(com.cnn.www),anchor包含两列(anchor:cssnsi.comanchor:my.look.ca),contents包含一列(contents:html)。此示例包含具有行键com.cnn.www的行的 5 个版本,以及具有行键com.example.www的行的一个版本。 contents:html列限定符包含给定网站的整个HTML。 anchor列族的限定符每个都包含指向该行所代表的站点的外部站点的链接,以及它在其链接的anchor中使用的文本。 people列系列表示与该站点关联的人员。

此表中看起来为空的单元格在 HBase 中不占用空间,或实际上不存在。这就是HBase“稀疏”的原因。表格视图不是查看 HBase 中数据的唯一方法,甚至也不是最准确的方法。以下表示与多维映射相同的信息。这只是一个出于演示目的的模型,可能并不完全准确。

{
  "com.cnn.www": {
    contents: {
      t6: contents:html: "<html>..."
      t5: contents:html: "<html>..."
      t3: contents:html: "<html>..."
    }
    anchor: {
      t9: anchor:cnnsi.com = "CNN"
      t8: anchor:my.look.ca = "CNN.com"
    }
    people: {}
  }
  "com.example.www": {
    contents: {
      t5: contents:html: "<html>..."
    }
    anchor: {}
    people: {
      t5: people:author: "John Doe"
    }
  }
} 

物理模型

虽然Hbase表可以看作一组稀疏的行,但在物理意义上它们是按照列族存储的。所以列是可以随时添加的。

Hbase是面向列的,存放行的不同列的物理文件,一个列族存放在多个HFile中,最重要的是一个列族的数据会被同一个Region管理。

空单元格不占据物理存储空间。因此,在时间戳t8处对contents:html列的值的请求将不返回任何值。类似地,在时间戳t9处对anchor:my.look.ca值的请求将不返回任何值。但是,如果未提供时间戳,则将返回特定列的最新值。给定多个版本,最新版本也是第一个版本,因为时间戳按降序存储。因此,如果没有指定时间戳,则对行com.cnn.www中所有列的值的请求将是:来自时间戳t6contents:html的值,来自时间戳t9anchor:cnnsi.com的值,来自时间戳t8anchor:my.look.ca

数据模型操作

四个主要的数据模型操作是 Get,Put,Scan 和 Delete。通过实例化Table进行操作。

版本问题: Rowkey、Column(列族和列)、Version组合在一起称为Hbase中的一个单元格。

Rowkey和Column的值是用字节数组表示的,Version则是用一个长整型表示的。

Get

操作返回指定行的属性,Get是在Scan基础上实现的。在默认情况下,如果没有指定版本,一旦使用Get操作,会返回最近版本的Cell。

要返回多个版本,需要设置Get.setMaxVersions()

要返回最新版本以外的其他版本,请参见 Get.setTimeRange()

默认版本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 

给定版本的Get示例

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Get get = new Get(Bytes.toBytes("row1"));
get.setMaxVersions(3);  // will return last 3 versions of row
Result r = table.get(get);
byte[] b = r.getValue(CF, ATTR);  // returns current version of value
List<KeyValue> kv = r.getColumn(CF, ATTR);  // returns all versions of this column 

PUT

执行 put 总是在某个时间戳创建cell的新版本。默认情况下,系统使用服务器的currentTimeMillis,但您可以在针对每一列指定版本(=长整数)。这意味着您可以在过去或将来指定时间,或者将long值用于非时间目的。

隐式版本示例

HBase 将使用当前时间隐式地对以下 Put 进行版本控制。

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Put put = new Put(Bytes.toBytes(row));
put.add(CF, ATTR, Bytes.toBytes( data));
table.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); 

DELETE

删除通过 Table.delete]执行。

有三种不同类型的内部删除标记。

  • 删除:对于特定版本的列。
  • 删除列:适用于列的所有版本。
  • 删除系列:适用于特定 ColumnFamily 的所有列

SCAN

扫描表

下面是对表进行扫描的示例。假设一个表填充了具有键“row1”,“row2”,“row3”的行,然后另一组是具有键“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!
} 

更多实时计算,Hbase,Flink,Kafka等相关技术博文,欢迎关注实时流式计算

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用Python爬虫下载整本小说

    如今网络上很多小说网站都有免费的小说阅读,但是它不提供下载全本的服务,目的也是为了获得更多的流量,资源君就不服了,今天刚好看到一个小说网站,就想弄本小说来看看,...

    JAVAandPython君
  • 《中餐厅》弹幕数据分析,我不要你觉得,我只要我觉得!

    这段时间奇怪了,周围朋友都爱上了同一个口头禅“我不要你觉得,我只要我觉得”;我就纳闷了汉语文字那么多,你们偏偏都爱上了同一句,我怀疑他们在玩梗,果不其然,在B站...

    小小詹同学
  • 一种基于proxysql的数据脱敏思路

    背景:我们这边给研发查数据的是通过phpmyadmin进行的,通常情况下研发人员查数据写法是 select * from db1.tb1 where id=xx...

    二狗不要跑
  • 接口爬虫之网页表单数据提取

    本人最近接到一项任务,要爬一项数据,这个数据在某个网页的表格里面,数据量几百。打开调试模式发现接口返回的就是一个html页面,只要当做string处理。(解析h...

    八音弦
  • Java SPI机制浅析

    在平时开发项目的过程中,相信很多读者都看到过这样的目录,/META-INF/services目录,该目录下的文件名是接口的全称,其内容是具体的接口实现。这就是使...

    孟君
  • 资源君带你抓取网站数据

    这是公众号Java模板(跟资源君一起学Java)的第一篇推文,资源君创建这个模板也是为了监督自己不断的学习,并且不断的跟大家一起分享编程当中的一些好...

    JAVAandPython君
  • Pandas常见的性能优化方法

    Pandas是数据科学和数据竞赛中常见的库,我们使用Pandas可以进行快速读取数据、分析数据、构造特征。但Pandas在使用上有一些技巧和需要注意的地方,如果...

    石晓文
  • 如何检测遗传相关的显著性:LRT检验操作方法

    3. 软件实现遗传相关计算 3.1 数据格式 前三列是系谱,有3个性状: y1, y2, y3 , 想要计算y1和y3的遗传相关,并用LRT检验显著性

    邓飞
  • PG Logical Replication 逻辑复制

    我下面演示的PG环境是单机多实例的方式部署在同一台物理机上的。部署方式可以参考 上一篇博客。

    二狗不要跑
  • Spring入门:The IoC Container,实践篇(下)

    示例5:(@Autowired + Constructors + Multi-Elements)

    WEBJ2EE

扫码关注云+社区

领取腾讯云代金券