Chapter4 分布式数据库HBase

4.1概述

4.1.1从BigTable说起

HBase是BigTable的开源实现。
BigTable是一个分布式存储系统,它最初是用于解决谷歌公司内部的大规模网页所搜问题。

网页搜索可以分为两个阶段:
1.第一阶段:建立整个网页的索引。
通过爬虫不断的抓取各个网站的页面,将网页的每页一行存储到BigTable中。
在BigTable上运行MapReduce,MapReduce计算作业运行在整张表上,会生成索引,保证能够快速搜索相关网页。
2.第二阶段:搜索互联网网页。
搜索引擎接收用户发起的查询请求。
网络搜索应用通过查询建立好的索引,从BigTable得到网页。
最后将网页搜索结果返回给用户。

BigTable诞生之初主要就是满足互联网搜索引擎的基本需求。但现如今,BigTable作为分布式存储系统,不止用于网页搜索,还用于谷歌非常多的项目中,包括搜索、地图、财经、打印,以及一些社交网站、视频共享网站、博客系统等。

BigTable并非直接将底层磁盘作为存储,它是架构在GFS(谷歌分布式文件系统)基础之上的,并使用GFS作为底层数据存储。并且采用Chubby提供的协调管理服务。
Chapter4 分布式数据库HBase_第1张图片
BigTable受到广泛关注的原因包括:
1.它具有非常好的性能,可以支持PB级别的数据。
2.它具有非常好的可扩展性,可以用集群去存储几千台服务器,完成分布式存储。

4.1.2HBase简介

HBase是一个高可靠、高性能、面向列、可伸缩的分布式数据库。
相比于只能存储完全非结构化数据的底层分布式文件系统,HBase可以用来存储非结构化和半结构化的松散数据。并且HBase的目标是通过水平扩展的方式,允许几千台服务器去存储海量文件,实现庞大的存储规模。

HBase和BigTable的底层技术对应关系如下:
Chapter4 分布式数据库HBase_第2张图片
关系型数据库已经流行许多年了,况且Hadoop已经有了HDFS和MapReduce,为什么需要HBase?

  1. Hadoop可以解决大规模数据的离线批量处理问题,但是Hadoop受限于Hadoop MapReduce编程框架的高延迟数据处理机制,随着数据的大规模爆炸式增长,Hadoop没有办法满足大规模数据实时处理的需求。
  2. 传统的关系型数据库的扩展能力非常有限,对大规模数据的存储能力不够。即使分库分表,也不能很好解决数据规模剧增导致的系统扩展性和性能问题。
  3. 传统的关系数据库可以应对一定的数据结构变化,但是需要进行停机维护。
  4. HDFS面向的是批量访问模式,而非随机访问模式。

HBase与传统的关系数据库的主要区别有哪些?

  1. 数据类型方面
    传统的关系数据库使用的是经典的关系数据模型,具有丰富的数据类型和存储方式。
    而HBase采用了更简单的数据模型,把数据存储为未经解释的字符串,需要依靠程序开发人员解释数据类型。
  2. 数据操作方面
    关系数据库中定义了非常多的数据操作,比如更新、删除、查询、多表连接等。
    而HBase只有简单的插入、查询、删除、清空等操作,避免了复杂的表与表之间的关系。
  3. 存储模式
    关系数据库基于行模式存储。
    而HBase基于列存储,每个列族都由几个文件保存,不同列族的文件是分离的。
  4. 数据索引
    关系数据库可以直接针对各个不同的列,构建非常复杂的索引,以快速定位到相关记录。
    而HBase只支持对行键进行索引,所有访问方法,要么通过行键访问,要么通过行键扫描。
  5. 数据维护
    在关系数据库中进行数据更新操作的时候,原来的旧值会被新值替换掉。
    而HBase不存在替换操作,不会擅长旧的版本,而是生成一个新的版本,并且每生成一个新版本就会生成一个时间戳标识新版本。直到过了设置的期限之后,系统才会在后台把它清理掉。
  6. 可伸缩性
    关系数据库很难实现水平扩展,最多实现纵向扩展,比如增加CPU、单核变双核、双核变四核、增加内存条、增加磁盘。但纵向扩展的空间也是有限的。
    而HBase借助于分布式集群存储海量数据,能够轻易的通过在集群中增加或者减少硬件数量来实现性能的伸缩。
4.1.3HBase访问接口

Chapter4 分布式数据库HBase_第3张图片

类型 使用场合
原生Java API Hadoop MapReduce作业并行批处理HBase表数据
Shell命令 HBase管理使用
Thrift Gateway方式 其他异构系统在线访问HBase表数据
REST Gateway 支持REST风格的Http API访问HBase
Pig 数据统计
数据仓库产品Hive 以类似SQL语言的方式访问HBase

