分布式数据库HBase原理

目录:

  1. 概述
  2. HBase访问借口
  3. HBase数据模型
  4. HBase实现原理
  5. HBase运行机制
  6. HBase应用方案

概述

简介

HBase是一个高可靠、高性能、面向咧、可伸缩的分布式数据库。是谷歌BigTable的开源实现,主要用来存储非结构化半结构化的松散数据。

为什么要HBase?

  1. 受限于Hadoop MR编程框架的高延迟数据处理机制,无法满足大规模数据实时处理的需求
  2. HDFS不能随机访问
  3. 传统关系型数据无法应对剧增的海量数据
  4. 传统关系型数据库在数据结构变化时需要停机维护;孔裂浪费存储空间

因此,业界出现了一类面相半结构化数据存储和处理的高可扩展、低写入、查询延迟的系统。如键值数据库、文档数据库和列族数据库(如BitTable和HBase)。如今HBase已经成功应用于互联网服务领域和传统行业的众多在线式数据分析处理系统中。

HBase与传统关系数据库的对比

特性 传统关系数据库 HBase
数据类型 关系模式,具有丰富的数据类型后和存储方式 采用更简洁的数据模型,吧数据存储为未经解释的字符串
数据操作 包含丰富的操作,涉及复杂的夺标链接 不存在复杂的表于表之间的关系,只有简单的增、删、查、清空等,避免表于表间复杂关系
存储模式 基于行存储 基于列存储,每个列族有几个文件保存,不同列族的文件是分离的
数据索引 通过针对不同列构建复杂多个索引以提高访问性能 只有一个索引(行键),访问方法为或行键访问或行键扫面,通过巧妙的设计,速度不会慢下来
数据维护 更新操作用最新的数据覆盖旧的 更新操作生成一个新的版本,久的版本仍然保留
可伸缩性 很难实现横向拓展,纵向拓展空间也有限 可以轻易通过在集群中增加或减少硬件数量实现性能伸缩

HBase访问接口

HBase数据模型

  1. 数据模型概述
  2. 数据模型相关概念
  3. 概念视图
  4. 物理视图
  5. 面向列的存储

数据模型概述

  • HBase是一个稀疏多维度、排序的映射表,这张表的索引时行键列族列限定符、、时间戳
  • 每一个值是一个未经解释的字符串,没有数据类型。
  • 每一行都有一个可排序的行键和任意多的列
  • 表在水平方向由一个或者多个列族组成,一个列族可以包含任意多个列,同一个列族里面的数据存储在一起
  • 列族支持动态扩展,轻松的添加列族或列,无预先定义列的数量和类型。所有列均以字符串形式存储,用户需自行进行数据类型转换。
  • HBase中执行更新操作时,生成新版本,保留旧版本,查询时默认返回最新版本。创建时可以设置最多保留版本数量。

    数据模型相关概念

  • 表:HBase采用表来组织数据,表由行和列组成,列换分为若干个列族,避免夺标链接操作,追求分析效率。
  • 行:每个HBAse表由若干行组成,每个行由行键(Row Key)来标示。不给行键所在的列进行命名,让其拥有纵向可拓展性。
  • 列族:一个HBase表被分组成许多“列族”的集合,它是基本的访问控制单元,也是基本存储单元。
  • 列限定符:相当于列名
  • 单元格:在HBaae表中,通过行、列族和列限定符确定一个“单元格”,(时间戳定义其版本)单元格中存储的数据没有数据类型,总被视为字节数组byte[]
  • HBase中需要根据行键、列族、列限定符和时间戳确定一个单元格,因此是一个“四维”坐标。
    💡:上文中提到HBase数据只有一个索引(行键),

概念视图

物理视图

面向列的存储

💡不同存储模型优劣对比

  • 面向行存储的数据库主要采用NSM(N-ary Storage Model)存储模型,即一个元组(行)会被连续存储在磁盘页中,数据是一行行进行存储,读取也是一行行进行读取。当要选取某属性进行分析时,也需要首先扫面完整元组内容。

    • 优点:适用于联机事务性数据处理,即将分布于不同地理位置的数据利用网络进行连接,进而进行统一的存储和管理。
    • 缺点:鄙视和分析性操作
  • 面向列存储的数据库主要采用DSM(Decompostion Storage Model)存储模型,该模型会对关系进行垂直分解,并为每个属性分配一个子关系,每个子关系单独存储。

    • 优点:在批处理和即兴查询等分析操作中能够直接定位目标列,能够有有效I/O开销;同一列数据类型相同,存储过程能够拥有很高的数据压缩旅,从而节省存储空间。
    • 缺点:执行连续操作时要付出昂贵的元组重构代价。

