如何优雅的理解HBase和BigTable

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
.cn 域名,1个 12个月
简介:

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


学习 HBase 最难的地方在于要让你的脑子真正理解它是什么。

HBase:Google BigTable 的开源实现

我们经常会把关系型数据库(RDBMS,比如 MySQL)和 HBase 搞混,因为在这两个系统中都包含 table 和 base(HBase,Database)。

这篇文章的目标是从概念上来说清楚 HBase 这个分布式的数据存储系统。读完后,你应该可以很清楚的知道什么情况下 HBase 更好,什么情况下传统的关系型数据库更好。

关于一些术语

幸运的是,Google 的 BigTable论文清楚的解释了 BigTable 到底是什么。下面是论文中数据模型章节的第一句话:

BigTable 是一个稀疏的、分布式的、可持久化的多维有序 map。

在这个节骨眼上,我想给读者一个机会,让他们在读到最后一行字时,能够收集到他们脑壳里的活动信息(这可能是个笑话,但我没懂^v^)。

论文中,继续解释如下:

map 通过 rowKey,columnKey 和时间戳进行索引,map 中的每个值都是一个连续的字节数组。

注:rowKey 是记录的主键,唯一标识一行记录

在 Hadoop 的官方文档中,也对 HBase 的架构做了说明:

HBase 使用了与 BigTable 非常类似的数据模型。用户存储数据行到特定的表中。一个数据行有一个可排序的 rowKey 和数量不定的列。这个表是稀疏的,只要用户愿意,这个表不同行可以有完全不同的列。

这些话看起来相当费解,让人摸不着头脑,但如果你把这些话拆成一个个词,意思就慢慢变的清晰了。我将按照以下的顺序来讨论这些词:map,持久化,分布式,有序的,多维的,稀疏。

我发现循序渐进地建立一个思维框架要比一次性勾画一个完整的系统更加容易。

map

从根本来上来,HBase/BigTable 是一个 map。map 在不同的编程语言中有不同的叫法,比如 PHP 中的 array,Python 的 dictionary,Ruby 中的 Hash,或者 JavaScript 中的 Object。

维基百科上对于 map 的定义是:map 是一个抽象的数据类型,包含了一组 key 和一组 value,每个 key 关联一个 value。

如果用 JavaScript 的对象来表示 map,这里有一个简单的例子,其中所有的 value 都是字符串:

{
  "zzzzz" : "woot",
  "xyz" : "hello",
  "aaaab" : "world",
  "1" : "x",
  "aaaaa" : "y"
}

持久化的

持久化的意思仅仅是指你放进这个特殊 map 的数据会在你的程序执行完成之后被保存下来。它和其他的持久化存储系统中持久化的概念没有任何区别,比如存一个文件到一个文件系统。我们继续...

分布式的

HBase 和 BigTable 都建立在分布式文件系统上,所以底层文件可以被分散存储到不同的机器上。

