当前位置: 首页 > article >正文

HBase简介

目录

  • 1. HBase概述
  • 2. HBase核心概念
    • 2.1 行关键字
    • 2.2 列关键字
    • 2.3 时间戳
    • 2.4 单元
    • 2.4.1 HBase和RDBMS的差异
    • 2.4.2 HBase组成
  • 3. HBase流程
    • 3.1 Region的分配
    • 3.2 RegionServer上线
    • 3.3 RegionServer下线
    • 3.4 Master上线
    • 3.5 Master下线
    • 3.6 写请求处理
  • 参考

1. HBase概述

  HBase是NoSQL(Not Only SQL,泛指用来解决大数据相关问题而创建的数据库技术)数据库的一种,与传统关系型数据库有很多区别,既可以存储结构化数据,也可以存储非结构化数据或半结构化数据。
  如果需要实时随机地访问超大规模数据集,就可以使用HBase这一Hadoop应用。HBase是一个在HDFS上开发的面向列的分布式数据库。
  虽然数据库存储和检索的实现可以选择很多不同的策略,但是绝大多数解决办法,特别是关系型数据库技术的变种,不是为大规模可伸缩的分布式处理设计的。很多厂商提供了复制和分区解决方案,让数据库能够从单个节点上扩展出去,但是这些附加的技术大都属于“事后“的解决办法,而且难以安装和维护,并且这些解决办法常常要牺牲一些重要的关系型数据库管理系统特性。
  在一个扩展的关系型数据库管理系统RDBMS上,连接、复杂查询、触发器、视图以及外键约束这些功能或运行开销大,或根本无法用。HBase从另一个方向来解决可伸缩的问题,它自底向上地进行构建,能够简单地通过增加节点来达到线性扩展的目的。
  HBase并不是关系型数据库,它不支持SQL。但在特定的问题空间里,它能够做RDBMS不能做的事:在廉价硬件构成的集群上管理超大规模的稀疏表。
  HBase是Apache的顶级开源项目,本质是谷歌BigTable的开源山寨版本。建立在HDFS之上,提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统,它介于NoSQL和RDBMS之间,仅能通过主键和主键的范围来检索数据,仅支持单行事物(可通过Hive支持来实现多表join等复杂操作)。主要用来存储非结构化和半结构化的松散数据。

2. HBase核心概念

  HBase的数据存放在带标签的表中。表由行和列组成。表格的单元格由行和列的坐标交叉决定,是有版本的。默认情况下,版本号是自动分配的,为HBase插入单元格时的时间戳。单元格的内容是未解释的字节数组。HBase是一个稀疏、长期存储、多维度、排序的映射表。这张表的索引是行关键字、列关键字和时间戳。每个值是一个二进制的字节数组。

2.1 行关键字

  row key保存为字节数组,是用来检索记录的主键。可以是任意字符串(最大长度为64KB)。存储时,数据按照row key的字典序排序存储。设计row key时,要充分利用排序存储这个特性,将经常一起读取的行存储放到一起。

2.2 列关键字

  列关键字由列族column family和列qualifier两部分组成。列族是表的schema元数据的一部分(列不是),必须在表使用前定义。列名都是以列族为前缀的。例如courses:history、courses:math都属于courses这个列族。有关联的数据应都存放在一个列族里,否则将降低读写效率。目前HBase并不能很好地处理多个列族,建议最多使用两个列族。

2.3 时间戳

  HBase中通过row和columns确定的一个存储单元称为cell。每个cell都保存着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是64位整型。时间戳可以由HBase在数据写入时自动赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由用户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。 每个cell中,不同版本的数据按照时间倒序排列,即最新的数据排在最前面。为了避免数据存在过多版本造成管理负担,HBase提供了两种数据版本回收方式。一是保存数据的最后N个版本,二是保存最近一段时间内的版本。用户可以针对每个列族进行设置。

2.4 单元

  由{row key, column(=<family> + <label>), version}唯一确定的单元,cell中的数据是没有类型的,全部以字节码形式存储。
  与NoSQL数据库一样,row key是用来检索记录的主键。访问HBase表中的行,只有3种方式:
  1. 通过单个row key访问单条记录。
  2. 通过row key的range指定检索范围。
  3. 全表扫描。
  物理上,所有列族成员都一起存放在文件系统中。所以,虽然把HBase描述为一个面向列的存储器,但实际上更准确的说法是,HBase是个面向列族的存储器。由于调优和存储都是在列族这个层次进行的,所以最好使所有列族成员都有相同的访问模式和大小特征。简而言之,HBase表和RDBMS中的表类似,单元格有版本,行是排序的,只要有列族预先存在,客户端随时可以把列添加到列族中去。
  HBase的存储格式如下图所示。