💡 总结:NSM存储模型更加适合事务型应用,DSM存储模型更加适合分析性应用

HBase实现原理

HBase功能组件

  • 库函数
  • 一个Master主服务器
  • 许多个Region服务器

Master负责管理和维护Hbase表的分区信息,维护Region服务器列表,分配Region,负责均衡,和Namenode功能类似。

Region服务器负责存储和维护分配给自己的Region,处理来自客户端的读写请求,和Datanode功能类似。

客户端并不是直接从Master主服务器读取数据,而是在获得Region的存储位置后,直接从Region服务器上读取数据。

客户端并不依赖Master,而是通过Zookeeper来获得Region位置信息,大多数客户端甚至从来不和Master通信,这种设计是的Master负载很小。

表和Region

  • 一个表包含多个Region
  • 开始只有一个Region,后来不断分裂
  • Regin拆分操作非常快(开始只是修改文件指向),接近瞬间。因为拆分之后的Region读取的仍然是原存储文件,知道“合并”过程吧存储文件异步写到独立的文件之后,才会读取新文件。

  • 每个Region默认大小是100MB到200MB(2006之前)

    • 每个Region的最佳大小取决于丹台服曲奇的有效处理能力
    • 目前每个Region的最佳大小建议1G~2G(2013以后)
  • 每个Region不会被分拆到多个Region服务器(Region最小不可分)
  • 每个Region服务器存储10~1000个Region

Region的定位

  • 元数据表,又名META表,存储了RegionRegion服务器的映射关系。
  • 当HBase表很大时,META表也会被分裂成多个Region
  • 根数据表,有明ROOT表,记录所有元数据的具体位置
  • ROOT表只有唯一一个Region,名字是在程序中被写死的
  • Zookeeper文件记录了ROOT表的位置

  • 为了加快访问速度,META表的全部Region都会被保存在内存中

  • 假设META表的每行(一个映射条目)在内存中大约占用1KB,每个Region限制为128MB,那么上面三层结构可以曹村的用户数据表的Region数目的计算方法是:
    • ROOT表能够寻址META表的Region个数 X 每个META表能寻址的个数
  • 一个ROOT表最多只能有一个Region大小,也就是最多只能有128MB,按照每行占用1KB内存计算,128MB空间可以容纳$128MB ÷ 1kb = 2^{17}$。也就是一个ROOT可以寻址$2^{17}$个.META表的Region。
  • 同理每个META表的Region可以存之的用户数据表的Region个数也是$2^{17}$个

客户访问数据时的“三级寻址”:

  • 为了加速寻址,客户端会缓存位置信息,同时需要解决缓存失效的问题
  • 寻址过程客户端需要询问Zookeeper服务器,不需要链接Master服务器。

HBase运行机制

  1. HBase系统架构
  2. Region服务器工作原理
  3. Store工作原理
  4. HLog工作原理

HBase系统架构

  • 客户端
    • 客户端包含访问HBase的接口,同时在缓存中维护者已经好访问过的Region位置信息,用来加快后续数据访问的过程
  • Zookeeper服务器
    • Zookeeper可以帮助选出一个Master作为集群的总管,并保证在任何时刻总有唯一一个Master在运行,这就避免了Master“单点失效”问题.

💡Zookeeper是一个很好的集群管理工具,被大量用于分布式计算,提供配置维护、域名服务、分布式同步、组服务等

  • Master服务器: 主服务器主要负责和Region的管理工作
    • 管理用户对表的增删改查
    • 实现不同Region服务器之间的负载均衡
    • 在Region分裂或合并后,负责重新调整Region的分布
    • 对发生故障时晓得Region服务器上的Region进行迁移
  • Region服务器:
    • Region服务器时HBase最核心的模块,负责维护分配给自己的Region,并响应用户的读写请求

Region服务器的工作原理

1.用户读写数据过程

  • 用户写入数据时,被分配到相应Region服务器去执行
  • 用户数据首先被写入到MemStore和Hlog中
  • 只有当操作写入Hlog之后,commit()调用才会将其返回给客户端
  • 当用户读取数据时,Region服务器会首先访问MemStore缓存,如果找不到,再去磁盘上面的StoreFile中寻找

2.缓存的刷新

  • 系统会周期性地把MemStore缓存里的内容刷写到磁盘的StoreFile文件中,清空缓存,并在Hlog里面写入一个标记
  • 每次刷写都生成一个新的StoreFile文件,因此,每个Store包含多个StoreFile文件

  • 每个Region服务器都有一个自己的HLog 文件,每次启动都检查该文件,确认最近一次执行缓存刷新操作之后是否发生新的写入操作;如果发现更新,则先写入MemStore,再刷写到StoreFile,最后删除旧的Hlog文件,开始为用户提供服务

