Hbase学习笔记(二)

来源:互联网 发布:网站cms系统 编辑:程序博客网 时间:2024/06/05 23:42

【Table和Region的关系】

 

table 默认最初只有一个region,随着记录数的不断增加而变大,起初的region会逐渐分裂成多个region,一个region有【startkey,endkey】表示,不同的region会被master分配给相应的regionserver管理, region 是hbase分布式存储和负载均衡的 最小单元,不同的region分不到不同的regionserver。

 

注意:region 虽然是分布式存储的最小单元,但并不是存储的最小单元

 

region 是由一个或者多个store 组成的,每个store就是一个 column family,每个store又由一个memstore和 1至多个store file组成(memstore 到一个阈值会刷新,写入到storefile,有hlog 来保证数据的安全性,一个regionserver 有且只有一个hlog)。

 

【Store】

 

每一个region由一个或多个store组成,至少是一个store,hbase会把一起访问的数据放在一个store里面,即为每个ColumnFamily建一个store,如果有几个ColumnFamily,也就有几个Store。一个Store由一个memStore和0或者多个StoreFile组成。 HBase以store的大小来判断是否需要切分region。

 

【MemStore】

 

memStore 是放在内存里的。保存修改的数据即keyValues。当memStore的大小达到一个阀值(默认64MB)时,memStore会被flush到文件,即生成一个快照。目前hbase 会有一个线程来负责memStore的flush操作。

 

【StoreFile】

 

memStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。

 

【HFile】

 

HBase中KeyValue数据的存储格式,是hadoop的二进制格式文件。 首先HFile文件是不定长的,长度固定的只有其中的两块:Trailer和FileInfo。Trailer中有指针指向其他数据块的起始点,FileInfo记录了文件的一些meta信息。 Data Block是hbase io的基本单元,为了提高效率,HRegionServer中有基于LRU的block cache机制。每个Data块的大小可以在创建一个Table的时候通过参数指定(默认块大小64KB),大号的Block有利于顺序Scan,小号的Block利于随机查询。每个Data块除了开头的Magic以外就是一个个KeyValue对拼接而成,Magic内容就是一些随机数字,目的是防止数据损坏。

【Hlog】

 

HLog文件就是一个普通的Hadoop Sequence File, Sequence File的value是key时HLogKey对象,其中记录了写入数据的归属信息,除了table和region名字外,还同时包括sequence number和timestamp,timestamp是写入时间,sequence number的起始值为0,或者是最近一次存入文件系统中的sequencenumber。 Sequence File的value是HBase的KeyValue对象,即对应HFile中的KeyValue。

 

【LogFlusher】

 

数据以KeyValue形式到达HRegionServer,将写入WAL之后,写入一个SequenceFile。看过去没问题,但是因为数据流在写入文件系统时,经常会缓存以提高性能。这样,有些本以为在日志文件中的数据实际在内存中。这里,我们提供了一个LogFlusher的类。它调用HLog.optionalSync(),后者根据 hbase.regionserver.optionallogflushinterval (默认是10秒),定期调用Hlog.sync()。另外,HLog.doWrite()也会根据hbase.regionserver.flushlogentries (默认100秒)定期调用Hlog.sync()。Sync()本身调用HLog.Writer.sync(),它由SequenceFileLogWriter实现。

 

【LogRoller】

 

Log的大小通过$HBASE_HOME/conf/hbase-site.xml  的 hbase.regionserver.logroll.period限制默认是一个小时。所以每60分钟,会打开一个新的log文件。久而久之,会有一大堆的文件需要维护。首先,LogRoller调用HLog.rollWriter(),定时滚动日志,之后,利用HLog.cleanOldLogs()可以清除旧的日志。它首先取得存储文件中的最大的sequencenumber,之后检查是否存在一个log所有的条目的“sequencenumber”均低于这个值,如果存在,将删除这个log。 每个regionserver维护一个HLog,而不是每一个region一个,这样不同region(来自不同的table)的日志会混在一起,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此可以提高table的写性能。带来麻烦的时,如果一个regionserver下线,为了恢复其上的region,需要将region server上的log进行拆分,然后分发到其他regionserver上进行恢复。

原创粉丝点击