hbase基本原理 - 数据模型

本文介绍了HBase的基本原理,特别是其数据模型,包括行、列簇、列修饰符、单元格、时间戳等概念。HBase是一个分布式、稀疏的多维度排序Map,数据存储按列簇维度进行。数据模型的操作主要包括Put、Get、Delete和Scan,每个单元格由行键、列族、列修饰符和时间戳唯一确定,版本按照降序存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

在hbase中,数据是以表的形式存储的,表又是由列簇和行组成,几个基本概念如下:
1. 行(Row)
hbase的行(row)由一个row key和多组数据组成;
row是按照rowkey的字母排序来存储的;
2. 列簇(Column Family)
列簇在物理存储上包含了一系列Column的集合;
数据按ColumnFamily分开存储,HBase所谓的列式存储就是根据ColumnFamily分开存储(每一个ColumnFamily对应一个Store),每个列簇有自己的存储属性,包括数据是否压缩,是否在内存中缓存等。
3. 列修饰符(Column Qualifier)
每个列簇可以有一个或多个列修饰符,用来索引列簇中的数据,不需要在表定义时给出,新的列族成员可以随后按需、动态加入,不同row之间的列修饰符可以不同;
4. 列(Column)
hbase中的列是由列簇和列修饰符(Column Qualifier)组成,并以冒号隔开,表示一个具体的列;
5. 单元格(Cell)
Cell由行键,列族,列修饰符,时间戳唯一确定,时间戳表示版本;
Cell中的数据是没有类型的全部以字节码的形式贮存;
6. 时间戳(Timestamp)
时间戳在每次写入数据时候指定,默认是写入时RegionServer上的时间,但是也可以直接指定;

逻辑视图

以上,就是hbase数据模型的全部基本概念,下面可以看看逻辑视图如何。
Apache hbase是基于google开源的bigtabe,关于bigtable论文,可以参考这里
类似于bigtable的原理,hbase也被设计成一个稀疏的,分布式的,可持久化的多维度排序map。
表结构和基本概念对应关系见下图:
这里写图片描述
其中第一行row00001对应的存储稀疏map如下:
这里写图片描述

物理视图

我们通过官网的一个描述示例来说明逻辑模型对应的物理存储模型。

Row KeyTime StampColumnFamily contentsColumnFamily anchorColumnFamily people
“com.cnn.www”t9anchor:cnnsi.com = “CNN”
“com.cnn.www”t8anchor:my.look.ca = “CNN.com”
“com.cnn.www”t6contents:html = “…​”
“com.cnn.www”t5contents:html = “…​”

其中有些单元格是空的,这个在hbase实际存储中是不占空间的,这也就是为什么hbase是“稀疏”的。

虽然hbase的表从逻辑上来说是一系列稀疏的map存储,但是从实际存储上来说是按照列簇维度存储的。比如上述官网的逻辑模型实际存储就是:

Row KeyTime StampColumn Family anchor
“com.cnn.www”t9anchor:cnnsi.com = “CNN”
“com.cnn.www”t8anchor:my.look.ca = “CNN.com”

Row KeyTime StampColumnFamily contents
“com.cnn.www”t6contents:html = “…​”
“com.cnn.www”t5contents:html = “…​”
“com.cnn.www”t3contents:html = “…​”

数据模型的操作

hbase只提供四种针对数据模型的操作,即Put,Get,Delete和Scan,都是基于客户端api的Table类来进行操作,可以简单看下Scan的api用法,后面再详细讲。

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中有一个版本的概念,即version,我们通过{row, column, version}三元组可以定位一个Cell,可以理解为同一行同一列支持一组单元格存储,关于版本我们要知道:
1. 版本按照降序存储,即如果读一个版本,时间最近的数据将被读取;
2. 如果多次写入的版本相同,则只有最近一次写入的数据被保留;
3. 写入数据的版本不必是增序的;
4. hbase的最大版本个数可以在创建表时指定,也可以通过alter来修改,默认的是1(0.96版本及以后);
5. 在获取数据时,也可以指定版本个数;
拿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

【参考资料】http://hbase.apache.org/book.html#datamodel

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值