3.StoreFile的合并

  • 每次刷写都生成一个新的StoreFile,数量太多,影响查找速度
  • 调用Store.compact()把多个合并成一个
  • 合并操作比较耗费资源,只有数量达到一个阈值才启动合并

💡这么做是为了尽量一次性刷到磁盘,以此提高速度.但是如果StoreFile数量太多影响查找速度

Store工作原理

  • Store是Region服务器的核心
  • 多个StoreFile合并成一个
  • 单个StoreFile过大时,又触发分裂操作,1个父Region被分裂成两个子Region

HLog工作原理

  • 分布式环境必须要考虑系统出错。HBase采用HLog保证系统恢复
  • HBase系统为每个Region服务器配置了一个HLog文件,它是一种预写式日志(Write Ahead Log)
  • 用户更新数据必须首先写入日志后,才能写入MemStore缓存,并且,直到MemStore缓存内容对应的日志已经写入磁盘,该缓存内容才能被刷写到磁盘
  • Zookeeper会实时监测每个Region服务器的状态,当某个Region服务器发生故障时,Zookeeper会通知Master
  • Master首先会处理该故障Region服务器上面遗留的HLog文件,这个遗留的HLog文件中包含了来自多个Region对象的日志记录
  • 系统会根据每条日志记录所属的Region对象对HLog数据进行拆分,分别放到相应Region对象的目录下,然后,再将失效的Region重新分配到可用的Region服务器中,并把与该Region对象相关的HLog日志记录也发送给相应的Region服务器
  • Region服务器领取到分配给自己的Region对象以及与之相关的HLog日志记录以后,会重新做一遍日志记录中的各种操作,把日志记录中的数据写入到MemStore缓存中,然后,刷新到磁盘的StoreFile文件中,完成数据恢复
  • 共用日志优点:提高对表的写操作性能;缺点:恢复时需要分拆日志

应用方案

  1. HBase实际应用中的性能优化方法
  2. HBase性能监视
  3. 在HBase之上构建SQL引擎
  4. 构建HBase二级索引

HBase实际应用中的性能优化方法

行键
行键是按照字典序存储,因此,设计行键时,要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。
举个例子:如果最近写入HBase表中的数据是最可能被访问的,可以考虑将时间戳作为行键的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE - timestamp作为行键,这样能保证新写入的数据在读取时可以被快速命中。
InMemory
创建表的时候,可以通过HColumnDescriptor.setInMemory(true)将表放到Region服务器的缓存中,保证在读取的时候被cache命中。
Max Version
创建表的时候,可以通过HColumnDescriptor.setMaxVersions(int maxVersions)设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置setMaxVersions(1)。
Time to Live
创建表的时候,可以通过HColumnDescriptor.setTimeToLive(int timeToLive)设置表中数据的存储生命期,过期数据将自动被删除,例如如果只需要存储最近两天的数据,那么可以设置setTimeToLive(2 24 60 * 60)。

HBase性能监视

  1. Master-status(自带)
  2. Ganglia
  3. OpenTSDB
  4. Ambari

Master-status
HBase Master默认基于Web的UI服务端口为60010,HBase region服务器默认基于Web的UI服务端口为60030.如果master运行在名为master.foo.com的主机中,mater的主页地址就是http://master.foo.com:60010,用户可以通过Web浏览器输入这个地址查看该页面
可以查看HBase集群的当前状态
Ganglia
Ganglia是UC Berkeley发起的一个开源集群监视项目,用于监控系统性能
OpenTSDB
OpenTSDB可以从大规模的集群(包括集群中的网络设备、操作系统、应用程序)中获取相应的metrics并进行存储、索引以及服务,从而使得这些数据更容易让人理解,如web化,图形化等
Ambari
Ambari 的作用就是创建、管理、监视 Hadoop 的集群 (推荐HDP CDH)

在HBase之上构建SQL引擎

NoSQL区别于关系型数据库的一点就是NoSQL不使用SQL作为查询语言,至于为何在NoSQL数据存储HBase上提供SQL接口,有如下原因:

  1.易使用。使用诸如SQL这样易于理解的语言,使人们能够更加轻松地使用HBase。
  2.减少编码。使用诸如SQL这样更高层次的语言来编写,减少了编写的代码量。 

方案:
1.Hive整合HBase
2.Phoenix