在这里插入图片描述

2.4.1 HBase和RDBMS的差异

  下面通过一些数据来比较HBase和RDBMS表格式上的差异。

Primary keyLast NameFirst NameAccount NumberType of AccountTimestamp
1234SmithJohnabcd1234Checking20120118
1235JohnsonMichaelwxyz1234Checking20120118
1235JohnsonMichaelaabb1234Checking20111123

  (这个表主键应该是(Primary key, Account Number))
  对应的数据在HBase中的存储格式如下。

row keyValue(CF, column, version, cell)
1234info: {‘lastName’: ‘Smith’, ‘firstName’: ‘John’}
acct: {‘checking’: ‘abcd1234’}
1235info: {‘lastName’: ‘Johnson’, ‘firstName’: ‘Michael’}
acct: {‘checking’: ‘wxyz1234’@ts=2012, ‘checking’: ‘aabb1234’@ts=2011}

  下面列出了HBase与RDBMS的主要差异。

HBaseRDBMS
数据类型只有字符串丰富的数据类型
数据操作简单的增删改查各种各样的函数,表连接
存储模式基于列存储基于表格结构和行存储
数据保护更新后旧版本仍然会保留替换
可伸缩性轻易地增加节点,兼容性高需要中间层,牺牲性能
典型的数据大小TB-PB级别上亿到数十亿条记录GB-TB级别,几十万到几百万条记录
吞吐量每秒百万条查询每秒数千次查询

2.4.2 HBase组成

  HBase自动将表水平划分成区域。每个区域由表中行的子集构成。每个区域由它所属的表、它所包含的第一行及最后一行(不包括这行)来表示。
  一开始,一个表只有一个区域。但是随着区域变大,等到它的大小超出设定的阈值时,便会在某行的边界上把表分成两个大小基本相同的新分区。在第一次划分前,所有加载的数据都放在原始区域所在的服务器上。
  随着表变大,区域的个数也会增加。区域是在HBase集群上分布数据的最小单位。用这种方式,一个因为太大而无法放在单台服务器上的表会被放在服务器集群上,其中每个节点都负责管理表所在区域的一个子集。表的加载也是使用这种方法把数据分布到各个节点。在线的所有区域按次序排列就构成了表的所有内容。
  HBase的组成如下表所示。

角色功能
Region表中一部分数据组成的子集,当Region内的数据过多时能够自动分裂,过少时会合并
RegionServer维护Master分配给它的Region,处理对这些Region的IO请求,负责切分在运行过程中变得过大的Region
Master为RegionServer分配Region,负责RegionServer的负载均衡,发现失效的RegionServer并重新分配其上的Region,执行HDFS的垃圾文件回收
ZooKeeper保证任何时候集群中只有一个Master存储所有Region的寻址入口。实时监控RegionServer的状态,将RegionServer的上线和下线信息实时通知给Master。存储HBase的Schema,包括有那些table,每个table有那些column family,处理Region和Master的失效

3. HBase流程

  HBase的客户端会将查询过的HRegion的位置信息进行缓存,如果客户端没有缓存一个HRegion的位置或者位置信息是不正确的,客户端会重新获取位置信息。如果客户端的缓存全部失效,则需要进行多次网络访问才能定位到正确的位置。

3.1 Region的分配

  任何时刻,一个Region只会分配给一个RegionServer。Master跟踪当前有哪些可用的RegionServer,以及当前哪些Region分配给了哪些RegionServer,哪些Region还没有分配。当存在未分配的Region且有一个RegionServer上有可用空间时,Master就给这个RegionServer发送一个装载请求,把Region分配给这个RegionServer。RegionServer得到请求后,就开始对此Region提供服务。

3.2 RegionServer上线

  Master使用ZooKeeper来跟踪RegionServer状态。当某个RegionServer启动时,会首先在ZooKeeper上的rs目录下建立代表自己的文件,并获得该文件的独占锁。由于Master订阅了rs目录上的变更消息,当rs目录下的文件出现新增或删除操作时,Master可以得到来自ZooKeeper的实时通知。因此一旦RegionServer上线,Master能马上得到消息。

