Hbase底层原理浅析

Hbase简介
Hbase是一个分布式的、面向列的开源数据库,是Apache下hadoop项目的子项目。不同于一般的数据库,Hbase是一个非常适合于非结构化数据以及海量数据存储的数据库。本文从现行数据库存在的问题,Hbase数据库存储模型及体系结构,Hbase简单使用以及最佳实践者四个角度对Hbase数据库进行简要叙述,使大家对Hbase数据库从底层有一个清晰的认识,以方便后续的使用。目前京东雨人医药同步系统同步日志的信息,处方药订单事件轨迹的信息等都在使用Hbase进行存储。

现行数据存储方式
现行数据库数据存储方式主要包括行式存储和列式存储,在介绍列式存储的优势之前,想要先对行式存储做一个简要说明。通过对比来展现列式存储的优势。
行式存储:即以行作为单元对数据进行存储。应用在当前几乎所有关系型数据库,例如Mysql、oracle等,历史非常悠久,使用非常广泛。
(1)行式存储优点:在建表时,已经做规定好数据长度以及数据类型,结合索引可以进行非常高效的查询。
(2)行式存储缺点:1)浪费存储空间:一个表可能有50多个字段,但是经常用到的可能只有两三个,那么用行式存储这种组织方式,势必导致存储空间存在一定的浪费。2)巨量磁盘IO:在进行数据查询的时候,为了存取速度,数据库会一次性读取若干条数据交给客户端,在客户端进行筛。例如,在执行select rx_status from rx_info ,我们需要的只是rx_status这个字段,但是数据库却把50个字段的数据全部交给客户端,客户端再从整行数据中选出rx_status(订单状态),这个操作会带来巨量的磁盘IO。所以在对少许列查询时,关系型数据库优势不大。3)对于传统的行式数据库,在进行海量数据的存储及检索时,几乎是无能为力的。
Hbase列式存储则通过另一种数据组织形式解决了行式存储的缺点,下面透过“逻辑模型”、“物理模型”、“存储模型”三个存储模型,展示出Hbase强大的存储优势及查询优势。

Hbase存储模型及体系结构
逻辑模型:表示数据在逻辑概念上的存储方式,逻辑模型的概念主要为了我们能对数据组织方式方便的进行理解。结合下标,对行、行键、列、列簇、时间戳进行说明。行:即广义理解的行。行键(123.abc.DEF):类似于关系型数据库的主键,不存在两个行键完全相同的行建。列(B):广义的列,但是不能脱离列簇而单独存在,例如列簇B存在两列,其中列”bbb”的值为”eee”。列簇(Colums “B”):列的集合,每一个列簇就是一个文件。时间戳(Timsstamp):数据插入到Hbase表中的时间,取数据库的时间。天然存在的,只要创建Hbase表就会有时间戳概念。
在这里插入图片描述
物理模型:表示数据实际存储时的方式。列簇:单独存储一系列列的文件。Hbase在进行数据存储时,会前进行了大小比较,最终是按照行键进行存储的(Mysql 存储时按照插入顺序存储)。数据真实的存储方式见下图。
在这里插入图片描述

存储模型:表示数据在分布式环境下的存储方式,只有明白这个知识点,才能设计出搜索效率较高的行键。首先,Hbase 面对的数据量是 T、 P级别的,相同量级数据在mysql中直接宕机,在oracle中会非常慢。而Hbase如何做到高效的存储,与他的存储模型有密不可分的关系。Hbase表在行的方向上分割为多个Region,一个region由[startKey,endKey]表示,每个region分散在不同的region server上面。例如0-10000到region1上找,10001-20000到region2上找依次类推,这就实现了高并发快速查询。

