HBase入门

HBase – Hadoop Database

是一个高可靠性高性能面向列可伸缩的分布式存储系统。

从这个结构图可见,Hadoop HDFS为HBase提供了高可靠性的底层存储支持,Hadoop MapReduce为HBase提供了高性能的计算能力,Zookeeper为HBase提供了稳定服务和failover机制。此外,Pig和Hive还为HBase提供了高层语言支持,使得在HBase上进行数据统计处理变的非常简单,而Sqoop则为HBase提供了方便的RDBMS数据导入功能,使得传统数据库数据向HBase中迁移变的非常方便。

 

HBase访问接口

1. Native Java API,最常规和高效的访问方式,适合Hadoop MapReduce Job并行批处理HBase表数据

2. HBase Shell,HBase的命令行工具,最简单的接口,适合HBase管理使用

3. Thrift Gateway,利用Thrift序列化技术,支持C++,PHP,Python等多种语言,适合其他异构系统在线访问HBase表数据

4. REST Gateway,支持REST 风格的Http API访问HBase, 解除了语言限制

5. Pig,可以使用Pig Latin流式编程语言来操作HBase中的数据,和Hive类似,本质最终也是编译成MapReduce Job来处理HBase表数据,适合做数据统计

6. Hive,当前Hive的Release版本尚没有加入对HBase的支持,但在下一个版本Hive 0.7.0中将会支持HBase,可以使用类似SQL语言来访问HBase

 

HBase数据模型

Table & Column Family

Row Key: 行键,Table的主键,Table中的记录按照Row Key排序

Timestamp: 时间戳,每次数据操作对应的时间戳,可以看作是数据的version number。不推荐将版本较大值设到一个很高的水平 (如, 成百或更多),除非老数据对你很重要。因为这会导致存储文件变得极大。

Column Family:列簇,Table在水平方向有一个或者多个Column Family组成,一个Column Family中可以由任意多个Column组成,即Column Family支持动态扩展,无需预先定义Column的数量以及类型,所有Column均以二进制格式存储,用户需要自行进行类型转换。

HBase是三维有序存储的,是指rowkey(行键),column key(column family和qualifier)和TimeStamp(时间戳)这个三个维度是依照ASCII码表排序的

 

Table & Region

当Table随着记录数不断增加而变大后,会逐渐分裂成多份splits,成为regions,一个region由[startkey,endkey)表示,不同的region会被Master分配给相应的RegionServer进行管理。

-ROOT- && .META. Table

HBase中有两张特殊的Table,-ROOT-和.META.

.META.:记录了用户表的Region信息,.META.可以有多个regoin

-ROOT-:记录了.META.表的Region信息,-ROOT-只有一个region

Zookeeper中记录了-ROOT-表的location

Client访问数据之前需要首先访问zookeeper,然后访问-ROOT-表,接着访问.META.表,最后才能找到用户数据的位置去访问,中间需要多次网络操作,不过client端会做cache缓存优化效率。

 

HBase系统架构

 

Client

HBase Client使用HBase的RPC机制与HMaster和HRegionServer进行通信,对于管理类操作,Client与HMaster进行RPC;对于数据读写类操作,Client与HRegionServer进行RPC

Zookeeper

Zookeeper Quorum中除了存储了-ROOT-表的地址和HMaster的地址,HRegionServer也会把自己以Ephemeral方式注册到 Zookeeper中,使得HMaster可以随时感知到各个HRegionServer的健康状态。此外,Zookeeper也避免了HMaster的 单点问题,见下文描述

HMaster

HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行,HMaster在功能上主要负责Table和Region的管理工作:

1. 管理用户对Table的增、删、改、查操作

2. 管理HRegionServer的负载均衡,调整Region分布

3. 在Region Split后,负责新Region的分配

4. 在HRegionServer停机后,负责失效HRegionServer 上的Regions迁移

HRegionServer

HRegionServer主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBase中最核心的模块。

HRegion

HRegionServer内部管理了一系列HRegion对象,每个HRegion对应了Table中的一个 Region。

HStore

多个HStore组成了HRegion,每个HStore对应了Table中的一个Column Family的存储,可以看出每个Column Family其实就是一个集中的存储单元,因此最好将具备共同IO特性的column放在一个Column Family中是最高效的。HStore由两部分组成,一部分是MemStore,一部分是StoreFiles。 MemStore是Sorted Memory Buffer,用户写入的数据首先会放入MemStore,当MemStore满了以后会Flush成一个StoreFile(底层实现是HFile), 当StoreFile文件数量增长到一定阈值,会触发Compact合并操作,将多个StoreFiles合并成一个StoreFile,合并过程中会进 行版本合并和数据删除,因此可以看出HBase其实只有增加数据,所有的更新和删除操作都是在后续的compact过程中进行的,这使得用户的写操作只要 进入内存中就可以立即返回,保证了HBase I/O的高性能。当StoreFiles Compact后,会逐步形成越来越大的StoreFile,当单个StoreFile大小超过一定阈值后,会触发Split操作,同时把当前 Region Split成2个Region,父Region会下线,新Split出的2个孩子Region会被HMaster分配到相应的HRegionServer 上,使得原先1个Region的压力得以分流到2个Region上。下图描述了Compaction和Split的过程:

 

HLog

上边了解到MemStore优化了写性能,但一旦HRegionServer意外退出,MemStore中的内存数据将会丢失,这就需要引入HLog了。每个HRegionServer中都有一个HLog对象,HLog是一个实现Write Ahead Log的类,在每次用户操作写入MemStore的同时,也会写一份数据到HLog文件中(HLog文件格式见后续),HLog文件定期会滚动出新的,并删除旧的文件(已持久化到StoreFile中的数据)。当HRegionServer意外终止后,HMaster会通过Zookeeper感知到,HMaster首先会处理遗留的 HLog文件,将其中不同Region的Log数据进行拆分,分别放到相应region的目录下,然后再将失效的region重新分配,领取到这些region的HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。

Spring操作HBase

1、maven引入spring-data-hadoop和hbase-client

2、配置

   @Bean
    public HbaseTemplate hbaseTemplate(@Value("${hbase.zookeeper.quorum}") String quorum,
                                       @Value("${hbase.zookeeper.port}") String port) {
        HbaseTemplate hbaseTemplate = new HbaseTemplate();
        org.apache.hadoop.conf.Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", quorum);
        conf.set("hbase.zookeeper.port", port);
        hbaseTemplate.setConfiguration(conf);
        hbaseTemplate.setAutoFlush(true);
        return hbaseTemplate;
    }

3、注入HbaseTemplate 

RowKey设计

row key在HBase中是以B+ tree结构化有序存储的,所以查询起来效率很快

长度原则

rowkey是一个二进制码流,可以是任意字符串,最大长度64kb,实际应用中一般为10-100bytes,以byte[]形式保存,一般设计成定长。

设计太长,一是占存储空间,包括磁盘StoreFile和内存MemStore。现代操作系统都是64位系统,内存8字节对齐,控制在16个字节,8字节的整数倍利用了操作系统的最佳特性,最好不超过16字节。

散列原则

HBase中采用了”Range分区”,将Key的完整区间切割成一个个的”Key Range” ,每一个”Key Range”称之为一个Region。如果rowkey按照时间戳的方式递增,不要将时间放在二进制码的前面,建议将rowkey的高位作为散列字段,由程序随机生成,低位放时间字段,这样将提高数据均衡分布在每个RegionServer,以实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息,所有的数据都会集中在一个RegionServer上,这样在数据检索的时候负载会集中在个别的RegionServer上,造成热点问题,会降低查询效率。

唯一原则

必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。

热点

按照rowkey的字典顺序排序,这种设计优化了scan操作,可以将相关的行以及会被一起读取的行存取在临近位置,便于scan。然而糟糕的rowkey设计是热点的源头。热点发生在大量的client直接访问集群的一个或极少数个节点(访问可能是读,写或者其他操作)。大量访问会使热点region所在的单个机器超出自身承受能力,引起性能下降甚至region不可用,这也会影响同一个RegionServer上的其他region,由于主机无法服务其他region的请求。设计良好的数据访问模式以使集群被充分,均衡的利用。为了避免写热点,设计rowkey使得不同行在同一个region,但是在更多数据情况下,数据应该被写入集群的多个region,而不是一个。下面描述了几个常用的避免热点的方法:

1、加盐:在rowkey的前面增加随机数,具体就是给rowkey分配一个随机前缀以使得它和之前的rowkey的开头不同。分配的前缀种类数量应该和你想使用数据分散到不同的region的数量一致。

2、哈希:哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的rowkey,可以使用get操作准确获取某一个行数据。

3、反转:反转固定长度或者数字格式的rowkey。这样可以使得rowkey中经常改变的部分(最没有意义的部分)放在前面。这样可以有效的随机rowkey,但是牺牲了rowkey的有序性。

手机号反转:13400001111^201803010800 将先导字段Mobile1反转后的RowKey变为:11110000431^201803010800

时间戳反转:用Long.Max_Value - timestamp追加到key的末尾,例如[key][reverse_timestamp],如果需要查询某段时间的操作记录,startRow是[user反转][Long.Max_Value - 起始时间],stopRow是[userId反转][Long.Max_Value - 结束时间]。

其他建议

  • 列族尽可能越短越好,最好是一个字符

  • 冗长的属性名虽然可读性好,但是更短的属性名存储在HBase中会更好

二级索引

对于HBase而言,如果想精确地定位到某行记录,唯一的办法是通过rowkey来查询。如果不通过rowkey来查找数据,就必须逐行地比较每一列的值,即全表扫瞄。对于较大的表,全表扫瞄的代价是不可接受的。所以在多维度查询的时候,二级索引就很有存在的必要了。1需要考虑的问题:1、高性能的范围检索 2、数据的低冗余(存储所占的数据量)3、数据一致性

案例:海量交通数据实时存储

特色:基于LVS的IP虚拟分发技术进行socket通信集群负载,队列缓存处理I/O时延,HBase进行分布式数据存储,ElasticSearch并构建分层索引。

 

取消自动写入,根据实验设置写入缓冲区大小为20 MB,能提高千万级数据同时插入的效率。

预分配region,建表时直接使用预分配region,避免单个region灌入数据。

 

参考:

http://www.infocomm-journal.com/bdr/article/2017/2096-0271/2096-0271-3-1-00080.shtml

https://blog.csdn.net/nuoyahadili8/article/details/51088345

 

posted @ 2018-09-10 19:36  Eric Lan  阅读(178)  评论(0编辑  收藏  举报