4.2HBase数据模型

4.2.1HBase数据模型概述

HBase是一个稀疏的多维度的排序的映射表。这张表的索引是四个元素:行键、列族、列限定符、时间戳。
Chapter4 分布式数据库HBase_第4张图片
HBase中,每一个值都是未经解释的字符串,也就是Bytes数组。

用户在表中存储数据时,一个行可以有一个行键和任意多个列。

表的水平方向由一个或多个列族组成,一个列族可以包含任意多个列,相同列族中的数据存储在一起。

列族支持动态扩展(增加、减少等),因此无序事先定义好列的数量和类型。

HBase执行数据更新操作时,会保留旧的版本。这是因为HBase基于HDFS存储数据,而HDFS只支持追加不支持修改。所以HBase只能生成一个新的版本并追加时间戳,然后根据时间戳找到新的版本。

HBase中很多数据是冗余存储的,通过牺牲空间追求更高的效率。

4.2.2基本概念

表:HBase使用表组织数据,表由若干个行和列构成,每个列可以包含多个列族。
行:每个行由唯一的标识符rowKey(行键)来标识。
列族:列族是HBase存储的基本单元,不同列族存储在不同文件中。一个HBase表被划分成多个列族的集合,列族是基本的访问控制单元。
列限定符(列):列族中的数据通过列定位。
单元格:是具体存储数据的地方。通过行、列族、列,就可以唯一的确定一个单元格。单元格中存储的数据类型都是未经解释的字符串。
时间戳:数据需要更新,新的版本会通过时间戳进行区分。因此一个单元格中有很多版本的数据保存在系统中。
Chapter4 分布式数据库HBase_第5张图片
数据坐标:在传统关系数据库中,只需要通过行、列两个维度就可以确定唯一数据(如Excel)。而HBase采用四维坐标定位,必须确定行键、列族、列限定符、时间戳。
Chapter4 分布式数据库HBase_第6张图片

4.2.3概念视图和物理视图

在设计HBase 的时,在概念上和底层的存储是有区分的。

HBase数据的概念视图举例如下:
在这个例子中,仅仅有一个行键"com.cnn.www",唯一的标识一行。在行键中可能包含多个列族,在这里第一个列族是contents、第二个列族是anchor。一个列族也可以包含多个列,在这里t1、t2、t3对应的是contents列族。
每一行在不同的时间版本插入数据时,并不是插入所有的相关列。比如在t1时,只在列族contents下面的html列中有数据。在t5时间戳下,只在列族anchor下有数据,anchor:cnnsi.com=“CNN"表示的是:anchor是列族、cnnsi.com是列的名称、存储的内容是"CNN”。
Chapter4 分布式数据库HBase_第7张图片
从上面的概念视图中,可以看到HBase是稀疏表,很多单元是空的。然而,在底层中,HBase并不是以这种方式存储的。

HBase数据的物理视图举例如下:
在底层存储时,以列族为单位存储,把行键、时间戳、列族单独拿出来存储。
底层物理存储并没有像上面一样,存储很多空值。
Chapter4 分布式数据库HBase_第8张图片

4.2.4面向列的存储

HBase的存储方式和传统的关系型数据库的存储方式是存在很大区别的。传统的关系数据库采用面向行的方式进行存储,而HBase采用面向列的方式进行存储。
Chapter4 分布式数据库HBase_第9张图片
面向行的存储的优点:

  1. 对于传统的事务型操作,需要每次插入一条数据的时候,比如一条购物记录。一次会写入一条完整的记录,将购物记录的各项信息存入数据库。
  2. 采用面向行存储的原因是之前我们使用的大都是OLTP(事务型操作)系统,每一次都生成一个完整的记录。需要一次写入完整字段。

面向行的存储的缺点:

  1. 对于行式存储来讲,如果想分析某一列数据,为了得到这一列数据,必须先扫描数据库中第一行,再扫描第二行。便利整个数据库才能得到完整的列数据。
  2. 目前通常是针对某一列进行分析,使用行式存储代价过大。
  3. 而列式存储通常是按一个列去存储,且每列中的数据类型通常是相似的,所以可以带来很高的数据压缩率。这是行式做不到的,因为行式存储,一行中的不同字段的差别非常大,不可能达到很高的数据压缩率。

如果事务型操作比较多 -> 使用行式存储
如果企业以分析型应用为主 -> 使用列式存储

HBase数据库采用列式存储。

4.3HBase实现原理

