当前位置:   article > 正文

Hadoop大数据系列之NoSql海量数据库Hbase详解原理篇(一)_海量数据库是nosql吗

海量数据库是nosql吗

Hbase的引言

一、什么是Hbase

1、hbase是Apache 组织开源的顶级项目 distributed, scalable, big data store 产品。
2、hbase是Google 的BigTable论文的开源实现。
3、hbase是基于Hadoop的一个NoSQL产品  Column(列存储)类型的NoSQL。
4、hbase是Google BigTable的开源实现, 数据存储于Hdfs上。
5、hbase运行亿级别数据查询时,效率可达到秒级、毫秒级、在线处理、实时的处理。

二、Hbase表的包含

表(Table)
       一个表可以有上亿行,上百万列,面向列:面向列(族)的存储和权限控制,列(族)独立检索。稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
行(Row)
       在表中数据依赖于行来存储,行通过行键来区分。行键没有数据类型,通常是一个字节数组。

列族(Column Family)
       行中的数据通过列族来组织。列族也暗示了数据的物理排列。所以列族必须预先定义,并且不容易被修改。每行都拥有相同的列族,可能有些行的数据为空。列族是字符串和字符的组合,可以在文件系统路径 
中使用。

列标识(Column Qualifier)
       数据在列族中的位置是通过列标识来指定的。列标识不需要预先指定,每行的列标识也不需要相同。就像行键一样,列标识没有数据类型,通常也是字节数组。

单元(Cell)
       单元是行键、列族、列标识的组合。这些数据存储在单元中,被称作单元数据。数据也不需要数据类型,通常也是字节数组。

时间戳(Timestamp)
单元数据是有版本的。版本的区分就是他们的版本号,版本号默认就是时间戳。当写入数据时,如果没有指定时间,那么默认的时间就是系统的当前时间。读取数据的时候,如果没有指定时间,那么返回的就是最新的数据。保留版本的数量根据每个列族的配置。默认的版本数量是3。

三、NoSQL特点

