Hbase学习总结

Hbase 集群包括三个集群

zookeeper群:zookeeper集群主要用于存储master地址、协调Master和RegionServer等上下线、存储临时数据等等。存储-ROOT-表的RS地址。

Master群: master主要负责region的分配,手动管理操作下发等,一般读写操作不需要经过master集群,所以堆master集群的配置要求不是很高。master集群中也有主从之分,Master是整个集群的发起者,如果Master一旦发生意外停机,整个集群将会无法进行管理操作,所以Master也必须有多个,当然多个 Master也有主从之分,如何区分哪个是主,哪个是从?一旦master主节点挂掉,其他从节点会监控掉,如是会向Zookeeper 中注册master节点,谁先抢占注册,则谁负责主master的功能。

RegionServer群:是真正数据存储的地方,每个RegionServer由若干个region组成,而一个region维护了一定区间rowkey值的数据,

RS 是非副本方式的,在集群中是唯一的,如果其中一个RS挂掉来,RS中内部数据region会被迁移到其他节点。RS服务的单点故障可能会在极小代价下很快恢复,但是一旦停掉的RS上有 -ROOT-或者.META.表的region,那后果还是比较严重,因为数据节点的RS停机,只会在短时间内影响该台RS上的region不可访问,等 到region迁移完成后即可恢复,如果是-ROOT-、.META.所在的RS停机,整个HBase的新的求情都将受到影响,因为需要通过.META. 表来路由,从而寻找到region所在RS的地址。

整个结构如下图:

 

table根据rowkey把表拆分为多个region,region存储在regionserver中,regionserver是存放region的容器,其可以存放不同表的多个region,也可以存放一个表的多个region,一般情况是一个表的region分布式的存放在不同的regionserver中,一个region是保存一个表一定范围的rowkey 数据,一个中该表的列族,一个表可以有多个列族, 一个列族可以保护多个列,一个列里的一个cell存储的是数据为二进制数组形式。rowkey也是以字节数据的形式存储。一个列族的数据存储在一个文件中,不同的列族存储在不同文件中。hbase表尽量见单个列族,因为多个列族存储的数据在不同文件中,这用查询会影响效率。

Hbase读

如何通过hbase客户端快速的定位到RegionServer定位。

首先通过zookeeper快速的找到-ROOT-表的RS地址,通过-ROOT-表找到-meta-表,-meta-表中存储来region与RS的映射地址,通过-meta-表找到region的RS的地址反回该客户端,客户端通过RS的地址可以访问到region实在的RS了。RS地址会缓存在客户端,下次在次访问的时候就不需要在走一边 ZK-->ROOT-表-->-meta-表-->RS-->region的过程来,但是也有存在region地址变更的情况,当region实在RS出现单点故障,完成来region的迁移,或者region的实现来split操作,master分配region到其他的RS上,这些情况下会出现 不能访问region。所以需要在重新在走一遍寻址过程ZK-->ROOT-表-->-meta-表-->RS-->region

为什么会走一个三级索引呢,不直接把-meta-表的数据存储在ZK中呢,其中组要是考虑到ZK的原因,zk不不适合存储大量数,而region是没有限制的,如果存储数据量大会给ZK带来不少的压力。同时增加一级索引并没有带来多少性能影响。所以选择的是三级索引。

整个region寻 址过程大致如下:

https://blog.csdn.net/xgjianstart/article/details/53290155

Client通过三层索引获得RS的地址后,即可向指定RS的对应region进行数据写入,HBase的数据写入采用WAL(write ahead log)的形式,先写log,后写数据。HBase是一个append类型的数据库,没有关系型数据库那么复杂的操作,所以记录HLog的操作都是简单的 put操作(delete/update操作都被转化为put进行)

Hbase写

HLog写入:HLog文件是Rs中的所有region共享一个HLog文件,其记录Rs中对region的所有操作,这是日志写优先方式产生的日志信息。HLog主要是在RS崩溃的时候可以尽可能的恢复数据,这里说是尽量多,因为在一般情况 下,客户端为了提高性能,会把HLog的auto flush关掉,这样HLog日志的落盘全靠操作系统保证,如果出现意外崩溃,短时间内没有被fsync的日志会被丢失。

HLog过期

HLog的大量写入会造成HLog占用存储空间会越来越大,HBase通过HLog过期的方式进行HLog的清理,每个RS内部都有一个HLog监控线程在运行,其周期可以通过hbase.master.cleaner.interval进行配置。

HLog在数据从memstore flush到底层存储上后,说明该段HLog已经不再被需要,就会被移动到.oldlogs这个目录下,HLog监控线程监控该目录下的HLog,当该文 件夹下的HLog达到hbase.master.logcleaner.ttl设置的过期条件后,监控线程立即删除过期的HLog。

menstore 在对hbase客户端进行写操作,把记录操作写到 HLog之后,接下来就是写到memstore 缓存中,每一个store文件中有一块memstore,内存大小可以通过参数设置,当memstore中的数据达到自定的值之后会进行刷盘操作,把menstore中的数据持久化到磁盘中,刷盘操作一次会在hdfs上生成一个Hfile 文件。

memstore 继续刷盘操作 有几种方式:

1、当系统总体内存利用率比较高的时候而还没有达到memstore刷盘大小的时候,会进行刷盘操作,因为如果不进行刷盘操作的话,会产生内存溢出oom的情况。但是也不是一直刷盘下去,当系统总体内存达到指定的内存大小的时候,会停止刷盘操作。主要是防止长时间的刷盘操作,影响总体性能。在进行刷盘操作的时候,region是停止写操作的。

2.手动调用api实现刷盘删除。