HBase 可以存储到 HDFS(Hadoop's Distributed File System)上,也可以存储到 亚马逊的 S3(Simple Storage Service)上,而 BigTable 使用的是 GFS(Google File System)。

同一份数据会被复制存储到多个节点上,类似于 RAID(独立冗余磁盘阵列,利用冗余存储的数据使损坏数据得以恢复,从而保护数据不丢失)系统中数据在磁盘上的复制存储到多块磁盘的方式。

在这篇文章中,我们不关心具体使用哪种分布式文件系统。重要的是,要理解这个文件系统是分布式的,即使集群中某个节点出现故障,也可以保证数据的完整性和安全性。

有序的

和其他大多数 map 的实现不同,HBase 和 BigTable 的键值对的顺序严格按照字母顺序来排列。所以 rowKey 为 "aaaaa" 的下一条记录的 rowKey 就是 "aaaab",并且会离 “zzzz” 非常远。

继续看上面的那个 JSON 例子,排行序之后是下面这样的:

{
  "1" : "x",
  "aaaaa" : "y",
  "aaaab" : "world",
  "xyz" : "hello",
  "zzzzz" : "woot"
}

因为这个系统是分布式的,而且会越来越大,因此排序这个特性非常重要。这样就会把 rowKey 相近的记录放在一起,在某些情况下,如果你必须要扫描表(通常不推荐),那就能保证你需要获取的记录都在一块。

那么如何选择 rowKey 就非常重要。比如说,一个表的 rowKey 就是域名。一个比较好的方式就是将域名进行反转来作为 rowKey(使用 “com.jimbojw.www”,而不要使用 “www.jimbojw.com”),这样,同一个域名下的记录就可以存储在相邻的位置。

继续上面的域名例子,rowKey 为 “mail.jimbojw.com” 行应该与 “www.jimbojw.com” 行更近,而不是 “mail.xyz.com”,如果不把域名反转存储,就会发生这种情况。

需要注意的是,在 HBase / BigTable 中,有序并不意味着值是有序的。除了 rowKey 以外,没有任内容会被排序,在这点上和普通 map 的实现一致。

多维的

到目前为止,我们还没有提过任何关于列的概念,而是将表在概念上当做常规的 map。我是故意这么做的。列和表、base 等词一样,都带有传统关系型数据库多年的情感包袱。

然而,我发现把 HBase 理解为一个多维的 map 会容易很多,map 的 map。给上面的 JSON 再加上一列:

{
  "1" : {
    "A" : "x",
    "B" : "z"
  },
  "aaaaa" : {
    "A" : "y",
    "B" : "w"
  },
  "aaaab" : {
    "A" : "world",
    "B" : "ocean"
  },
  "xyz" : {
    "A" : "hello",
    "B" : "there"
  },
  "zzzzz" : {
    "A" : "woot",
    "B" : "1337"
  }
}

在上面的例子中你可以看到每个 key 都指向了另一个 map,其中包含着 A 和 B 两个 key。在这里,我们将最上面那层键值对称为行。并且在 HBase / BigTable 的术语表中,A 和 B 的映射称之为列族。

一个表的列族在表创建的时候就会被创建好,而且后续修改很困难,添加一个新列族的开销同样也很大,所以在创建表的时候应当将后续会用到的所有列族创建好。

好在一个列族可以有任意数量的列。称之为为列限定符(qualifier)或者标签(label)。

下面是我们上面 JSON 例子的子集,这次加入了 qualifier 的维度:

{
  // ...
  "aaaaa" : {
    "A" : {
      "foo" : "y",
      "bar" : "d"
    },
    "B" : {
      "" : "w"
    }
  },
  "aaaab" : {
    "A" : {
      "foo" : "world",
      "bar" : "domination"
    },
    "B" : {
      "" : "ocean"
    }
  },
  // ...
}

注意在上面的两行数据中,A 列族有两列:foo 和 bar,B 列族只有一列,而且 qualifier 是一个空字符串。

当访问 HBase / BigTable 中的数据时,你需要提供完整的列名::。举个例子,上面总共有三列,分别是:A:foo,A:bar 和 B:。

列族虽然基本固定不变,但是列不是,来看下面的例子:

{
  // ...
  "zzzzz" : {
    "A" : {
      "catch_phrase" : "woot",
    }
  }
}

在这个例子中,zzzzz 行有一个列 A:catch_phrase。因为每一行可以有任意数量的列,所以没有内置方法可以从所有行中的所有列中查询出一个列表。为了获取到那些信息,你需要做全表扫描。但是你可以查询所有的列族,因为它们是不变的(基本不变)。

HBase / BigTable 中最后的一个维度是时间。所有数据默认通过时间戳(1970年以来的秒数)来表示版本,或者你也可以指定一个其他的整数。客户端在插入数据的时候可以指定这个时间戳。

在最新的例子中,我们使用任意的整数来作为版本标识:

{
  // ...
  "aaaaa" : {
    "A" : {
      "foo" : {
        15 : "y",
        4 : "m"
      },
      "bar" : {
        15 : "d",
      }
    },
    "B" : {
      "" : {
        6 : "w"
        3 : "o"
        1 : "w"
      }
    }
  },
  // ...
}

每个列族可以自己指定一个 cell 中的数据可以保留多少个版本(cell 由 rowKey 和列进行标识)。在大多数情况下,应用会直接访问一个 cell 中的数据,而不会指定一个时间戳(版本),HBase / BigTable 会直接返回最近版本(时间戳最大的那个)的数据,因为它是按照时间倒序来存储数据的。

如果应用在请求数据的时候指定了一个时间戳,那么 HBase 就会返回时间戳小于或者等于指定时间戳的一个 cell 中的数据。

如果查询上面例子中的 HBase 表,查询 aaaaa A:foo,就会返回 y,如果带时间戳查询 aaaaa A:foo 10,就会返回 m,如果查询 aaaaa A:foo 2,就会返回 null。

稀疏的

最后的一个关键词是稀疏的。就如上面所说的,一个给定的行在每个列族中可以有任意数量的列,0 或者任意大。行之间可以存在间隙,这也是另一种稀疏。

如果你一直跟着本文在 map 的基础上来理解 HBase / BigTable,而没有与关系型数据库(RDBMS)的概念混淆,这样就很好了。

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-06-14
本文作者:Rayjun
本文来自:“掘金”,了解相关信息可以关注“掘金”

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
|
Java Shell 分布式数据库
【大数据技术Hadoop+Spark】HBase数据模型、Shell操作、Java API示例程序讲解(附源码 超详细)
【大数据技术Hadoop+Spark】HBase数据模型、Shell操作、Java API示例程序讲解(附源码 超详细)
162 0
|
SQL 分布式计算 Hadoop
Hadoop集群hbase的安装
Hadoop集群hbase的安装
211 0
|
3月前
|
分布式计算 Java Hadoop
java使用hbase、hadoop报错举例
java使用hbase、hadoop报错举例
111 4
|
2月前
|
分布式计算 Hadoop Shell
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
76 4
|
2月前
|
SQL 分布式计算 Hadoop
Hadoop-37 HBase集群 JavaAPI 操作3台云服务器 POM 实现增删改查调用操作 列族信息 扫描全表
Hadoop-37 HBase集群 JavaAPI 操作3台云服务器 POM 实现增删改查调用操作 列族信息 扫描全表
34 3
|
2月前
|
分布式计算 Hadoop Shell
Hadoop-36 HBase 3节点云服务器集群 HBase Shell 增删改查 全程多图详细 列族 row key value filter
Hadoop-36 HBase 3节点云服务器集群 HBase Shell 增删改查 全程多图详细 列族 row key value filter
59 3
|
2月前
|
SQL 分布式计算 Hadoop
Hadoop-34 HBase 安装部署 单节点配置 hbase-env hbase-site 超详细图文 附带配置文件
Hadoop-34 HBase 安装部署 单节点配置 hbase-env hbase-site 超详细图文 附带配置文件
88 2
|
2月前
|
存储 分布式计算 Hadoop
Hadoop-33 HBase 初识简介 项目简介 整体架构 HMaster HRegionServer Region
Hadoop-33 HBase 初识简介 项目简介 整体架构 HMaster HRegionServer Region
56 2
|
6月前
|
存储 分布式计算 Hadoop
Hadoop节点文件存储HBase设计目的
【6月更文挑战第2天】
65 6
|
6月前
|
存储 分布式计算 Hadoop
Hadoop节点文件存储Hbase高可靠性
【6月更文挑战第2天】
101 2