4.3.1HBase的功能组件

HBase包括三个最核心的功能组件:

  1. 库函数:通常用于链接每个客户端
  2. Master服务器:充当管家的作用
    Master服务器可以实现对HBase表中的分区信息进行维护和管理。
    Master服务器维护了一个Region服务器列表,通过它可以知道整个集群中有哪些Region服务器在工作。
    Master服务器也负责对Region进行分配,一个表要进行分区分成多个Region,每个Region被分配到哪个Region服务器上由它决定。
    Master服务器还负责负载均衡。
  3. 多个Region服务器:负责存储不同的Region
    一个大的表会被分成多个不同的Region,这个Region就由Region服务器进行维护和管理。
    客户端要访问数据的时候,也是直接和Region服务器进行数据的存取(客户端不会直接从Master处获取数据,一般是直接获得整个Region的位置信息后,直接和相应的Region服务器交互。)
    客户端并不依赖Master获取位置信息,而是通过Zookeeper获取Region位置信息。大多数客户端甚至从不和Master通信,减小了负载。
4.3.2表和Region

一个HBase表在起初数据量很小,只有一个Region。但是,随着数据不断的增加,Region会逐渐增大,增大到一定程度后,一个Region会分裂成多个新的Region。并且这种分裂过程是十分迅速的,在分开的瞬间修改数据的指向信息即可,实际的数据还是存储在旧的Region中,访问的时候还是访问旧的Region中的数据。一直到合并过程,把存储文件异步的写到独立的文件之后,才会读取新的文件。
Chapter4 分布式数据库HBase_第10张图片
在2006年之前,Region大小为100MB到200MB。但是到目前,一个Region的最佳大小配置为1GB到2GB。
注意,拆分时对于同一个Region,不会被拆分到不同的Region服务器上去。
Chapter4 分布式数据库HBase_第11张图片

4.3.3Region的定位

HBase设计了三层结构实现Region的寻址和定位,实现原理如下:

  1. 构建一个元数据表,假设这个元数据表只有两列。第一列是Region的id,第二列是Region服务器的id。
  2. HBase最开始构建时有一个映射表,这个映射表被称为.META.表(用于存储元数据)。
  3. 随着Region的不断分类,映射条目逐渐增多,使得.META.表也需要分成多个Region进行存储。
  4. 为了记录所有元数据的具体位置,还需要另外一个表——根数据表(-ROOT-表)。但注意,HBase不允许-ROOT-表进行分裂,-ROOT-表最多只能有一个Region。
  5. -ROOT-表的地址在程序中是被写死的,在Zookeeper文件中记录了-ROOT-表的位置。

Chapter4 分布式数据库HBase_第12张图片
HBase的三层结构中各层次的名称和作用:
Chapter4 分布式数据库HBase_第13张图片
为了加快访问速度,.META.表的全部Region都会被保存在内存中。

假设.META.表的每行(一个映射条目)在内存中大约占用1KB,并且每个Region限制为128MB。那么,上面的三层结构可以保存的用户数据表的Region数目的计算方法是:

(-ROOT-表能够寻址的.META表的Region个数) x (每个.META.表的Region可以寻址的用户数据表的Region个数)

一个-ROOT-表最多只能有一个Region,也就是最多只能有128MB,按照 每行(一个映射条目)占用1KB内存计算,128MB空间可以容纳 128MB/1KB=217行。
也就是说,一个-ROOT-表可以寻址217个.META.表的Region。
同理,每个.META.表的 Region可以寻址的用户数据表的Region个数是
128MB/1KB=217
最终,三层结构可以保存的Region数目是(128MB/1KB) × (128MB/1KB)= 234个Region。这个数目远远超过企业的实际需求。

客户端访问数据时的"三级寻址":为了加速寻址,客户端会缓存位置信息。同时,需要解决缓存失效问题(采用惰性机制,只有发现某个缓存不能正确找到数据的时候才会更新缓存,使用三级寻址找到Region的ID再次缓存下来)。

4.4HBase运行机制

4.4.1HBase系统架构

从HBase系统架构示意图课件,HBase的数据存储并非直接和底层存储打交道,而是借助于HDFS完成数据存储的。
Chapter4 分布式数据库HBase_第14张图片
1.客户端:包含访问HBase的接口。并且为了加快访问速度,客户端会在自己的缓存中维护已经访问过的Region位置信息。

2.Zookeeper服务器:实现协同管理服务。被大量用于分布式系统,提供配置维护、域名服务、分布式同步服务。在HBase中,作为管家存在,负责维护和管理整个HBase集群,可以帮助选举出一个Master作为集群的总管,并保证任何时刻总有一个唯一的Master在运行,避免了Master的单点失效问题。
Chapter4 分布式数据库HBase_第15张图片
3.Master(主服务器):负责整个HBase中表及Region的管理工作,包括管理用户对表的增删改查、对不同的Region服务器进行负载均衡、负责调整分裂/合并后Region的分布、负责重新分配故障/失效的Region服务器。

4.Region服务器:负责用户数据的存储和管理。用户读数据的时候就是和Region服务器交互。

4.4.2Region服务器工作原理

每一台Region服务器中可以存储10~1000个Region,这些Region共用一个公用的HLog文件。在进行存储时,每一个Region中的每一个列族会构成一个单独的Store,注意Store中的数据不是直接写到底层,而是先写入缓存MemStore中,缓存满了之后再刷新写入StoreFile(在底层借助HDFS存储,文件格式是HFile)中去。
Chapter4 分布式数据库HBase_第16张图片
用户数据读写过程
1.写数据:

  • 用户写入数据时,需要去被分配到的相应的Region服务器上执行。
  • 首先写入到缓存MemStore中。 为了保证数据的安全和恢复性,还要写日志到HLog中。
  • 只有保证HLog中的数据已经被完整的写入磁盘后,才允许调用返回给客户端。

2.读数据:

  • 读数据时,Region服务器也会首先访问MemStore缓存,因为最新的数据都在MemStore中,而非磁盘的StoreFile中。
  • 如果在MemStore缓存找不到,再去磁盘的StoreFile中找相关数据。

缓存的刷新
系统会周期性的把MemStore缓存里的内容刷写到磁盘的StoreFile文件中,清空缓存,并在HLog日志中写入一个标记。
由于每次刷写都生成一个新的StoreFile文件,因此每个Store包含多个StoreFile文件。
每个Region服务器都有一个自己的HLog日志文件(是所有Region公用的),每次启动时都检查该文件,确认最近一次执行缓存刷新操作之后是否发生新的写入操作。如果发现更新,则先写入MemStore,再刷写到StoreFile,最后删除旧的HLog文件,开始为用户提供服务。

StoreFile的合并
由于每一次刷写都会生成一个新的StoreFile,如果数量非常多,会影响查找速度。
当StoreFile数目达到一定程度的时候,会合并成一个大的StoreFile。
这种合并是非常耗费资源的,只有磁盘中刷写生成的StoreFile数量达到一定阈值后,才会启动合并操作。

然而,StoreFile可能会随着合并不断增大。大到一定程度的时候又会触发分裂操作(HBase的Region分裂就发生在这里)。一个父Region被分裂成两个子Region。
Chapter4 分布式数据库HBase_第17张图片

4.4.3HLog工作原理

HBase通过构建一个集群去管理数据,是典型的分布式环境,底层又是非常廉价的低端机,因此故障是难免的,并且必须采取手段应对故障。HBase中采用日志HLog保证系统恢复。
HBase为每个Region服务器配置了公共的HLog文件(是一种预写式日志),用户更新数据时必须先写入日志,然后才能写入MemStore缓存。直到MemStore缓存内容对应的日志已经写入磁盘,缓存内容才能被刷写磁盘。
ZooKeeper负责监视Region服务器集群,当它发现某个Region服务器发生故障的时候,会通知Master。
Master会处理故障Region服务器遗留的HLog文件(包含故障Region服务器上各个Region的日志记录)。
由于多个Region共用一个HLog,所以需要根据每条日志记录所属的Region对象,对HLog数据进行拆分,分别放到相应Region对象的目录下。然后将失效的Region重新分配到可用的Region服务器中,并把与该Region对象相关的HLog日志记录发送给相应的Region服务器。
Region服务器领取到分配给自己的Region对象以及相关的HLog记录之后,会重新执行一遍日志记录中的各种操作,把日志记录中的数据写入到MemStore缓存中,然后刷新到磁盘的StoreFile文件中,完成数据恢复。

一个Region服务器中所有Region共用一个HLog日志:
优点是可以提高对表的写操作性能。
缺点是一旦发生故障,进行恢复的时候需要进行日志拆分。

4.5HBase应用方案

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

1.行键
HBase中按照行键索引数据,而行键按照字典序存储。因此可以把最近可能被访问的数据放在一起,举例如下:
如果想把时间靠近的数据都存在一起,可以考虑将时间戳作为行键的一部分,然而按照升序排序的话,越到后面时间戳会越来越大。考虑到长整形变量是64位,可以使用系统最大的整型值减去时间戳,让排序顺序反转。也就是说将Long.MAX_VALUE - timestamp作为行键。这样可以保证最新写的数据可以被很快命中。

2.提升读写性能
如果对实时性要求比较高,想把数据放入缓存中,以提升读写性能。可以在创建表时,通过设置HColumnDescriptor.setInMemory选项为true,就可以把相关的表放到Region服务器的缓存中,根据需要决定是否放入缓存。

3.最大版本
在创建表时,通过设置HColumnDescriptor.setMaxVersions(int MaxVersions),以限制最大版本数。如果仅仅想保存最新版本的数据,将参数设置为1即可。

4.生存时间
在创建表时,通过设置HColumnDescriptor.setTimeToLive(int TimeToLive)设置表中存储数据的生命周期,一旦超过生命周期就成为过期数据,会被系统自动删除。
比如,如果只需要最近两天的数据,可以设置为setTimeToLive(2 * 24 * 60 * 60)

4.5.2HBase性能检测

有四种常用工具可以帮助进行HBase性能检测:
1.Master-status
2.Ganglia
3.OpenTSDB
4.Ambari

Master-status:是HBase自带的工具。通过Web界面的方式可以查询HBase运行状态,直接在浏览器中输入地址即可查看。

Ganglia:是UC Berkeley发起的一个开源集群监视项目,用于监控系统性能,也支持对HBase进行性能监控。

OpenTSDB:可以从大规模的集群中获取相关的性能参数,进行存储索引,然后以可视化的方式提供给管理员。

Ambari:是Hadoop架构上的一个产品,作用是创建、管理、监视Hadoop的集群。

4.5.3在HBase上构建SQL引擎

构建SQL引擎的好处:
1.易使用:目前大部分工作人员还是更了解SQL,SQL也更容易理解。
2.减少编码:SQL语句非常简洁,是非过程语言,可以减少代码量。

在HBase上构建SQL引擎有两种常用方法:

  1. Hive整合HBase
    从Hive0.6.0版本开始,已经具备了和HBase的整合功能,它们的接口互相通信就可以实现对HBase的访问。
  2. Phoenix
    Phoenix是知名的SaaS服务供应商Salesforce的产品。这个Salesforce.com公司开源了一个项目叫Phoenix,它是构建在Apache HBase之上的一个SQL中间层,开发者可以通过它在HBase上执行SQL查询。
4.5.4构建HBase二级索引

二级索引,也称辅助索引。在关系数据库中,可以对学号字段建立主索引(Primary key),然后对姓名和成绩字段构建多个二级索引。

然而,原生的HBase产品不支持对各个列构建相关的索引,默认只支持对行键rowKey进行索引。
因此,在HBase中想访问某一行,仅有三种方式:
1.通过单个行键访问
2.定一个行键的开始点和结束点去访问区间数据
3.只能进行全表扫描,对整个HBase表顺序扫一遍

实际应用中,通常需要针对不同的列构建索引。因此,HBase0.92版本后引入了一个新特性叫做Coprocessor,用于帮助HBase构建二级索引。
一些产品包括:Hindex、HBase+Redis、HBase+solr

Coprocessor解析
利用Coprocessor,可以构建二级索引。
Coprocessor提供了两个实现:endpoint和observer。endpoint相当于关系型数据库的存储过程,而observer相当于触发器。
observer允许在记录put前后做一些处理。因此,可以在插入数据的时候同步写入索引表。在这种情况下,在HBase数据库中就有主表、索引表。索引表是通过Coprocessor机制,额外开发的二级索引(可以针对其他列)
Chapter4 分布式数据库HBase_第18张图片
这种构建方式的优点:非侵入性:引擎构建在HBase之上,既没有对HBase进行任何改动,也不需要上层应用作出任何妥协。
缺点:每插入一条数据需要向索引表插入数据,耗时是双倍的,对HBase集群的压力也是双倍的。

Hindex:是华为公司使用Java开发的,专门针对HBase数据库。支持多个表索引,也支持多个列索引,也支持基于部分列值的索引。

HBase+Redis:Redis是一种键值数据库产品,能高效的管理键值对。由Redis数据库在缓存中管理索引,再定期把索引更新到HBase底层数据中。避免了频繁更新索引引起的耗时等问题。
Chapter4 分布式数据库HBase_第19张图片
HBase+Solr:Solr是高性能、基于Lucene的全文搜索服务器。Solr构建的是其他列和行键rowKey之间的对应关系。通过输入其他列中某一个值,可以快速找到这一行对应的行键,再根据行键在HBase中查找数据。
Chapter4 分布式数据库HBase_第20张图片

你可能感兴趣的:(#,Hadoop,big,data,hbase,大数据)