HBase基础及数据模式设计探讨
(一)起源及定位
HBase理论知识起源于Google发表的BigTable论文,Google使用其BigTable系统存储从互联网抓取的网页副本(不断更新),然后通过MapReduce批量处理为这些网页建立索引,供WEB搜索使用。
HBase建立在Hadoop之上,Hadoop理论知识起源于GFS和MapReduce,与BigTable一起构成Google网页搜索业务的技术基础设施。Hadoop与HBase搭档自然适合用于建设网页搜索系统,但并不限于此,它们能在许多大数据情境下发挥重要作用。
Hbase是一种数据库:Hadoop数据库,一个可以随机访问的存储和检索数据的平台。它经常被描述为一种持久化的、分布式的、多维有序映射的、稀疏的,基于行键(row key)、列键(column key)、时间戳(timestamp)建立索引。它也经常被描述为键值(key-value)存储、面向列族的数据库,也是一种能自动保留数据多个历史版本(时间戳)数据库。列族数据库是一种兼顾数据操作(OLTP)和数据分析(OLAP)的数据库。列族数据库逻辑结构常被描述为二级映射(Row Key - Column Key - Cell Value)数据库。有关列族数据更多讨论参考《》
(二)数据模型与基本操作
HBase数据库由一组表构成,不同表的数据结构是一样的,都是五元组<行键、列族、列限定符、时间戳、单元值>。参考下面来自于<<HBase In Action>>中的图所示。
对照关系数据库(RDB)术语,行键对应RDB主键。列族对应RDB中1:1关系的垂直分表,不同列族对应不同的存储文件。列对应RDB表字段的“列“,不过HBase把RDB的列放置到行上,这样操作非常适合存储稀疏矩阵(sparse):表中多数内容为空,只有少数内容有值。时间戳是HBase的一个特色,用于标识和区分存储数据的多个历史版本。
行键作为行记录的主键不能重复,列限定符在行内不能重复,<行键、列限定符、时间戳>是物理排序的唯一索引,其中时间戳是倒序排列。
HBase按照<行键、列限定符、时间戳>排序后顺序存储的特性,便于快速读取行键临近数据,这种特性是否有助于数据分析,则依赖于行键设计。
HBase提供的基本操作主要包括Get、Put、Delete、Scan、Increment指令,另外提供Observer(类似于RDB的触发器)、Endpoint(类似于RDB的存储过程)支持联机处理和MapReduce支持批量分析。
这里比较特殊的指令是Scan,扫描获得一段行键范围内的记录。根据列族数据库的特点,这些记录被连续有序地存储在列族文件中。
为了减少Scan的数据传输,可以为命令提供过滤条件,过滤条件类似于RDB中SQL的Where条件但更灵活,毕竟直接采用Java代码实现。
同样Observer和Endpoint也是用Java实现,比起RDB中使用SQL扩展的私有语言,Java更灵活强大,注:有些RDB也支持使用Java撰写存储过程。
用完整能力的开发语言扩展数据库能力是一件非常有意义的事情,利用已有的成果和强大的能力、广泛的用户群,无需要重复造轮子。如果采用开发数据库平台的兼容语言(例如都运行于JVM),则方便地集成和低成本计算,避免各类数据转换和环境切换。
(三)数据模式设计
数据库存储数据之前需要先设计数据模式,回答以什么样的结构和格式存储什么东西,如何管理及访问数据等。RDB和HBase设计数据模式的核心概念如下图所示。
RDB数据模式设计
图中左侧是关系数据模式设计方法,业务分析追求逻辑上的完整、清晰、准确,模型强调业务实体以及实体之间的关系,强调完整(包括全部内容)和一致(所有应用、服务看到同样的数据结构)。
为RDB设计数据模式,业界拥有标准化的规范方法、丰富的实践经验。这得益于RDB数据模型建立在关系运算之上,一组简单的、规范的、可自由连接的二维表格。更得益于RDB对数据访问方式不做要求,随机访问、批量访问、还是跨多表的组合访问都非常方便,数据库系统自动优化访问路径,提供完善的事务控制。
HBase数据模式设计
图中右侧是HBase的数据模式设计方法,HBase是一个全新物种,采用完全不同于RDB的设计方法。
HBase这种列族数据库无论在理论研究、应用经验上都无法与RDB相提并论,但它能解决RDB不能支撑的数据规模。
为了解决数据的“大”、模式演进等问题,HBase没有提供组合访问能力(数据join和事务控制),数据随机访问和批量访问也做了许多限制:只能通过行键进行。如何访问HBase中的数据成为应用数据模式设计的关键。
HBase的列族数据模型直接影响了业务分析方法:从业务的主要问题入手,而不是业务的完整的实体关系。通过分析用户主要活动,获得应用系统的主要访问方式,应用系统的访问方式决定HBase数据库表的访问方式,进一步决定表行键的结构、列和单元值的内容。
HBase行键设计
数据模式设计如果有唯一重要的事情,一定是行键,它决定了随机访问和批量访问的便利和性能,影响数据存储的效率。为了设计便于数据访问行键,往往需要综合运用这里的多种方法。
随机访问场景需要防止读/写热点,维护行键离散以便把数据分散到不同节点。
离线分析场景需要连续读写,维护行键有序以便把数据放到一起。
定长行键有助于行键组合/分割、随机行键有助于随机访问分散、有序行键有助于数据顺序读取、更短的行键有助于缩小存储空间。
常用行键候选包括顺序字段、业务字段、组合字段、时间戳、随机数、字段Hash、salt前缀等。
HBase模式设计经验
数据规模是第一本质性要素。
规范化利于写性能但不利于读性能,反规范化则相反,HBase需要比RDB更多地利用反规范化。把相关信息聚合到一个记录,甚至聚合到一个单元值是常用的方法。注:每个单元值都有完整的坐标,如果把RDB表的列映射到HBase的表列,则更多的坐标占用更多存储空间。
字符串数组(字节流)可以存储任何东西,行键、列限定符、单元值均如此。
列限定符占用存储空间,建议用更短的列名;列限定符自身可以用于存储数据,就像数据单元一样,这一点类似于JSON格式。
同一列族存储同一访问模式的所有东西,列族名长度不影响存储空间但影响网络IO。
高表利于随机访问但降低原子性和聚合访问,宽表则反之。高表指多用行键编码更多内容来定位细粒度数据,宽表则多用行键+列限定符定位数据。
尽量能否在单个API调用完成访问模式,HBase不支持跨行事务控制。
与关系数据模型映射
所有设计最终都应该来自于业务需求,而不是另一个数据模型。无论是上层的业务模型驱动下层的逻辑数据模型,还是底层的存储数据模型影响上层的逻辑数据模型,都是建立在同一个前提下:更简单有效地解决客户问题。
如果决定用HBase作为应用的存储,那么设计数据模式时就应该使用HBase的方式来思考(Thinking in HBase),而不是使用关系数据库的方式。事实上选择HBase一定是因为它更善于解决应用的关键问题(通常是规模和随机访问),且没有阻碍应用落地的重要限制。
仍然有一些与RDB有关联的需求或者你想运用一些关系知识,例如使用HBase搭建数据源为RDB的数据仓库,使用SQL对HBase库进行数据分析等。这些情况下设计HBase数据模型就需要考虑RDB的特点,这种情况下关系模型友好是需求的一部分。
模式设计根本是模型映射
数据模式设计的本质是映射业务需求到数据库存储模型。如果业务模型与存储模型差异很大,就需要大量的代码用于处理访问和转换,这违背了更简单有效地解决问题的初衷。
架构设计选用更适合分析解决业务问题的模型方法,同样需要选用适合落实业务模型的存储模型,这样模映射起来自然简单。
由于模型是对现实世界的抽象思考,往往可以有多种方法进行 (尽管可能有一种方法会更好)。如果采用的某个工具是前提(比如这里的HBase),尽量使用工具的模型思考待解决的问题就会比较好。更多模型映射的讨论请参考《》
(四)适合的应用场景
对象数据存储
数据历史存储
单元值可以自动存储多个历史版本、以列族为单位控制保留版本数和TTL保存周期,适合用于存储数据的历史版本。列族压缩和有序存储便于大幅度减少存储空间和历史版本读取性能。Google用于存储爬取网页的历史。企业可以用于存储需要跟进变更历史的情景,如文档修订历史、单据审批历史等。
大数据存储
HBase适合处理规模非常大的情景,例如监控日志、行为采集、博客网站等。
大数据平台底层是计算机集群,集群的本质是通过分工来承担更大的存储/计算量,而简单独立的事情更便于分工。数据量不大但逻辑复杂的事情,RDB要比大数据存储合适;但数据量大且逻辑复杂的事情,还是需要大数据存储,通过服务分治等降低复杂性。
HBase起源于搜索引擎,它适合在多少领域范围内作为数据库使用,这是个难于回答的问题。这依赖于其自身的通用性和易用性,更依赖于待解决问题的可用方案候选,这不是谁能胜任而是谁能胜出的问题。与擅长横向扩展的另外两类数据库系统相比,键值数据库代表产品Redis和文档数据库代表产品MongoDB在各自领域获得广泛应用且取得领导地位,HBase的最大优势恐怕还是与Hadoop的无缝整合,便于进一步与其它大数据分析工具整合。
无论您有什么相关想法或建议,欢迎一起探讨。
(本文完)