详细介绍了Hbase各个组件功能,表数据结构
1. 数据模型
1.1 数据模型相关概念
- 表:HBase采用表来组织数据,表由行和列组成,列划分为若干个列族。
- 行:每个HBase表都由若干行组成,每个行由行键(row key)来标识。
- 列族:一个HBase表被分组成许多“列族”(Column Family)的集合,它是基本的访问控制单元。
- 列限定符:列族里的数据通过列限定符(或列)来定位。
- 单元格:在HBase表中,通过行、列族和列限定符确定一个“单元格”(cell),单元格中存储的数据没有数据类型,总被视为字节数组byte[]。
- 时间戳:每个单元格都保存着同一份数据的多个版本,这些版本采用时间戳进行索引。
1.2 数据坐标
HBase中需要根据行键、列族、列限定符和时间戳来确定一个单元格
2. HBase 系统架构
2.1 HBase功能组件
- Client
- 包含访问HBase的接口,同时在缓存中维护着已经访问过的Region位置信息,用来加快后续数据访问过程
- 通过与Zookeeper通信在获得Region的存储位置信息后,直接从Region Server上读取数据
- 与Hmaster通信进行管理类操作
- 一个Master Server
- 维护元数据信息
- 在Region分裂或合并后,负责重新调整Region的分布。
- 对发生故障失效的Region服务器上的Region进行迁移。
- 多个Region Server
- 负责存储和维护分配给自己的Region,处理来自客户端的读写请求
- Region由RegionServer管理。所有用户数据的读写请求,都是和RegionServer上的Region进行交互
- Region可以在RegionServer之间迁移
- Zookeeper服务器
- 选举出一个Master作为集群的总管,并保证在任何时刻总有唯一一个Master在运行,这就避免了Master的“单点失效”问题
- 获得Region位置信息返回给客户端,大多数客户端甚至从来不和Master通信,这种设计方式使得Master负载很小。
2.2 Region Server 概念
- Region :用于存放数据信息
- Store:一个Region由一个或多个Store组成。每个Store对应图中的一个Column Family。
- MemStore:一个Store包含一个MemStore,客户端向Region插入的数据缓存到MemStore。
- StoreFile:MemStore的数据Flush到HDFS后成为StoreFile
- HFile:HBase中keyvalue数据的存储格式,HFile是Hadoop二进制格式文件,实际上是storefile对hfile做了轻量级包装
- HLog:HBase中WAL的存储格式,物理上是Hadoop的sequence file。保证了当RegionServer故障的情况下用户写入的数据不丢失。RegionServer的即可以多个Region共享一个相同的Hlog,也可以每个Region拥有一个Hlog。
2.2.1 Store 工作原理
- Store是Region服务器的核心。
- storefile的数量增长到一定的阈值会触发compact合并操作
- 单个StoreFile过大时,即当前达到Region设置的阈值,会触发split操作,即把当前的region分成2个region
- HBase只是增加数据,更新和删除操作都是在compact阶段做
- 是为了减少同一个Region中的同一个ColumnFamily下面的小文件(HFile)数目,从而提升读取的性能
2.2.2 Hlog工作原理
- 分布式环境必须要考虑系统出错。HBase采用HLog保证系统恢复。
- HBase系统为每个Region服务器配置了一个HLog文件,它是一种预写式日志(Write Ahead Log,WAL)
- 用户更新数据先写入MemStore缓存再写入日志
- 出现故障
- Zookeeper会实时监测每个Region服务器的状态,当某个Region服务器发生故障时,Zookeeper会通知Master
- Master首先会处理该故障Region服务器上面遗留的HLog文件,这个遗留的HLog文件中包含了来自多个Region对象的日志记录
- 系统会根据每条日志记录所属的Region对象对HLog数据进行拆分,分别放到相应Region对象的目录下,然后,再将失效的Region重新分配到可用的Region Server中,并把与该Region对象相关的HLog日志记录也发送给相应的Region Server
- Region Servrt获得分配给自己的Region对象以及与之相关的HLog日志记录以后,会重新做一遍日志记录中的各种操作,把日志记录中的数据写入到MemStore缓存中,然后,刷新到磁盘的StoreFile文件中,完成数据恢复。
2.3 写入操作
- Client通过访问ZK来获取到HBase:meta.的地址信息
- ZK通过访问HBase:meta.表来获取具体的RS返回给Client
- Client端获取到目标地址(RegionServer、Region、Rowkey)后,然后直接向该地址发送数据请求。
- 向指定RS的对应region进行数据写入
- 获取Region操作锁。(读写锁)
- 一次获取各行行锁。
- 写入到MemStore中。(一个内存排序集合)
- 释放以获取的行锁。
- 写数据到WAL中。(Write-Ahead-Log)
- 释放Region锁。
既然是Write-Ahead-Log,为何先写内存再写WAL? 先写内存的原因:HBase提供了一个MVCC机制,来保障些数据阶段的数据可见性。先写MemStore再写WAL,是为了一些特殊场景下,内存中的数据能够更及时的返回。如果先写WAL失败的话,MemStore助攻的数据会被回滚。
- Flush
- 达到Region设置MemStore的阈值
- MemStore占用内存的总量和RegionServer总内存的比值超出来了预设的阈值大小
- HBase定期刷新MemStore
- WALs中文件数量达到阈值
- 通过shell命令分别对一个表或者一个Region进行Flush
- Compaction
Compaction分为Minor、Major两类:
- Minor合并:多个小文件重写为数量较少的大文件。有最少和最大的数量限制,通常会选择一些连续时间范围内的小文件进行合并,受磁盘IO的影响
- Major合并:将Region中的一个列族的所有hfile重写为一个新的hfile,过程如下图
- 扫描所有的Row Key,顺序重写全部数据
- 重写数据的过程中可能删除掉标记过的数据和超出版本号的数据,删不删除根据实际情景而定
- Region Split
- Region的大小超出了预设的阈值,则需要将该Region自动分裂成为两个Region
- 分裂过程中,被分裂的Region会暂停读写服务。父Region的数据文件并不会真正的分裂,而是仅仅通过更改引用方式,来实现快速分裂,即通过新的访问方式访问源文件,HBase后台会自己进行分裂操作
- 客户端册所缓存的父Region的路由信息需要被更新
2.4 读操作
- 客户端发起请求
- Get操作在精准的Key值的情形下,读取单行用户数据。
- Sacn操作时为了批量扫描限定KEy值范围的用户数据。
- Scanner定位Region(读取顺序)
- memstore
- blockacache(每个Region Server只有一个)
- hfile
2.5 Region 概念
- 将一个表的数据按RowKey的范围划分为一个或多个子表,实现分布式存储
- 每个子表在Region Server中被称为
Region
- 每一个Region都关联一个Key值范围,即一个使用StartKey和EndKey描述的区间,其实只需要记录StarKey就完事了
- Region是HBase分布式存储的最基本单元
- Region分为元数据Region以及用户Region两类
- Meta Region记录了每一个User Region的路由信息
补充:hbase:meta表相关介绍
1. 基本介绍
- HBase 0.96 以前
- -root- 表位置信息存放在Zookeeper上,内容为meta的存放信息
- .meta存放在regionserver上,存储用户表的region信息。
- HBase 0.96以后
- 移除root表,用
hbase:meta
代表 .meta 表,hbase:meta
表的存放信息直接存放在zookeeper的/hbase/meta-region-server
上
- 移除root表,用
2. 表内容
2.1 hbase:meta 表结构
存储的是用户的表的region信息
Key:
代码语言:javascript复制Region key的格式是:[table],[region start key],[region id]
Value:
代码语言:javascript复制info:regioninfo: 序列化的当前region的HRegionInfo实例。
info:server:存储这个region的regionserver的server:port
info:serverstartcode:该Regionserver拥用该region的起始时间
2.2 数据访问流程
- 0.9.6以前的版本
Client———>zookeeper———>-ROOT-(单region)—–>.META.————->用户表region
- 0.9.6及以后的版本
Client———>zookeeper——–>hbase:meta———>用户表region
Client的会从Zookeeper找到hbase:meta的位置,然后扫描该表找到我们需要请求的region信息,直接跟存储该region的regionserver建立连接,请求数据,而不是经由master。这些信息会被客户端缓存,避免多次请求
3. Shell操作
Shell 命令操作
参考博客
- HBase原理和设计
- HBase技术原理
4. 预分区
默认情况下,创建一个表,hbase会为其自动分区,即Region Server会不断工作,导致Region Server负载过大,所以比较好的办法是根据业务提前对表进行分区,例如有5个region被多个Region Server管理,在插入数据的时候,会向5个region中分别插入,负载均衡
创建分区的方法:
hbase> create ‘ns1:t1’, ‘f1’, SPLITS => [‘10’, ‘20’, ‘30’, ‘40’]
hbase> create ‘t1’, ‘f1’, SPLITS => [‘10’, ‘20’, ‘30’, ‘40’] hbase> create ‘t1’, ‘f1’, SPLITS_FILE => ‘splits.txt’, OWNER => ‘johndoe’ hbase> create ‘t1’, {NAME => ‘f1’, VERSIONS => 5}, METADATA => { ‘mykey’ => ‘myvalue’ } hbase> # Optionally pre-split the table into NUMREGIONS, using hbase> # SPLITALGO (“HexStringSplit”, “UniformSplit” or classname) hbase> create ‘t1’, ‘f1’, {NUMREGIONS => 15, SPLITALGO => ‘HexStringSplit’} hbase> create ‘t1’, ‘f1’, {NUMREGIONS => 15, SPLITALGO => ‘HexStringSplit’, REGION_REPLICATION => 2, CONFIGURATION => {‘hbase.hregion.scan.loadColumnFamiliesOnDemand’ => ‘true’}} hbase> create ‘t1’, {NAME => ‘f1’, DFS_REPLICATION => 1}
如: 1.create ‘logs’,’info’,SPLITS => [‘20181010’,’20181020’,’20181030’] 2.指定分隔文件 create ‘logs’,’info’,SPLITS => ‘opt/datas/logs_split.txt’ 3.指定多少分区,十六进制字符串分割 create ‘t1’, ‘f1’, {NUMREGIONS => 3, SPLITALGO => ‘HexStringSplit’}