Hbase物理存储
物理模型
- 每个column family存储在HDFS上的一个单独文件中,空值不会被保存。
- Key 和 Version number在每个column family中均有一份;
- HBase为每个值维护了多级索引,即:<key, columnfamily, columnname, timestamp>;
- 表在行的方向上分割为多个Region;
- Region是Hbase中分布式存储和负载均衡的最小单元,不同Region分布到不同RegionServer上。
- Region按大小分割的,随着数据增多,Region不断增大,当增大到一个阀值的时候,Region就会分成两个新的Region;
- Region虽然是分布式存储的最小单元,但并不是存储的最小单元。每个Region包含着多个Store对象。每个Store包含一个MemStore或若干StoreFile,StoreFile包含一个或多个HFile。MemStore存放在内存中,StoreFile存储在HDFS上。
Region的数量设计
这里需要提一下,每个regionsServer的region数量不要太多,以免造成RS不响应或其它问题。Region的数量由memstore内存使用情况来决定的,
每个region都有至少一个memstore,这个存储的值可分配,一般来说都是128M-256M范围,每个memstore占堆内存的默认值为40%
以下是region的计算公式。
MemStore
将修改信息缓存在内存当中
信息格式为Cell/KeyValue
当flush触发时,MemStore会生成快照保存起来,新的MemStore会继续接收修改信息,指导flush完成之后快照会被删除
当一个MemStore flush发生时,属于同一个region的memStore会一起flush
MemStore Flush刷入触发机制
MemStore的大小达到单个MemStore阀值
hbase.hregion.memstore.flush.size
RegionServer中所有MemStore的使用率超过RS中MemStore上限值,该Server上所有MemStore会执行flush直到完成或者小于RS中MemStore安全值
hbase.regionserver.global.memstore.upperLimit
或者
hbase.regionserver.global.memstore.size
RegionServer中WAL超过WAL阀值
hbase.regionserver.max.logs
ROOT表和META表
HBase的所有Region元数据被存储在.META.表中,随着Region的增多,.META.表中的数据也会增大,并分裂成多个新的Region。为了定位.META.表中各个Region的位置,把.META.表中所有Region的元数据保存在-ROOT-表中,最后由Zookeeper记录-ROOT-表的位置信息。所有客户端访问用户数据前,需要首先访问Zookeeper获得-ROOT-的位置,然后访问-ROOT-表获得.META.表的位置,最后根据.META.表中的信息确定用户数据存放的位置,如下图所示。
-ROOT-表永远不会被分割,它只有一个Region,这样可以保证最多只需要三次跳转就可以定位任意一个Region。为了加快访问速度,.META.表的所有Region全部保存在内存中。客户端会将查询过的位置信息缓存起来,且缓存不会主动失效。如果客户端根据缓存信息还访问不到数据,则询问相关.META.表的Region服务器,试图获取数据的位置,如果还是失败,则询问-ROOT-表相关的.META.表在哪里。最后,如果前面的信息全部失效,则通过ZooKeeper重新定位Region的信息。所以如果客户端上的缓存全部是失效,则需要进行6次网络来回,才能定位到正确的Region。
一个完整分布式的HBase的组成示意图如下
Hbase高可用
Write-Ahead-Log(WAL)保障数据高可用
由于HBase的数据是先写入内存,数据累计达到内存阀值时才往磁盘中flush数据,所以,如果在数据还没有flush进硬盘时,regionserver down掉了,内存中的数据将丢失。要想解决这个场景的问题就需要用到WAL(Write-Ahead-Log),tableDesc.setDurability(Durability. SYNC_WAL ) 就是设置写WAL日志的级别,该方式安全性较高,但无疑会一定程度影响性能,请根据具体场景选择使用;
我们理解下HLog的作用。HBase中的HLog机制是WAL的一种实现,而WAL(一般翻译为预写日志)是事务机制中常见的一致性的实现方式。每个RegionServer中都会有一个HLog的实例,RegionServer会将更新操作(如 Put,Delete)先记录到 WAL(也就是HLog)中,然后将其写入到Store的MemStore,最终MemStore会将数据写入到持久化的HFile中(MemStore 到达配置的内存阀值)。这样就保证了HBase的写的可靠性。如果没有 WAL,当RegionServer宕掉的时候,MemStore 还没有写入到HFile,或者StoreFile还没有保存,数据就会丢失。或许有的读者会担心HFile本身会不会丢失,这是由 HDFS 来保证的。在HDFS中的数据默认会有3份。因此这里并不考虑 HFile 本身的可靠性。
HFile由很多个数据块(Block)组成,并且有一个固定的结尾块。其中的数据块是由一个Header和多个Key-Value的键值对组成。在结尾的数据块中包含了数据相关的索引信息,系统也是通过结尾的索引信息找到HFile中的数据。
组件高可用
- Master容错:Zookeeper重新选择一个新的Master。如果无Master过程中,数据读取仍照常进行,但是,region切分、负载均衡等无法进行;
- RegionServer容错:定时向Zookeeper汇报心跳,如果一旦时间内未出现心跳,Master将该RegionServer上的Region重新分配到其他RegionServer上,失效服务器上“预写”日志由主服务器进行分割并派送给新的RegionServer;
- Zookeeper容错:Zookeeper是一个可靠地服务,一般配置3或5个Zookeeper实例。