3.当menstore中的内存使用达到指定的参数值的时候就进行刷盘操作。

menstore进行刷盘操作的时候,其region是解决访问的。而且每次一刷盘操作,都会在生成一个持久化Hfile文件,如果刷盘操作频繁,会在hdfs上产生许多小Hfile文件,许多小文件会影响查询性能,于是有来compact操作,把小文件合并为大文件。

compact操作有2种,minor compact和major compact。

minor compact 操作是把列族下 Hfile文件大小小于指定值并且这种文件达到一定数量的时候进行的minor compact 操作。

major compact 操作是把同一个列族下的所有Hfile文件合并为一个大的Hfile文件,同时把那些之前进行delete操作标记过的文件,还有那些过期的的文件进行删除。major compact是一个比较长的过程,对底层I/O的压力相对较大。

compact操作都有特定的线程进行,一般情况下不会影响RS上数据写入的性能,当然也有例外:在compact操作速度跟不上region中 HFile增长速度时,为了安全考虑,RS会在HFile达到一定数量时,对写入进行锁定操作,直到HFile通过compact降到一定的范围内才释放 锁。

compact 操作不断的把小的Hfile文件合并为大的Hfile文件,Hfile文件会不断变大,许多的小Hfile文件操作读影响性能,同样大Hfile文件也影响性能,对应大的Hfile文件在查找rowkey的时候也会变慢,所以hbase提供来split功能,把大的hfile文件拆分为两个相同大小的Hfile 文件。个较大的region通过split操作,会生成两个小的region。

HBase设计

表的设计

Rowkey设计

 表的rowkey在hbase中是根据字典顺序进行排序的,为了防止热点问题,数据往其中一台RS放,需要合理的设计好rowkey。所以在rowkey的头部不要出现有阶段性相同的作为key ,例如时间,ip 手机号码等。可以采用逆转或者md5杭州hash作为头部。

      列簇设计

列族设计尽量设计为一个列族,因为不同列族是在底层的文件是分开存储的,如果采用多个列族,查询的话会去不同的文件中查询,这明显比在去同一个文件中查询速度慢。所以为来提高查询性能,设计列族的时候尽量设计为单列族。

TTL设计

选择合适的数据过期时间也是表设计中需要注意的一点,HBase中允许列簇定义数据过期时间,数据一旦超过过期时间,可以被major compact进行清理。大量无用历史数据的残余,会造成region体积增大,影响查询效率。

Region设计

region不能设计得太大,因为设计的太大,major compact操作周期也会很长,长时间的major compact  操作会影响 memstore的刷盘操作,同时major compact 操作周期变长,则对那些已经删除或者过期数据需要清除的不能及时的。这样会对数据的读取速率有影响。

设计小的region,则major compact 操作时间短 而相对较多的major compact 操作,会加快过期数据的清理。

但是设计小的region,就存在region  split 的风险。 而split操作 使region在RS中的重新分配等,这中split操作在是很消耗性能的。

所以这中split操作尽量避免。所以需要设计合适大小的region。

可以在建表的时候,提前设计合适的预分区的数量大小。预先分配足够多的 region数,在region达到上限前,至少有部分数据会过期,通过major compact进行清理后, region的数据量始终维持在一个平衡状态。

而每一个region 中的memstore 需要占用内存,所以需要规划好内存大小。

region数量的设计还需要考虑内存上的限制,通过前面的介绍我们知道每个region都有memstore,memstore的数量与region数量和region下列簇的数量成正比:

一个RS下memstore内存消耗:

Memory = memstore大小 * region数量 * 列簇数量

如果不进行前期数据量估算和region的预分配,通过不断的split产生新的region,容易导致因为内存不足而出现OOM现象。


参考链接:https://blog.csdn.net/xgjianstart/article/details/53290155

https://www.zhihu.com/question/20130759

HBASE中,region server挂了之后,如何把这台server上的region转移到另外的region server上呢?

无论哪种情况,region server都无法继续为它的region提供服务了,此时master会删除server目录下代表这台region server的文件,并将这台region server的region分配给其它还活着的同志。”
这段话摘自淘宝官方对habse原理的介绍(tbdata.org/archives/150)。

我想问,region server既然挂了,那每个region的详细信息也就丢了,又没多个备份,怎么能重新分配给别的region server呢?

小弟刚接触bigtable,如果问题太脑残还请大家不要见笑。

作者:用心阁
链接:https://www.zhihu.com/question/20130759/answer/35406376
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Region Server fail时重新分配Region
其中HFile和WAL都存储在HDFS上,当Region Server fail的时候,数据是不会丢失的,丢失的只是Memstore中尚没有写入HFile的部分。

Region Server宕机后,该服务器所负责的Region就会变成不可用,HMaster就会根据集群的负载状况,将这些Region分配给其他Region Server。

接手的Region Server从Zookeeper上,以及ROOT表和META表上可以找到充分的元数据信息,数据又是存在HDFS上,由于HDFS会保持多个副本,数据也不会丢,那么Region Server只需要根据这些信息组织起内存结构,并获取WAL文件进行重放,就可以最大程度的恢复到原来那台Region Server宕机前的状态。

当然由于Region Server大多和Data Node在一台服务器上,在写入时,也会调用本地的DFSClient写入,数据块会在本机有一个副本,在另外的机架上有一个副本,还有另外一个随机分配的副本,这样在读写时可以保证Data Locality。如果Region Server接手了一个Region,那么大多数数据块不在本地的Name Node上,读写性能会有下降,但会在后续的Compact过程中逐渐将文件写入本地的Data Node,从而恢复Data Locality。







你可能感兴趣的:(hbase)