- 主从架构的非关系型数据库;
- 面向列簇存储,每个列簇内部数据以key-value格式存放;
- 支持水平扩展、容错性良好;
- 随机读写性能好、数据扫描慢,不适合用作OLAP。
数据模型
每个Namespace包含一组Table,默认有两个Namespace,hbase(如Meta表)、default;
- rowkey:类似主键(但没有数据类型,字符数组保存),唯一标识一行、按序排列。
- column family:定义表时需要指定好,可包含统一存放的无数个动态列(于一个文件);
- column qualifier:可动态指定的列;
- cell:通过rowkey-column family-column qualifier定位一个cell,内有多个timestamp版本、以数组存放的值;
- timestamp:cell内的值的版本号,访问cell时默认只取timestamp最新的值,超过最大版本数时最旧的版本会被剔除。
可看作一个多维映射表:
{
"rowkey_1": {
"column_family_1": {
"column_1": {
"timestamp_1": "value_1",
"timestamp_1": "value_2",
...
}
}
}
}
而在实际存储中,不同版本的数据会重复保存rowkey(为节省空间,应尽可能短):
key CF qualifier timestamp value
-----------------------------------------------------
tom data city 20180101000000 GZ
tom data country 20180101000000 GD
tom data city 20180102000000 SZ
基本架构
- 主从架构,Master与Slave通过ZooKeeper解耦而非直接相连(Master宕机也不至于停止服务);
- HMaster:ZooKeeper选举产生,可多个,无状态(状态信息保存在ZK):
- 协调Region Server:分配Region给Region Server并调整负载、发现失效Region Server并重新分配;
- 元信息管理:管理Region Server的元数据,提供Table的增删改查操作;
- 不参与数据I/O过程。
- Region Server:负责单个Region的存储管理(如按rowkey切分Region),处理Client读写请求;
- ZooKeeper:HMaster与Region Server之间的协调者,存放HBase关键元信息和状态信息:
- 主HMaster选举(并确保只有一个);
- 存储Region寻址入口(Meta表所在Region Server);
- 实时监控Region Server状态并通知HMaster;
- 存储HBase的Schema和Table元数据;
- Client:提供HBase访问接口,与Region Server交互,维护Cache(加快访问速度)。
内部原理
Region定位
HBase的put、get、delete、scan操作基础是Region定位:
- Client访问ZooKeeper,查找Meta表所在的Region Server(rowkey区间与Region存放位置的映射关系);
- Client访问Meta表所在Region Server,获取rowkey所在的Region Server;
- Client访问rowkey所在Region Server,执行rowkey相关操作;
- 首次定位后会缓存Meta表位置,直到Region发生移动。
Region Server
- BlockCache:读缓存(LRU策略);
- MemStore:写缓存(每个Region的每个Column Family都有一个);
- HFile:(支持多级索引)存放实际数据于HDFS;
- WAL:暂存未持久化到HDFS的数据用于错误恢复(先写入内存、再写入HLog)。
模块协作
HBase启动
- HMaster启动,注册到ZooKeeper,等待Region Server汇报;
- Region Server注册到ZooKeeper,并向HMaster汇报;
- HMaster对各个Region Server(包括失效的)数据进行整理,分配Region和Meta信息。
Region Server失效
- HMaster将失效的Region Server上的Region分配给其他节点;
- HMaster更新Meta表以保证数据正常访问。
HMaster失效
- (已配置HA)处于Standby状态的其他HMaster节点选出一个、转为Active状态;
- (未配置HA)数据能正常读写,但不能创建、删除、更改表(Meta表不能更新)。
读写操作
写
- Region Server接收写请求,将数据追加到HDFS上的日志文件(WAL);
- Region Server将数据写入内存MemStore中,更新到HLog,并通知客户端写入成功;
- MemStore内存达到一定阈值就将数据顺序写入HDFS保存成HFile(多级索引支持);
- HFile达到一定阈值,会触发Split机制,Region重新分配;
- HFile小文件太多,会触发Compact机制进行合并(每个Store仅包含一个文件时查询效率才是最高)。
读
需要依次从读缓存BlockCache(最近读取)、写缓存MemStore(最近写入,每个column family都有一个MemStore)、磁盘HFile文件(已持久化)中查找数据,合并返回用户。
Compact
- Minor Compaction:选取一些小的、相邻的StoreFile合并成更大的;
- Major Compaction:将所有StoreFile合并成一个StoreFile,清理无意义数据(被删除、TTL过期、版本号超出范围)。
执行Compact检查:
- 当MemStore被Flush到磁盘;
- 用户执行Shell命令或调用API:compact、major_compact;
- HBase后台线程周期性触发检查。
设计原则
HBase最好看作一个巨大的哈希表,基于键取值,更适用于迭代访问(范围扫描)。
Rowkey
- 基于行键查询,因此使用宽表(包括尽可能多的信息)更有优势;
- 数据按行键排序按范围存储在不同的Region(一个Region Server),可利用时间戳将put、get请求集中在单一Region上(反模式设计),为了使负载分布均匀,进行Salt处理;
- 数据块缓存(最近最少使用LRU),对行键第一部分进行salt处理(对原来的键获其中一部分做Hash取模),同一个数据块中同时获取的数据之间按行键有序排列,数据块缓存中记录相关、命中率更高;
- 行键越短存储消耗越小、读写性能越高,但行键较长时get、scan性能更好;同时也需要顾及可读性(便于发现问题);
- 行键选择不合理可能导致一次查找需要访问多个Region Server,过滤不相关的记录。
Region
- Region数量越多、平均每个Region的memstore空间越少,磁盘冲刷越小,导致更小、更多的HFile和更多较小的合并而性能降低,memstore分区(每个100M);
- Region越大,合并花费时间越多(最大为20G~120G);
- 建议建表时指定Region数量,将Region大小设置为足够大的值,避免自动分片范围不理想影响性能(但数据集只更新最新记录时建议自动分片)。
Column、Column Family
- 列的数量决定了:数据块缓存记录数、进入WAL的数据量、memstore一次冲刷写入记录数、合并所需时间;
- 一个表包括一或多个列簇,列簇有自己的HFile集合,同一个表不同列簇合并其他列簇不受影响;
- 一般不使用多个列簇,除非:一张表中的一部分列操作完成不会改变,或者变化频率与其他列存在显著不同(降低合并成本、更好利用数据块缓存)。
过滤器
为筛选数据提供的过滤器,可以在HBase中的数据的多个维度(行、列、版本)上对数据进行筛选。
- 基于行:PrefixFilter、PageFilter;
- 基于列:ColumnPrefixFilter、FirstKeyOnlyFilter;
- 基于单元值:KeyOnlyFilter、TimestampsFilter;
- 基于列和单元值:SingleColumnValueFilter、SingleColumnValueExcludeFilter。
- 比较过滤器:RowFilter、FamilyFilter、QualifierFilter、ValueFilter。
常用的:
- RowFilter
- PrefixFilter
- KeyOnlyFilter
- ColumnPrefixFilter
- ValueFilter
- TimestampsFilter
- FilterList
(支持自定义过滤器,但不建议使用)
协处理器
- HBase协处理器受BigTable协处理器的启发,为用户提供类库和运行时环境,使得代码可以在HBase Region Server和Master上处理;
- 分为系统协处理器(全局加载到Region Server托管的所有表和Region上,针对整个集群)和表协处理器(用户可以指定一张表使用协处理器,针对表);
- 两种插件:Observer(类似触发器,实现安全性检查、完整性约束、二级索引)和Endpoint(类似存储过程)。
Observer
- RegionObserver:提供客户端的数据操纵事件钩子:Get、Put、Delete、Scan等;
- MasterObserver:提供DDL类型的操作钩子,如创建、删除、修改数据表等;
- WALObserver:提供WAL相关操作钩子。
Endpoint
- 动态RPC插件的接口,它的实现代码被安装在服务器端,从而能够通过HBase RPC唤醒;
- 调用接口,实现代码会被目标的Region Server远程执行;
如对于较大的表(上百个Region)计算某列平均值、求和等操作,使用Endpoint可减少耗时。
加载协处理器
- 配置文件加载:修改配置文件hbase-site.xml加载,系统级别;
- Shell加载:alter命令对表进行Schema修改来加载协处理器;
- 通过API代码加载。
卸载/更新协处理器
必须重启Region Server,即重启JVM;否则重复加载的协处理器实例不会起作用。
容灾
- CopyTable:支持时间区间、Row区间,改变表名称,改变列簇名称,制定是否copy已经被删除的数据等功能;工具采用Scan查询,写入新表时采用put和delete的API(全部是基于Client API进行读写);
- Export/Import:Export将数据到处到目标集群(HDFS)、再用Import导入数据(可指定开始时间与结束时间、作增量备份);
- Snapshot:作用在表上,修改配置文件hbase-site.xml实现,可通过快照迅速修复数据,但会丢失快照之后的数据;
- Replication:通过Replication机制实现HBase主从模式。
监控
-
保证系统的稳定性、可靠性、可运维性;
-
了解集群性能表现,及时做出针对性调整;
-
出现问题时及时报警,快速定位解决问题。
-
利用Hadoop生态圈开源的专业监控工具(Ambari、Cloudera Manager);
-
调用Hadoop和HBase的JMX接口获取检测数据。
Phoenix
- 构建在Apache HBase上的SQL中间层,具备完善的查询支持,且查询效率高;
- 具备完整的ACID事务功能的SQL和JDBC API的强大功能(多租户,二级索引,用户自定义函数,行时间戳列,分页查询,视图);
- 可以与Spark、Hive、Pig、Flume、MR集成;
- 通过HBase协处理器,在服务端进行操作,最大限度减少客户端与服务的的数据传输;
- 通过定制的过滤器对数据进行处理;
- 通过本地HBase API(而非Hive的MR),最大限度降低启动成本。
网友评论