hbase-4
高可用集群搭建
高可用架构搭建
当HMaster出现故障时,再选出一个节点作为HMaster
在conf目录下的创建backup-masters文件
将作为备份的节点添加到该文件中(直接写主机名即可)
num05
num06
将文件分发到其余主机上
重启HBase生效
启动成功后,在备份节点列表中的节点也会启动HMaster服务
网页UI中Backup Masters可以看到备用节点列表
架构模型
client
客户端
Master Server
- 监控RegionServer
- 处理RegionServer故障转移
- 处理元数据变更
- 处理RegionServer的分配或移除
- 在空闲时间进行数据的负载均衡
- 通过Zookeeper发布自己的位置到哭护短
Region Server
- 处理分配给它的Region
- 负责存储HBase的实际数据
- 刷新缓存到HDFS
- 维护HLog
- 执行压缩
- 包含了大量的组件
- Write-Ahead logs
- HFile
- Store
- MemStore
- Region
关键概念
- Region:一个表由多个Region组成,每个Region保存一定的rowkey范围的数据,Region中的数据一定是有序的,是按照rowkey的字典序来排列的
- Store:存储的是表中每一个列族的数据
- MemStore:所有数据都是先写入MemStore,可以使读写操作更快,当MemStore快满的时候,需要有一个线程定期的将数据Flush到磁盘中
- HFile:在HDFS上保存的数据,使HBase独有的一种数据格式(丰富的结构、索引、DataBlock、BloomFilter布隆过滤器…)
- WAL:预写日志,当哭护短连接RegionServer写数据的时候,会先写WAL预写日志,put/delete/incr命令写入到WAL,当某一个RegionServer出现故障时,还可以通过WAL来恢复数据,恢复的就是MemStore的数据
性能调优
列族设计
- HBase列族的数量应该越少越好
- 两个级以上的列族HBase性能并不是很好
- 一个列族所存储的数据达到flush的阈值时,表中所有列族将同时进行flush操作
- 这将带来不必要的IO开销,列族越多,对性能影响越大
数据压缩
压缩算法(参考数据)
压缩算法 | 压缩后占比 | 压缩速度 | 解压速度 |
---|---|---|---|
GZIP | 13.4% | 21MB/S | 118MB/S |
LZO | 20.5% | 135MB/S | 410MB/S |
Zippy/Snappy | 22.2% | 172MB/S | 409MB/S |
- GZIP的压缩率最高,其实CPU密集型的,对CPU的消耗比其他算法高很多,压缩和解压速度也慢;
- LZO的压缩率居中,比GZIP要低一些,但是压缩和解压速度明显要比GZIP快很多,其中解压速度快的更多;
- Zippy/Snappy的压缩率最低,而压缩和解压速度要比LZO快一些
查看数据压缩方式
describe 'table'
默认创建的表没有设置压缩算法
# 创建新表,指定压缩算法
create 'namespace:table',{NAME=>'column-family',COMPRESSION=>'GZ'}
# 修改已有的表,指定压缩算法
alter 'namespace:table',{NAME=>'column-family',COMPRESSION=>'GZ'}
ROWKEY设计原则
HBase官方设计原则
避免使用递增行键/时序数据
如果rowkey设计的都是按照顺序递增,这样会有很多的数据写入时,负载都在一台机器上,造成负载失衡
避免rowkey和列的长度过大(指名称)
- 在HBase中,要访问一个cell,需要有rowkey、列族、列名,如果rowkey、列名太大,就会占用较大的内存空间,所以rowkey和列的长度应该尽量短小
- rowkey的最大长度是64KB,建议越短越好
使用long等类型比String类型更省空间
long类型8个字节,8个字节可以保存非常大的无符号整数,如果是字符串,就按照一个字节一个字符的方式保存,需要多3倍的字节存储
ROWKEY唯一性
- 设计rowkey时,必须保证rowkey唯一性
- 由于hbase数据存储时key-value形式,若向hbase中同一张表插入相同的rowkey数据,则原先存在的数据会被新的数据覆盖
避免数据热点
- 热点是指大量的客户端直接访问集群的一个或几个节点(可能是读,也可能是写)
- 大量地访问量可能会使得某个服务器节点超出承受能力,导致整个RegionServer地性能下降,其他的RegionServer也会受影响
- 解决方案:
- 预分区
- 默认情况下,一个HBase地表只有一个Region,被托管在一个RegionServer中
- 每个Region有两个重要属性:Start Key、End Key,表示这个Region维护的ROWKEY范围
- 如果只有一个Region,那么Start Key、End Key都是空的,没有边界,所有的数据都会放在这个Region中,但当数据越来越大时,会将Region分裂,去一个Mid Key来分裂成两个Region
- 预分区个数等于节点的倍数。默认Region的大小为10G.假设我们预估一年下来的大小为10T,则10000G/10G=1000个Region,所以我们可以预设为1000个Region,这样,1000个Region将均衡的分布在各个结点上
- 预分区
- rowkey避免热点设计
- 反转策略
- 如果设计出的rowkey在数据分布上不均匀,但rowkey尾部的数据却呈现出了良好的随机性,可以考虑将rowkey翻转,或者直接将尾部的bytes提前到rowkey的开头
- 反转策略可以是rowkey随机分布,但是牺牲了rowkey的有序性
- 缺点:利于Get操作,不利于scan操作,因为数据在原rowkey的自然顺序已经被打乱
- 加盐策略
- Salting(加盐)的原理是在原Rowkey的前面添加固定长度的随机数,也就是给rowkey分配一个随机前缀使它和之间的rowkey开头不同
- 随机树保障数据在所有Region间负载均衡
- 缺点:因为添加的是随机数,基于原rowkey查询时无法知道随机数是什么,那样在查询时就需要去各个可能的Region中查找,加盐对比读取是无力的
- 哈希策略
- 基于rowkey的完整或者部分数据进行Hash,而后将Hashing后的值完整替换或部分替换原Rowkey的前缀部分。
- 这里的hash包括MD5、shal、sha256或者sha512等算法
- 缺点:Hashing也不利于Scan,因为打乱了原有的Rowkey自然顺序
- 反转策略
在HBase中,可以指定start key、end key来进行分区,还可以指定Region的数量,指定分区策略
# 指定start key、end key来分区
create 'tab_name','col_family',SPLITS=>['10','20','30','40']
# 指定分区数量 分区策略
create 'tab_name','col_family',{NUMREGIONS=>15,SPLITALGO=>'HexStringSplit'}
-
分区策略:
-
HexStringSplit:RowKey是十六进制的字符串作为前缀的
-
DecimalStringSplit:RowKey是十进制数字字符串作为前缀的
-
UniformSplit:RowKey:前缀完全随机
案例:
# 指定有六个分区,压缩算法为GZ,分区策略为十六进制字符串前缀的
create 'namespace:table',{NAME=>'column-family',COMPRESSION=>'GZ'},{NUMREGIONS=>6,SPLITALGO=>'HexStringSplit'}