分布式的存储海量非结构化数据的
开源、分布式的、多版本的、可扩展的非关系型数据库
可以做到随机近实时读写数据
依赖于zookeeper

架构

Hbase深入理解
写操作流程
•1、客户端向hregionServer请求写数据
2、hregionServer将数据先写入hlog中。
3、hregionServer将数据后写入memstore中。
4、当内存中的数据达到阈值64M的时候,将数据Flush到硬盘中,并同时删除内存和hlog中的历史数据。
5、将硬盘中数据通过HFile来序列化,再将数据传输到HDFS进行存储。并对Hlog做一个标记。
6、当HDFS中的数据块达到4块的时候,Hmaster将数据加载到本地进行一个合并(如果合并后数据的大小小于256M则当数据块再次达到4块时(包含小于256M的数据块)将最新4块数据块再次进行合并,此时数据块大于256M)。
7、若数据块大于256M,则将数据重新拆分,将分配后的region重新分配给不同的hregionServer进行管理。
8、当hregionServer宕机后,将hregionServer上的hlog重新分配给不同的hregionServer进行加载(修改.META文件中关于数据所在server的信息)。注意:hlog会同步到HDFS中。

可以看出HBase只有增添数据,所有的更新和删除操作都是在后续的Compact历程中举行的,使得用户的写操作只要进入内存就可以立刻返回,实现了HBase I/O的高机能。

读操作流程
•(1) Client访问Zookeeper,查找-ROOT-表,获取.META.表信息。
•(2) 从.META.表查找,获取存放目标数据的Region信息,从而找到对应的RegionServer。
•(3) 通过RegionServer获取需要查找的数据。
•(4) Regionserver的内存分为MemStore和BlockCache两部分,MemStore主要用于写数据,BlockCache主要用于读数据。读请求先到MemStore中查数据,查不到就到BlockCache中查,再查不到就会到StoreFile上读,并把读的结果放入BlockCache。
寻址过程:client–>Zookeeper–>-ROOT-表–>.META.表–>RegionServer–>Region–>client

HBASE的region的拆分策略

当region中storeFile的大小超过了一定的大小后,这个region就会被拆分为两个regioin,父region下线,两个新region放到相应的regionserver中
我们可已定义拆分策略,可以通过设置RegionSplitPolicy的实现类来自定义拆分策略,保证相同RowKey前缀的数据在一个Region中
并不是设置了hbase.hregion.max.filesize(默认10G)为很大就保证不split了
第一次拆分大小为:min(10G,11128M)=128M
第二次拆分大小为:min(10G,33128M)=1152M
第五次拆分大小为:min(10G,99128M)=10G
第五次拆分大小为:min(10G,1111128M)=10G
配置拆分策略
可以在hbase配置文件中定义全局的拆分策略,设置hbase.regionserver.region.split.policy的值即可

rowkey行键设计

数据按照Row key的字典序(byte order)排序存储。设计key时,要充分排序存储这个特性,将经常一起读取的行存储放到一起
长度原则:hbase的rowkey建议是8的整数倍,另外尽量不要太长,尽量别超过16,太长的话,比如占用100个字节的rowkey,1000w条就是10亿字节,将近1g的数据,影响hfile的存储效率,而且会占用memstore的内存过多,系统会缓存更少的数据
散列原则:例如按时间戳方式递增,不要将事件放在前面,建议将高位字段作为散列字段,程序随机生成低位字段为事件字段,可以提高数据均衡分布在每个regionserver实现负载均衡的几率,如果没有散列字段,首字段是时间戳会发生所有数据在一个regionserver上堆积的热点现象,在数据检索时负载会集中在个别regionserver中,降低查询效率
唯一原则: rowkey必须是唯一的
应用场景
针对事务数据rowkey设计
事务数据是带时间属性的,建议将事件存在rowkey中,会提高查询速度,可以按天建表,rowkey就可以只保留时分秒毫秒,4个字节就可以
针对统计数据
也是带时间,但是知道分钟,按天分表,保留小时分钟,两个字节
针对通用
可以按天分表也可单标模式采用自增序列作为唯一主键
支持多条件查询的rowkey设计
scan扫描查询可以通过setCaching和setBatch方法提高速度(空间换时间)
通过setStartRow和setEndRow限定范围,范围越小,性能越高
通过setFilter添加过滤器,分页多条件查询

column family列簇设计

列簇的设计根据业务,被反复修改的数据尽量使用一个列簇也就是单列簇,每个列簇在hdfs上都是有一个hfile的,当某个列簇数据被冲刷时,其他列簇数据也会被一起冲刷,io负担会增大
使用多列簇时把经常一起查询的列放到一个列簇中

热点问题,怎么调整

大量client访问hbase集群一个或者少数几个节点,造成regionserver读写请求过大,负载过大,引起性能下降甚至region不可用,erqitaregionserver负载很小,就造成热点现象
原因: 大量连续编号的rowkey导致大量rowkey相近的记录集中在个别region导致client对个别region访问过多

解决:
在rowkey前面加一个随机数,如果10个region就给10个前缀,rowkey就会分散到各个region上
使用hash前缀
反转rowkey,可以有效的随机rowkey,但是牺牲了rowkey的有序性
尽量减少行和列的大小
在hbase中,value和key一起输出,rowkey名和列明时间戳回忆起传输,rowkey名和列名很大,storefiles的索引会占用大量内存

相关文章: