图解HBase--大数据平台技术栈
|
HBase简介 HBase是一个分布式的、面向列的开源数据库存储系统,是对Google论文BigTable的实现,具有高可靠性、高性能和可伸缩性,它可以处理分布在数千台通用服务器上的PB级的海量数据。BigTable的底层是通过GFS(Google文件系统)来存储数据,而HBase对应的则是通过HDFS(Hadoop分布式文件系统)来存储数据的。 HBase不同于一般的关系型数据库,它是一个适合于非结构化数据存储的数据库。HBase不限制存储的数据的种类,允许动态的、灵活的数据模型。HBase可以在一个服务器集群上运行,并且能够根据业务进行横向扩展。 HBase特点 海量存储:HBase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与HBase的记忆扩展性息息相关。正是因为HBase的良好扩展性,才为海量数据的存储提供了便利。 列式存储:列式存储,HBase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定,而不用指定列。 极易扩展:HBase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储能力(HDFS)的扩展。 高并发:目前大部分使用HBase的架构,都是采用廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,主要是在并发的情况下,HBase的单个IO延迟下降并不多。 稀疏:稀疏主要是针对HBase列的灵活性,在列族中,可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间。 HBase与关系型数据库对比 HBase数据模型
物理视图 在物理存储上,数据是以Key-Vaule对形式存储,每个Key-Value只存储一个Cell里面的数据,不同的列族存储在不同的文件中,每个逻辑单元格(Cell)会对应一行数据,有Timestamp标记版本,每次插入、删除都会生成一行数据(append-only,写效率高)。 HBase体系架构 HBase的服务器体系结构遵循简单的主从服务器架构,一般一个HBase集群由一个Master服务(高可用的话,至少两个)和1个或多个RegionServer服务组成。Master服务负责维护表结构信息,实际的数据是保存在RegionServer上,最终RegionServer保存的表数据会直接存储在HDFS上。HBase的体系架构图如下图所示: Master HBase的管理节点,在一个集群中Master一般是主备的,主备的选择是由Zookeeper实现的。 HBase Master主要职责:
RegionServer RegionServer主要负责服务和管理Region。在分布式集群中,建议RegionServer和DataNode按照1:1比例部署,这样RegionServer中的数据文件可以存储一个副本于本机的DataNode节点中,从而在读取数据时可以利用HDFS的"短路径读取(Short Circuit)"来绕过网络请求,降低读延时。 RegionServer内部管理一个或多个Region。Region许多Store组成。每个Store对用Table中的一个列族存储,即一个Store管理一个Region上的一个列族。每个Store包含一个MemStore和0到多个StoreFile。 RegionServer的主要职责:
Zookeeper HBase通过Zookeeper来做Master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:
HDFS HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高可用(HLog)的支持。HBase底层存储并非必须是HDFS文件系统,但是HDFS是最佳选择,也是目前应用最广泛的选择。HDFS具体功能如下:
Client Client使用HBase的RPC机制与HMaster、RegionServer进行通信,Client与Master进行管理类通信,与RegionServer进行数据操作类通信。Client包含了访问HBase的接口,另外Client还维护了对应的cache来加速HBase的访问,比如.META.元数据信息。 RegionServer内部结构
用户写入的数据先写入WAL,然后写入MemStore,当MemStore满了以后会Flush成一个StoreFile(存储为HFile),当StoreFile数量到达一定阈值,会触发Compact合并,将多个StoreFile合并成一个StoreFile。StoreFiles合并后会逐渐形成越来越大的StoreFile,当Region内的所有的StoreFiles的总的大小超过阈值(hbase.hregion.max.filesize)会触发Split操作。会把当前Region Split成两个Region,父Region下线,新Split的两个子Region被Master分配到合适的RegionServer上,使得原先一个Region的压力分流到两个Region上。 Region寻址方式 在进行数据操作的时候,首先要定位需要对哪个Region进行操作,或者从哪个Region上读取数据,因此HBase数据读取的第一步是Region寻址。 Region寻址步骤:
HBase读写流程 HBase写流程
细节: HBase使用MemStore和StoreFile存储对象表的更新,数据在更新的时候首先写入HLog和MemStore。MemStore中的数据时排序的,当MemStore累积到一定阈值时,就会创建一个新的MemStore并将老的MemStore添加到flush队列,由单独的线程flush到磁盘上,成为一个StoreFile。同时,系统会在Zookeeper中记录一个checkpoint,表示这个时刻之前的更新已经持久化了,当系统出现意外时,可能导致MemStore中的数据丢失,此时使用HLog来恢复chckpoint之后的数据。 HBase读流程
在对HBase进行写操作的时候,进行Put和Update操作的时候,其实是新增了一条数据,即使是在进行Delete操作的时候,也是新增一条数据,只是这条数据没有value,类型为DELETE,这条数据叫做墓碑标记(Tobstone)。数据的真正删除是在compact操作时进行的。 WAL机制 WAL(Write-Ahead Log,预写日志)主要用来来解决宕机之后的操作恢复问题的。数据到达Region的时候会先写入WAL,然后再被写入MemStore。就算Region的机器宕掉了,由于WAL的数据时存储在HDFS中的,所以数据并不会丢失,还可以从WAL中恢复。 HLog的生命周期 产生 所有涉及到数据的变更都会先写到HLog中,除非是关闭了HLog。 滚动 HLog的大小可以通过参数hbase.regionserver.logroll.period来控制,默认是1小时,时间达到该参数设置的时间,HBase会创建一个新的HLog文件。这就实现了HLog滚动的目的。HBase通过hbase.regionserver.maxlogs参数控制HLog的个数。滚动的目的是为了避免单个HLog文件过大的情况,方便后续的过期和删除。 过期 HLog的过期依赖于sequenceid的判断。HBase会将HLog的sequenceid和HFile最大的sequenceid(刷新到的最新位置)进行比较,如果该HLog文件中的sequenceid比刷新的最新位置的sequenceid都要小,那么这个HLog就过期了,对应HLog会被移动到/hbase/oldWALs目录。 因为HBase有主从同步的功能,这个是依赖于HLog来同步HBase的变更,所以HLog虽然过期,也不会立即删除,而是移动到别的目录中。再增加对应的检查和保留时间机制。 删除 如果HBase开启了replication,当replication执行完一个HLog的时候,会删除Zookeeper上的对应HLog节点,在HLog被移动到/hbase/oldWALs目录后,HBase每隔hbase.master.cleaner.interval(默认60秒)时间会去检查/hbase/oldWALs目录下的所有HLog,确认对应的Zookeeper的HLog节点是否被删除,如果Zookeeper上不存在对应的HLog节点,那么久直接删除对应的HLog。 hbase.master.logcleaner.ttl(默认10分钟)这个参数用来控制HLog在/hbase/oldWALs目录保留的最长时间。 MemStore刷盘 为了提高HBase的写入性能,当写请求写入MemStore后,不会立即刷盘,而是会等到一定的时候再进行刷盘操作。 发生MemStore刷盘场景: 1. 全局内存控制 当整个RegionServer中所有MemStore占用的内存达到阈值的时候,会触发刷盘的操作。 2. MemStore达到上限 当MemStore占用内存的大小达到hbase.hregion.memstore.flush.size的值的时候会触发刷盘,默认128M。 3. RegionServer的HLog数量达到上限 如果HLog太多的话,会导致故障恢复的时间过长,因此HBase会对HLog的最大个数做限制。当达到HLog的最大个数的时候,会强制刷盘(hbase.regionserver.max.logs,默认32个)。 4. MemStore达到刷写时间间隔 当MemStore达到时间间隔的阈值,会触发刷写操作,hbase.regionserver.optionalcacheflushinterval,默认3600000,即1小时,如果设置为0,则意味着关闭定时自动刷写。 5. 手工触发 可以通过hbase shell或者java api手工触发flush的操作 6. 关闭RegionServer触发 当正常关闭RegionServer会触发刷盘的操作,全部数据刷盘后就不需要再使用HLog恢复数据 7. Region使用HLog恢复完数据后触发 当RegionServer出现故障的时候,其上面的Region会迁移到其他正常的RegionServer上,在恢复完Region的数据后,会触发刷盘,当刷盘完成后才会提供给业务访问。 Region拆分 随着业务的发展,在表中的数据会越来越多,Region会越来越大,这样会严重影响数据读取效率。所以当一个Region变的过大后,会触发Split操作,将一个Region分裂成两个子Region。Region的拆分分为自动拆分和手动拆分两种。 Region拆分流程
为了减少对业务的影响,Region Split过程并不会真正将父Region中的HFile数据搬到子Region目录中。Split过程仅仅是在子Region中创建了到父Region的HFile的引用文件,子Region1中的引用文件指向原HFile的上部,而子Region2的引用文件指向原HFile2的下部。数据的真正搬迁工作是在Compaction过程中完成的。 Region合并 Region的合并分为小合并(Minor Compaction)和大合并(Major Compaction)。 小合并(Minor Compaction) 当MemStore达到hbase.hregion.memstore.flush.size大小的时候会将数据刷写到磁盘,生成StoreFile。随着业务的发展,数据量会越来越大,会产生很多的小文件,对于HBase的数据读取,如果要扫描大量的小文件,会导致性能很差,因此需要将这些小文件合并成一个大一点的文件。 所谓的小合并,就是把多个小的StoreFile组合在一起,形成一个较大的StoreFile,通常是累积到3个SotreFile后执行。通过hbase.hstore.compationThreadhold参数配置,小合并的步骤如下:
这种小合并一般速度比较快,对业务的影响也比较小。本质上,小合并就是使用短时间的IO消耗以及带宽消耗换取后续查询的低延迟。在Minor Compaction过程中,达到TTL(记录保留时间)的数据会被移除,但是由墓碑标记的记录不会被移除,因为墓碑标记可能存储在不同HFile中,合并可能会跨过部分墓碑标记。 大合并(Major Compation) 大合并就是将一个Region下的所有StoreFile合并成一个大的StoreFile文件。在大合并的过程中,之前删除的行和过期的版本都会被删除。大合并一般一周做一次,由hbase.hregion.majorcompaction参数控制。大合并的影响一般比较大,尽量避免同一时间多个Region进行合并,因此HBase通过hbase.hregion.majorcompaction.jitter参数来进行控制,用于防止多个Region同时进行大合并。 具体算法:
RegionServer故障恢复 在Zookeeper中保存着RegionServer的相关信息,在RegionServer启动的时候,会在Zookeeper中创建对应的临时节点。RegionServer通过Socket和Zookeeper建立session会话,RegionServer会周期性的向Zookeeper发送ping消息包,以此说明自己还处于存活状态。而Zookeeper收到ping包后,则会更新对应Session的超时时间。 当Zookeeper超过session超时时间还未收到RegionServer的ping包,则Zookeeper会认为该RegionServer出现故障,Zookeeper会将该RegionServer对应的临时节点删除出,并通知Master,Master收到RegionServer挂掉的信息后就会启动数据恢复流程。 |
时间:2019-07-31 23:39 来源:可思数据 转发量:次
声明:本站部分作品是由网友自主投稿和发布、编辑整理上传,对此类作品本站仅提供交流平台,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,不为其版权负责。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。