用HBase处理大数据 第五部分:数据建模(或者,没有SQL的生活)


[编者注:请务必先查看 第一部分 第二部分 第三部分 ]。

这是介绍 Apache HBase 的系列博客的第五篇。在 第四部分 中, 我们看到了使用Java API与HBase交互的基础知识,以 创建表,通过行键检索数据,以及进行表扫描。这一部分 将讨论如何在HBase中设计模式。

HBase没有类似于 的SQL那样的丰富的查询能力。 关系型数据库的丰富查询功能。相反,它放弃了这种能力和其他 诸如关系、连接等,而是专注于提供 具有良好的性能和容错性的可扩展性。因此,当与HBase一起工作时,你需要设计 时,你需要设计行键和表结构的 的行和列族来设计行键和表结构,以匹配你的 应用的数据访问模式。 应用的数据访问模式。这与你在关系型数据库中的做法完全相反。 这与关系型数据库完全相反,在关系型数据库中,你一开始就有一个规范化的数据库模式, 。 独立的表,然后你用SQL来执行连接,将数据 以你需要的方式组合数据。有了HBase,你就可以根据应用程序的访问方式来设计你的表。 它们将被应用程序访问,所以你需要考虑更多 所以你需要提前考虑如何访问数据的问题。与关系型数据库相比,HBase更接近于**裸的 与关系型数据库相比,HBase更接近于**的 金属,因为关系型数据库抽象了 实施细节和存储机制。 实现细节和存储机制。然而,对于需要存储大量数据的应用 。 需要存储大量数据并具有固有的可扩展性, 性能特点和对服务器故障的容忍度, 潜在的好处可以远远超过成本。

关于Java API的最后一部分 中, 我提到,当扫描HBase中的数据时,行键是至关重要的 。 因为它是限制扫描行的主要手段;没有 没有像关系型数据库中的SQL那样的丰富查询。通常情况下 。 你使用开始和停止行键创建一个扫描,并且可以选择添加 过滤器来进一步限制返回的行和列数据。为了 为了在扫描时有一定的灵活性,行键应该被设计成 。 以包含你需要的信息,从而找到特定的数据子集。在 到目前为止,我们所看到的博客和人的例子中,行键是 设计为允许通过最常见的数据访问模式进行扫描。对于 博客,行键是简单的发布日期。这将允许 以博客条目的升序进行扫描,这可能不是 最常见的查看博客的方式;你宁愿看到最近的博客 首先。因此,一个更好的行键设计是使用反向顺序的 时间戳,你可以用公式 (Long.MAX_VALUE - timestamp) , 所以扫描时先返回最近的博客文章。这使得它很容易 扫描特定的时间范围,例如,显示过去 周或月的所有博客,这是在网络 中浏览博客条目的一种典型方式。 应用的典型方式。

对于 people 表的例子,我们使用一个复合行 键,由姓、名、中间名和一个(唯一的) 人的标识符来区分具有完全相同名字的人, 用破折号分隔。例如,Brian M. Smith的标识符为12345 将有行键 smith-brian-m-12345 。扫描 people 表的扫描可以使用开始和结束行来组成,旨在 检索具有特定姓氏的人,姓氏以 特定的字母组合,或具有相同姓氏和 名字的首字母。例如,如果你想找到那些 的人,你可以使用开始行键 smith-b 和停止行键 smith-c (开始行键是包容性的,而停止行键是排他性的,所以停止键 smith-c 确保所有名字以字母 "B "开头的史密斯人都被 包括在内)。你可以看到,HBase支持部分键的概念, 意味着你不需要知道确切的键,以提供更多的 灵活地创建适当的扫描。你可以将部分密钥 扫描与过滤器相结合,只检索需要的特定数据,从而 优化数据检索,使之符合你的 应用的特定数据访问模式。 应用。