在这里插入图片描述
体系结构:表示客户端通过什么样的请求路径来获取所需要的数据。首先,我们称Hbase主节点称为master,从节点称为region server。我们的请求首先发送到master,然后在由master找到对应的region server。这个过程涉及到Hbase中非常重要的两个表:-ROOT-表和.META.表。
.META.表:记录了用户表中的Region信息,.META.可以有多个region。
-ROOT-表:记录了.META.表中的Region信息,-ROOT-中只有一个region Zookeeper中记录了-ROOT-表中的location。
Zookeeper:客户端访问用户表数据之前,首先需要访问zookeeper,然后访问-ROOT-表,接着访问.META.表,最后才能找到准确的位置去获取数据。
总结:逻辑模型清晰的向用户展示了Hbase对于数据的管理方式,实现了列式存储,可以用最小的代价获取所需要的数据;物理模型展示了Hbase数据库如何实现对存储空间最大化的利用;存储模型展示了Hbase如何对数据进行分片管理,解决了大数据存储及海量数据搜索的问题;体系结构则向我们展示了Hbase再进行高效的数据检索时的步骤。

简单使用
结合雨人医药同步系统对操作日志的存储,简单说明Hbase的存储方式
Rowkey设计:“时间戳:仓库id:业务id:消息主题:uuid”。
增:通过 put.add方法加载数据,顺序为列簇(info),列名(name\city),value内容。创建Put类方法传rowkey

Put put = new Put(Bytes.toBytes("rowKey"));   
put.add(Bytes.toBytes("info"), Bytes.toBytes("storeId"), Bytes.toBytes("631")); 
put.add(Bytes.toBytes("info"), Bytes.toBytes("topic"), Bytes.toBytes("product"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("businessId"), Bytes.toBytes("123"));

删:通过传递将要删除的行的rowKey的字节数组格式,实例化Delete类。也可以通过构造时间戳和Rowlock。

Delete delete = new Delete(toBytes("row1"));
delete.deleteColumn(Bytes.toBytes("info"), Bytes.toBytes("storeId"));
delete.deleteFamily(Bytes.toBytes("info"));

查:主要有get操作、scan操作、filter过滤器。其中get操作值获取一条记录,scan和filter结合使用获取多条记录。
获取行键为rowkey的记录。

Get get=new Get(rowkey.getbytes());
Result get1=htable.get(get);
get1.getValue(Bytes.toBytes("info"), Bytes.toBytes("storeId"));
    
获取开始行为rowkey1,结束行为rowkey2,行键包含product的数据
Scan scan = new Scan();
Filter filter= new RowFilter(CompareFilter.CompareOp.EQUAL,new SubstringComparator
(":" + product + ":"));
scan.setStartRow(rowkey1.getBytes());
    scan.setStopRow(rowkey2.getBytes());
    scan.setFilter(filter);

最佳实践
分页:Hbase分页分为服务端分页和客户端分页。服务端分页使用的是FilterPage过滤器,他表示的是一个偏移量。客户端分页是将所有符合查询条件的数据一次性取出,在客户端利用程序进行分页。所以当想获取某一页的数据时,单靠服务端分页方式不容易实现,当时海量数据时,在客户端分页方式势必会对客户端造成不小的压力。作者结合两者的优势,每次从服务器获取pageSizepage调数据。在将数据在客户端进行分页。面对海量数据,可以不必获取海量的数据,又能达到分页的效果。
查询效率:对于特定的数据,尽量用get的方式,不建议用scan+filter的方式进行查询,因为filter过滤器的查询效率非常低。性能并不能满足要求。如果批量获取,一定要为scan赋值开始行和结束行来缩短查询范围。
Rowkey设计:满足长度原则、散列原则、唯一原则
长度原则:建议是越短越好,不要超过16个字节。原因如下。
数据的持久化文件HFile中是按照KeyValue存储的,如果Rowkey过长比如100个
字节,1000万列数据光Rowkey就要占用100
1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;
MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。
目前操作系统是都是64位系统,内存8字节对齐。控制在16个字节,8字节的整数倍利用操作系统的最佳特性。
散列原则:
如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。
唯一原则:
必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值