1.HBase架构组成
HBase采用Master/Slave架构搭建集群,它隶属于Hadoop生态系统,由以下类型节点组成:HMaster节点、HRegionServer节点,而在底层,它将数据存储于HDFS中。
-
- HMaster节点作用
1.管理HRegionServer,实现其负载均衡。
2.管理和分配HRegion,比如在HRegion split时分配新的HRegion;在HRegionServer退出时迁移其内的HRegion到其他HRegionServer上。
3.实现DDL操作(Data Definition Language,namespace和table的增删改,column familiy的增删改等)。
4.管理namespace和table的元数据(实际存储在HDFS上)。
5.权限控制(ACL)。
1.2 HRegionServer节点作用
1.存放和管理本地HRegion。
2.读写HDFS,管理Table中的数据。
3.Client直接通过HRegionServer读写数据(从HMaster中获取元数据,找到RowKey所在的HRegion/HRegionServer后)。
2. Hbase物理存储
2.1 整体结构
1.Table中所有行都按照row key的字典序排列。
2.Table在行的方向上分割为多个Region。
3.Region按大小分割的,每个表开始只有一个region,随着数据增多,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region,之后会有越来越多的region。
4.Region是Hbase中分布式存储和负载均衡的最小单元,不同的Region分布到不同RegionServer上。
5.Region虽然是分布式存储的最小单元,但并不是存储的最小单元。Region由一个或者多个Store组成,每个store保存一个columns family。每个Strore又由一个memStore和0至多个StoreFile组成,StoreFile包含HFile;memStore存储在内存中,StoreFile存储。
2.2 STORE FILE 和 HFILE结构
HBase的数据最终是以HFile的形式存储在HDFS中的,HBase中HFile有着自己的格式。一次memstore的flush会产生一个HFile,一次Compact会导致多个HFile合并成一个。本文主要讲述一下HFile文件格式,并介绍一些HBase中是如何读取,写出HFile的。通过HBase提供的读/写HFile的reader和writer工厂类,使用者可以直接从HFile文件读取数据,从而绕过HBase提供的Scan、Get、Put等api。
一个region由多个store组成,每个store包含一个列族的所有数据。Store包括位于内存的memstore和位于硬盘的storefile。写操作先写入memstore,当memstore中的数据量达到某个阈值,Hregionserver启动flashcache进程写入storefile,每次写入形成单独一个storefile。当storefile大小超过一定阈值后,会把当前的region分割成两个,并由Hmaster分配给相应的region服务器,实现负载均衡,客户端检索数据时,先在memstore找,找不到再找storefile。
2.4 HLog(WAL log)
WAL 意为Write ahead log,用来做灾难恢复只用,Hlog记录数据的所有变更,一旦数据修改,就可以从log中进行恢复。
每个Region Server维护一个Hlog,而不是每个Region一个。这样不同region(来自不同table)的日志会混在一起,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此可以提高对table的写性能。带来的麻烦是,如果一台region server下线,为了恢复其上的region,需要将region server上的log进行拆分,然后分发到其它region server上进行恢复。
HLog文件就是一个普通的Hadoop Sequence File:HLog Sequence File 的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是写入时间,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。HLog Sequece File的Value是HBase的KeyValue对象,即对应HFile中的KeyValue。
3.RowKey设计原则
3.1 Rowkey长度原则
Rowkey是一个二进制流,Rowkey的长度建议越短越好。
1.数据的持久化文件HFile中是按照KeyValue存储的,如果Rowkey过长,数据量就会很大,这会极大影响HFile的存储效率;
2.MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。
3.目前操作系统是都是64位系统,内存8字节对齐。控制在16个字节,8字节的整数倍利用操作系统的最佳特性。
1.业务有序数据方向(对业务数据进行reverse)
如果Rowkey是按时间戳的方式递增, 建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段, 这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。
必须在设计上保证其唯一性。
Rowkey作为索引原则。
Rowkey是Hbase里面唯一的索引,对于某些查询频繁的限定条件数据需要把其内容存放在rowkey里面。
4. 列族设计原则
4.1 同一个列族里存储相似访问模式的所有数据。
可以理解为关系数据库中一对一关系,一对一关系的两张表,在HBase中可以存储在一张表中,放到不同的列族。
4.2大多数的表,设计一个列族就可以。
在HBase中,高表比宽表性能好,可以设计多张表来满足需求。