1、部分NoSQL In-Memory 内存型 (Redis)。
2、Schema-Less NoSchema 弱格式 无格式。
3、杜绝表连接。
4、弱化事务,没有事务 (Redis有事务,MongoDB(4.x 没事务 4.x后有事务了)。
5、搭建集群方便。

四、NoSQL分类

1、Key value    类型  redis
2、Document   类型  mongodb
3、Column       类型  HBase Cassandra
4、图                类型  neo4j (金融 知识图谱) 

五、Hbase详细说明

1、它是面向列的存储方式,Hbase中没有库的概念。通过namespace替换库,它是一种数据格式为Key,Value类型的nosql数据库,Value是以Byte[]流存储。
2、Column Famliy:列簇,把具有相同特性的列放在一块,组成一个列簇。一个表可以有多个列簇,而且列簇必须在创建表的是指定Column:列名,存属于列簇,一个列簇下面可以有多个列名,列簇下面的列名可以动态添加。列名需要在添加数据的时候指定。Value:保存列名对应的值。同一个rowKey同一个列对应的值,可以有多个版本。通过timestamp当版本号。一个Value默认可以保存3个版本号,基于列簇可设置时间数据存活时间(TTL)
3、Hbase保存的数据特别稀疏:由于列名不固定,列对应的值得类型比较丰富。
4、支持数据的横向自动扩展。

六、hbase中的核心服务

1、Zookeeper:
①、保存了root表的位置
②、zk接受所有客户端的读写请求,引导用户查询root--->meta-->region位置--->操作
③、启动的时候,每一个reginServer会在zk上注册一个临时性节点,负责hmaster集群中的选举,负责hmaster集群环境的容灾(分布式锁的功能)

2、Hmaster:
①、注册对每一个RegionServer的节点监听.当Region发生拆分的时候。会触发此监听函数,负责Region的分布
②、负责regionServer的负载均衡
③、负责监听RegionServer的运行状态。如果某个RegionServer宕机,负责在其他regionServer上恢复此Region信息
④、负责监听用户对表写的操作

3、HregionServer:
①、是真正用来存储数据库中数据的服务器。
②、HregionServer必须启动在hadoop的datanode节点上面。
③、HregionServer中存储数据的基本单位是:hregion

4、Hregion:
①、 一个hregion包含了某个表的全部或者局部内容。默认情况下。默认每个Region大小为128/256M,只保存一个表的信息
②、在region内部。数据是按照Row key的升序排好序的
③、有一个或者多Hstore组成
④、每一个hstore保存一个column famliy(列簇)
⑤、每个hstore包含一个memStore和多个storFile(memStore达到128M进行刷盘)

七、Hbase的三级寻址原理:(0.96版本之前)

  1. Region寻址定位:
  2. Questions:问系统如何找到某个RowKey (或者某个 row key range)所在的Region?
  3. Answers:Client请求,Zk查看Root表信息—>Root表告知Meta元信息—>Meta返回对应表的所有region的位置和RowKey区间信息

1、用户通过查找Zookeeper的/hbase/root-region-server节点来知道Root表在什么RegionServer(服务器)
2、访问Root表(Root表只存储一行数据),查看需要的数据在哪个Meta表上,这个Meta表在哪个RegionServer上
3、访问Meta表查看查询的行健在什么Region范围里面
4、连接具体的数据所在的RegionServer,这回就真的开始用Scan来遍历rowKey

备注:客户端会把meta信息缓存起来(下一次快速访问),下次操作就不需要进行以上加载HBase:meta的步骤.(缓存算法【LRU,最近最少使用策略】

说明:
    由上可知,用户需要 4 次请求才能直到用户 Table 真正的位置,这在一定程序带来了性能的下降。在0.96之前使用3层设计的主要原因是考虑到元数据可能需要很大。但是真正集群运行,元数据的大小其实很容易计算出来。在BigTable的论文中,每行MetaData数据存储大小为 1KB左右,如果按照一个Region为128M的计算,3层设计可以支持的 Region 个数2^34 个,采用 2 层设计可以支持 2^17(131072)。那么 2 层设计的情况下一个集群可以存储 4P 的数据。(默认Region最大为10G),因此,通过计算,其实 2 层设计就可以满足集群的需求。因此在 0.96 版本以后就去掉了Root表了

八、Hbase的二级寻址原理:(0.96版本之后)

0.96 版本以后将Root表去掉了

1、用户通过查找zk(zookeeper)的/hbase/meta-region-server节点查询哪台RegionServer上有hbase:meta表
2、客户端连接含有hbase:meta表的RegionServer。Hbase:meta表存储了所有Region的行健范围信息,通过这个表就可以  查询出你要存取的rowkey属于哪个Region的范围里面,以及这个Region又是属于哪个RegionServer
3、获取这些信息后,客户端就可以直连其中一台拥有你要存取的rowkey的RegionServer,并直接对其操作

下图Zk存储的Hbase元信息:

备注:

       实际上.Meta表一直就只有一个,所以Root中的记录一直都只有一行,Root表形同虚设。而且三层寻址增加了代码的复杂度,二层寻址,可以提高性能,Region完全满足使用。0.96版本后,三层架构被改为二层架构,-ROOT-表被去掉了,同时zk中的/hbase/root-region-server也被去掉了。直接把Meta表所在的RegionServer信息存储到了zk中的/hbase/meta-region-server去了。再后来引入了namespace,.META.表这样别扭的名字被修改成了Hbase:meta

九、Hbase官方架构图

①、HBase写操作流程

        
       ①、先将数据写到WAL中;
       ②、WAL存放在HDFS中;
       ③、每次Put、Delete操作的数据均追加到WAL末端;
       ④、持久化到WAL之后,再写到MenStore;
       ⑤、两者写完返回ACK到客户端;

②、Hregion详解

        

一个或者多个Hstore,每个HStore保存一个CF,下图所示

③、HBase Region Flush(刷盘->内存到硬盘)

        

①、用户进行一个写操作:先写入Hlog(WAL)中,再写入到MemStore中,只要在MemStore中写入成功,则给客户端返回写成功Hlog的数据,是先到内存中,在每一个RegisonServer内部,会有一个线程,定期hbase.master.logcleaner.plugins将数据定写到本地文件中。当memStore中的数据被flush到本地硬盘后,Hlog中的数据没用了,会将无用的hlog移动到oldwal文件夹中。HLog监控线程监控该目录下的oldwal,当该文件夹下的HLog达到 hbase.master.logcleaner.ttl设置的过期条件后,监控线程立即删除过期的HLog(wal:write ahead log)
 ②、单个Region的RegionsServer的全部Memtores的最大值。超过这个值,一个新的update操作会被挂起,强制执行flush最大值为:hbase.regionserver.global.memstore.upperLimit 默认为内存空间的40%.
③、RegionServer的Hlog,数量达到上限,会Flush,由此设置。hbase.regionserver.max.logs
④、手动触发(Flush 'TableName')
⑤、关闭RegionServer触发

④、HBase Compaction

        

①、刷盘,都会产生小文件,文件数量过多,会影响效率,因此必须进行hfile的合并,生成大的hfile    
       合并分为两类:
②、minor compact(小范围合并):
       当一个HStore含有多于这个值的HStoreFiles(每一个memstore flush产生一个HStoreFile)的时候,会执行合并操作。
       同时选取Hfile小于hbase.hstore.compaction.min.size(128M)的进行合并
       hbase.hstore.compaction.min:每个小合并的HStoreFiles最小数量,默认为3.
       hbase.hstore.compaction.max:每个小合并的HStoreFiles最大数量,默认为10.

 ③、major compact(大范围合并):
        major compact会对整个region下相同列簇的所有HFile进行compact,majorcompact结束后,同一个列簇下的HFile会被合并成一个Major compact是一个比较长的过程,对底层I/O的压力相对较大。
④、合并时机:

        hbase.hregion.majorcompaction 7天(base)
        hbase.hregion.majorcompaction.jitter(jitter)

        计算公式:base + jitter - Math.round(2 * jitter * randomNum) 
        手动合并:major_compact 'tabelName'

  1. 说明:
  2. major compact除了合并HFile外,另外一个重要功能就是清理过期(TTL)或者被删除的数据。前面提到过,HBase的delete操作
  3. 也是通过append的方式写入,一旦某些数据在HBase内部被删除了,在内部只是被简单标记为删除,真正在存储层面没有进行数据清理,只
  4. 有通过major compact对HFile进行重组时,被标记为删除的数据才能被真正的清理。

⑤、Hbase读操作流程

(详情见七,二级寻址原理)

十、RowKey的作用和设计要点

①、HBase中RowKey可以唯一标识一行记录,是用来检索记录的主键

②、在HBase中检索数据有以下三种方式:
③、通过 Get 方式,指定 RowKey 获取唯一一条记录
④、通过 Scan 方式,设置 startRow 和 stopRow 参数进行范围匹配
⑤、全表扫描,即直接扫描整张表中所有行记录

RowKey在Region中的作用
        在 HBase 中,Region 相当于一个数据的分片,每个 Region 都有StartRowKey和StopRowKey,这是表示 Region 存储的 RowKey 的范围,HBase 表的数据时按照 RowKey 来分散到不同的 Region,要想将数据记录均衡的分散到不同的Region中去,因此需要 RowKey 满足这种散列的特点。此外,在数据读写过程中也是与RowKey 密切相关,RowKey在读写过程中的作用:

①、读写数据时通过 Row Key 找到对应的 Region
②、MemStore 中的数据按RowKey字典顺序排序
③、HFile中的数据按RowKey字典顺序排序

①、RowKey的设计- Salting(加盐)

Salting 的原理是将固定长度的随机数放在行键的起始处,避免数据只存在某一台服务器上,造成吞吐量不均匀问题。

优缺点:
        由于前缀是随机生成的,因而如果想要按照字典顺序找到这些行,则需要做更多的工作,时间更长。从这个角度上看,salting增加了写操作的吞吐量,却也增大了读操作的开销。

②、RowKey的设计-Hashing

Hashing 的原理将RowKey进行hash计算,然后取hash的部分字符串和原来的RowKey进行拼接。

优缺点:
       可以一定程度打散整个数据集,但是不利于Scan;由于不同数据的hash值可能一样,实际应用中一般使用md5计算,然后截取前几位的字符串。如下:subString(MD5(设备ID), 0, x) + 设备ID,其中x一般取5或6。

③、RowKey的设计-Reversing

Reversing 的原理是反转一段固定长度或者全部的键

优缺点:
       有效地打乱了行键,但是却牺牲了行键排序的属性。

  1. 总结:
  2. 因为rowkey以字典序排列,为了发挥出分布式的作用,应该让rowkey均匀散列分布.
  3. 有效方式:salting(加盐),reversing,Hashing(如:md5),但是散列会降低scan性能.
  4. 长度限制:建议不超过16byte(Hbase数据Rowkey,value是以byte字节数组存储).
  5. 唯一原则,因为相同Rowkey会覆盖.
  6. 应该根据实际业务场景,根据RowKey全局有序(rowkey和column是升序, times是降序)的特性,进行合理选择.

下一篇介绍Hbase的Shell的使用 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/465410
推荐阅读
相关标签
  

闽ICP备14008679号