首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

快速理解HBase和BigTable

学习Hbase(Google BigTable的开源实现)最困难的是理解它的实际概念。

很不幸的是,这两个伟大的系统在其概念中包含了table和base两个词,这往往会导致一些人(比如我) 把它们跟关系型数据库的东西搞混淆。

本文旨在从概念的角度描述这些分布式数据存储系统。阅读之后,你应该能够更好地判断,什么时候要使用Hbase,什么时候该更好地使用“传统”数据库。

一切都在术语中

幸运的是,Google的BigTable论文清楚地解释了BigTable究竟是什么。这是“数据模型”部分的第一句话:

注意:请牢记上边这句话的每一个词

BigTable论文继续说明

Hadoop wiki的HbaseArchitecture页面假设:

尽管所有这些看起来都相当神秘,但是一旦你将它分解为单词,它就变得容易明确了。我喜欢按照这个顺序讨论它们:map,持久化(persistent),分布式(distributed),有序(sorted),多维(multidimensional)和稀疏(sparse)。

我没有尝试一下子描绘完整的系统,而是发现在脑海中构建一个零碎的框架更容易理解HBase……

Map

Hbase / BigTable的核心是map,根据您的编程语言背景,您可能更熟悉这些术语,array (PHP), dictionary (Python), Hash (Ruby), or Object (JavaScript).

维基百科文章显示,Map是“由一组键和一组值组成的抽象数据类型,其中每个键与一个值相关联。”

用JSON来描述一个简单Map的示例,其中所有值都只是字符串:

持久化

持久化仅仅意味着在创建或访问数据的程序完成后,您放入此特殊Map的这些数据“会持久保存”。这在概念上与任何其他类型的持久存储(例如文件系统上的文件)没有什么不同。

有序

与大多数Map实现不同,在Hbase / BigTable中,键/值对按严格的字母顺序保存。也就是说,键“aaaaa”的行应该在具有键“aaaab”的行旁边,并且与具有键“zzzzz”的行相距很远。

继续我们的JSON示例,有序版本如下所示:

由于这些系统往往非常庞大且是分布式,因此这种有序的特性非常重要。具有相似键的行在空间上的邻近性确保了当您必须扫描表时,您最感兴趣的条目彼此接近。

值得注意的是,在Hbase / BigTable中,术语“有序”并不意味着“值(values)”已排序。除了键之外,没有任何自动索引,就像在普通Map实现中一样。

多维

到目前为止,我们还没有提到任何“列(columns)”的概念,将“表(table)”视为概念中的常规哈希/映射(map)。这是有意为之。 “列(column)”这个词是另一个加载的词,如“table”和“base”,它传承了多年关系型数据库经验的情感包袱。

相反,我发现(把HBase)看成一个多维Map更容易思考这个问题 - 如果你愿意的话,可以使用嵌套Map。在之前的JSON示例中添加一个维度:

在上面的例子中,您现在会注意到每个键都指向一个有两个键的Map:“A”和“B”。从此处开始,我们将顶层键/映射(key/map)称为“行”。此外,在BigTable / Hbase命名法中,“A”和“B”映射(mappings)将被称为“列族”。

创建表时会指定表的列族,以后很难或无法修改。添加新列族代价也很大,因此好的做法是从一开始就指定您需要的所有列族。

幸运的是,列族可以具有任意数量的列,由列“限定符(qualifier)”或“标签(label)”表示。以下是我们的JSON示例的子集,内置了列限定符维度(qualifier dimension):

请注意,在显示的两行中,“A”列族有两列:“foo”和“bar”,“B”列族只有一列,其限定符为空字符串(“”)。

在向Hbase / BigTable询问数据时,必须以“:”的形式提供完整的列名称。因此,例如,上例中的两行都有三列:“A:foo”,“A:bar”和“B:”。

请注意,虽然列族是静态的,但列本身不是。考虑这个扩展的行:

在这种情况下,“zzzzz”行只有一列,“A:catch_phrase”。由于每行可能包含任意数量的不同列,因此没有内置方法可以查询所有行中所有列的数据(list)。要获取该信息,您必须进行全表扫描。但是,您可以查询所有列族的数据,因为它们是不可变的(或多或少)。

Hbase / BigTable中最后一个维度是时间。所有数据都使用整数时间戳(seconds since the epoch)或您选择的另一个整数进行版本控制。客户端可以在插入数据时指定时间戳。

看一下使用任意整数时间戳的示例:

每个列族可能有自己的规则,确定保留的给定单元格的版本数量(单元格由其rowkey / column键值对标识)在大多数情况下,应用程序将只询问给定单元格的数据,而不指定时间戳。在这种常见情况下,Hbase / BigTable将返回最新版本(具有最高时间戳的版本),因为它以时间逆序存储这些版本数据。

如果应用程序指定时间戳,Hbase将返回时间戳小于或等于所提供时间戳的单元数据。

使用我们想象中的Hbase表,查询“aaaaa”/“A:foo”的行/列(row/column)将返回“y”,同时查询“aaaaa”/“A:foo”/ 10的 行/列/时间戳 将返回“M”。查询“aaaaa”/“A:foo”/ 2的 行/列/时间戳 将返回空结果。

稀疏

最后一个关键字是稀疏。如前所述,给定行在每个列族中可以包含任意数量的列,或者根本不包含任何列。另一种类型的稀疏性是基于行的间隙(row-based gaps),这仅仅意味着键(key)之间可能存在间隙。

如果您已经按照本文的基于映射(map-based)的术语来思考Hbase / BigTable,而不是用关系型数据库中的相似概念去思考,那么本文的目的就达到了。

就这样(And that's about it)

好吧,我希望这有助于您从概念上理解Hbase数据模型的含义。

一如既往,我期待着您的想法,意见和建议。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181026B13OHW00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券