3.3 RegionServer下线

  当RegionServer下线时,它和ZooKeeper的会话断开,Zookeeper会自动释放代表这台Server的文件上的独占锁,而Master不断轮询rs目录下文件的锁状态。如果Master发现某个RegionServer丢失了它自己的独占锁,Master就会尝试去获取代表这个RegionServer的读写锁,一旦获取成功,就可以确定:
  1. RegionServer和ZooKeeper之间的网络断开了。
  2. RegionServer失效了。
  只要这两种情况中的一种情况发生了,无论哪种情况,RegionServer都无法继续为它的Region提供服务,此时Master会删除Server目录下代表这台RegionServer的文件,并将这台RegionServer的Region分配给其他还“活着”的机器。
  如果网络短暂出现问题导致RegionServer丢失了它的锁,那么RegionServer重新连接到ZooKeeper之后,只要代表它的文件还在,它就会不断尝试获取这个文件上的锁,一旦获取到了,就可以继续提供服务。

3.4 Master上线

  Master启动上线包括以下步骤:
  1. 从ZooKeeper上获取唯一代表Master的锁,用来阻止其他节点成为Master。
  2. 扫描Zookeeper上的Server目录,获得当前可用的RegionServer列表。
  3. 与每个RegionServer通信,获得当前已分配的Region和RegionServer的对应关系。
  4. 扫描.META.region的集合,计算得到当前未分配的Region,将它们放入待分配Region列表。

3.5 Master下线

  由于Master只维护表和Region的元数据,而不参与表数据IO的过程,所以Master下线仅导致所有元数据的修改被冻结。此时无法创建、删除表,无法修改表的schema,无法进行Region的负载均衡,无法处理Region上下线,无法进行Region的合并,唯一例外的是Region的split可以正常进行,因为只有RegionServer的参与,表的数据读写还可以正常进行。因此Master下线短时间内对整个HBase集群没有影响。
  从上线过程可以看出,Master保存的信息全是冗余信息,都可以从系统其他地方收集或者计算出来。因此,一般HBase集群中总有一个Master在提供服务,还有一个以上的“Master"在等待时机抢占它的位置。
  当客户端要修改HBase的数据时,首先创建一个action(比如put、delete、incr等操作),这些action都会被包装成Key-Value对象,然后通过RPC将其传递到HRegionServer上。HRegionServer将其分配给相应的HRegion,HRegion先将数据写入Hlog中,然后将其写入MemStore。MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并且将老的MemStore添加到flush队列,由单独的线程flush到磁盘上,成为一个StoreFile。与此同时,系统会在ZooKeeper中记录一个redo point,表示这个时刻之前的变更已经持久化了。当系统出现意外时,可能导致内存(MemStore)中的数据丢失,此时使用Log来恢复redo point之后的数据。
  StoreFile是只读的,一旦创建后就不可以再修改,因此HBase的更新其实是不断追加的操作。当一个Store中的StoreFile达到一定的阈值后,就会进行一次合并,将对同一个key的修改合并到一起,形成一个更大的StoreFile。
  由于对表的更新是不断追加的,处理读请求时,需要访问Store中全部的StoreFile和MemStore,将它们的数据按照row key进行合并,由于StoreFile和MemStore都是经过排序的,并且StoreFile带有内存中索引,所以合并的过程还是比较快的。

3.6 写请求处理

  写请求的处理过程如下:
  1. Client向RegionServer提交写请求。
  2. RegionServer找到目标Region。
  3. Region检查数据是否与schema一致。
  4. 如果客户端没有指定版本,则获取当前系统时间作为数据版本。
  5. 将更新写入WAL log。
  6. 将更新写入MemStore。
  7. 判断MemStore的数据是否需要flush为Store文件。

参考

吴章勇 杨强著 大数据Hadoop3.X分布式处理实战


http://www.kler.cn/a/553326.html

相关文章:

  • 微软的基本类库BCL
  • 【python】tkinter简要教程
  • springmvc(13/158)
  • Pytorch实现之统计全局信息的轻量级EGAN
  • 计算机视觉算法实战——图像合成(主页有源码)
  • PHP培训机构教务管理系统小程序源码
  • CF1801D
  • ffmpeg configure 研究2:分析屏幕输出及文件输出的具体过程
  • 洛谷B2139
  • 解析Uniprot数据库数据|Python
  • PrimeFaces实战:IdleMonitor与Ajax的完美结合
  • Linux之kernel(1)系统基础理论(4)
  • 鸿蒙第三方库MMKV源码学习笔记
  • Redis字符串常见命令(String)
  • 深入浅出C语言内存模型——高阶篇
  • springboot-ffmpeg-m3u8-convertor nplayer视频播放弹幕效果
  • WIN系统服务器如何修改远程端口?
  • 人工智能学习环境配置
  • qt for android release apk 手动签名方式
  • 如何使用Spark SQL进行复杂的数据查询和分析