到目前为止,这些例子只涉及包含一种 类型的信息,而没有相关信息。HBase没有 外键关系,但由于它 支持多达数百万列的行,因此在HBase中设计表的一种方法是封装表。 在HBase中,一种设计表的方法是将相关信息封装在同一行中--一种 "宽 "表设计。它被称为 "宽 "设计,因为你要把与某一行有关的所有信息都存储在 所有与某一行相关的信息都被存储在有多少列的 是数据项。在我们的博客例子中,你可能想存储评论 为每一个博客。设计这个的 "广泛 "方法是包括一个 列族,然后向 comment 列族添加列,其中限定词是评论的时间戳;评论列看起来像 comments:20130704142510comments:20130707163045 . 。 更棒的是,当HBase检索列时,它会以排序的 顺序,就像行键一样。因此,为了显示一个博客条目和它的 评论,你可以通过要求 contentinfocomments 列族来检索一行中的所有数据。你也可以添加一个过滤器,只检索特定数量的评论,给它们添加分页。

people 表的列族也可以 重新设计,以存储联系信息,如单独的地址, 电话和电子邮件地址的列族,允许所有的 人的信息被存储在一行中。这种设计可以 。 如果列的数量相对较少,这种设计可以很好地工作,如博客 。 评论和一个人的联系信息就是如此。相反,如果你是 模型的东西,如电子邮件收件箱、金融交易或 大量的自动收集的传感器数据,你可能会选择 而将用户的电子邮件、交易或传感器读数分布在多行("高")。 跨越多行(一个 "高 "的设计),并设计行键以允许 有效的扫描和分页。对于一个收件箱,行键可能看起来 像 <user_id>-<reversed_email_timestamp> ,这将允许轻松地扫描和分页用户的收件箱,而对于金融交易,行键可能是 <user_id>-<reversed_transaction_timestamp> . 。 这种设计可以被称为 "高",因为你在传播 这种设计可以被称为 "高",因为你把关于同一事物的信息(例如,来自同一传感器的读数, 帐户中的交易)跨越多行,并且是需要 如果有一个不断扩大的信息量,如 在涉及到从一个巨大的 .com传感器网络中收集数据的情况下,是需要考虑的。 巨大的传感器网络的数据收集情况。

在HBase中设计行键和表结构是 工作的一个关键部分。 工作的关键部分,而且鉴于HBase的基本 架构的情况下,将继续如此。你还可以做其他事情来增加 HBase中的数据访问的替代方案。例如,你可以 。 通过Apache Lucene实现全文搜索,无论是在行内还是 外部的HBase(在谷歌上搜索HBASE-3529)。你还可以创建 (和维护)二级索引,以允许为 表;例如,在我们的 people 表中,复合行 键由名称和唯一标识符组成。但是,如果我们希望 通过他们的出生日期、电话区号、电子邮件地址、 或任何其他的方式,我们可以添加二级索引来实现 这种形式的交互。然而,请注意,添加二级索引 。 不是一件轻而易举的事情;每当你向 "主" 表(如 people )时,你就需要同时更新所有的 次级索引! (是的,这是关系型数据库做得 但请记住,HBase的设计是为了容纳更多的 的数据)。

第五部分的结论

在该系列的这一部分,我们得到了关于模式设计的介绍 。 在HBase中(没有关系或SQL)。尽管HBase缺少一些 传统RDBMS系统中的一些功能,如外键 。 和参考完整性、多行事务、多索引,以及 子,许多需要HBase固有优势的应用,如 缩放可以从使用HBase中获益。就像任何复杂的事物一样,也有 。 要做出权衡。在HBase的情况下,你会放弃一些 丰富的模式设计和查询灵活性,但你获得了 通过(或多或少)简单地 扩展到大量数据的能力。 添加额外的服务器到你的集群。

在本系列的下一部分也是最后一部分,我们将总结并提到 一些我们在这些介绍性的博客中没有涉及到的(许多)东西。

参考文献