Hbase学习笔记

1.hbase的基本介绍

简介

  • hbase是bigtable的开源java版本,是建立在hdfs之上,提供给高可靠性,高性能,列存储,可伸缩,实时读写的nosql的数据库系统,它介于nosql和RDBMS之间,仅能通过主键(row key)和主键range来检索数据,仅支持单行事务(可通过hive来实现多表join等复杂操作),主要用来存储结构化和半结构化的松散数据
  • hbase查询功能很简单,不支持join等复杂操作,不支持复杂的事务(行级的事务)
  • hase中支持的数据类型:byte[]
  • 和hadoop一样,hbase的目标主要依靠横向扩展,通过不断增加廉价的商用服务器,来增加计算和存储能力

hbase中的表一般有以下的特点:

  • 大:一个表可以有上十亿行,上百万列
  • 面向列:面向列(族)的存储和权限控制,列(族)独立检索
  • 稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏

hbase的发展历程

  • hbase的原型是Google的BigTable论文,受到了该论文思想的启发,目前作为hadoop的子项目来开发维护,用于支持结构化的数据存储
  • 2006年Google发表的BigTable白皮书
  • 2006年开始开发了hbase
  • 2008年hbase成为了hadoop的子项目
  • 2010年hbase成为了Apache的顶级项目

2.Hbase和Hadoop的关系

1.HDFS

  • 为分布式存储提供文件系统
  • 针对存储大尺寸的文件进行优化,不需要对hdfs上的文件进行随机读写
  • 直接使用文件
  • 数据模型不灵活
  • 使用文件系统和处理框架
  • 优化一次写入,多次读取的方式

2.HBase

  • 提供表状的面向列的数据存储
  • 针对表状数据的随机读写进行优化
  • 使用key-value操作数据
  • 提供灵活的数据模型
  • 使用表状存储,支持MapReduce,依赖HDFS
  • 优化了多次读,以及多次写

3.Hbase和RDBMS的对比

1.关系型数据库
结构:

  • 数据库以表的形式存在
  • 支持FAT,NTFS.TXT文件系统
  • 使用Commitlog存储日志
  • 参考系统是坐标系统
  • 使用主键(PK)
  • 支持分区
  • 使用行,列,单元格

功能:

  • 支持向上扩展
  • 使用SQL查询
  • 面向行,每一行都是一个连续单元
  • 数据总量依赖于服务器的配置
  • 具有ACID支持
  • 适合结构化数据
  • 传统关系型数据一般都是中心化的
  • 支持事务
  • 支持join
    2.Hbase

结构:

  • 数据库以region的形式存在
  • 支持HDFS文件系统
  • 使用WAL(wirte-Ahead Logs)存储日志
  • 参考系统是zookeeper
  • 使用行建(row key)
  • 支持分片
  • 使用行,列,列族和单元格

功能:

  • 支持向外扩展

  • 使用API和Mapreduce来访问Hbase表数据

  • 面向列,即每一列都是一个连续的单元

  • 数据总量并不依赖具体的某台机器,而是取决于机器数量

  • Hbase不支持ACID(Atomicity 原子性、Consistency 一致性、Isolation 隔离性、Durability 持久性)

            原子性是指事物是一个不可分割的工作单位,事物中的操作要么发生,要么都不发生

            事物必须使数据库从一个一致性状态换到另外一个一致性状态

            事物的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务操作所干扰,多个并发事务之间要互相隔离

            持久性是指一个事务一旦被提交,它对数据库中的数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

  • 适合结构化数据和非结构化数据

  • 一般都是分布式的

  • Hbase不支持事务

  • 不支持Join

4.Hbase的特征简要

  1. 海量存储
            Hbase适合存储PB级别的海量数据,在PB级别的数据采用廉价的PC存储的情况下,能在几十到几百毫秒内返回数据,这与Hbase的极易扩展性息息相关

  2. 列式存储
            这里的列式存储其实说的就是列族存储,Hbase是根据列族来存储数据的,列族下面可以有非常多的列,列族在创建表的时候就必须指定
          
  3. 极易扩展
            Hbase的扩展性只体现在两个方面,一方面是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS),通过横向的添加RegionServer的机器,进行水平扩展,提升Hbase上层的处理能力,提升Hbase服务更多的Region的能力
          
  4. 高并发
            目前大部分使用Hbase的架构,都是采用廉价的PC,因此单个的IO的延迟其实并不小,一般在几十到上百ms之间,这里说的高并发,主要是在并发的情况下,Hbase的单个IO延迟下降并不多,能获得高并发,低延迟的服务
     
  5. 稀疏
            稀疏主要是针对Hbase的列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存存储空间的

5.Hbase的基础架构

Hbase学习笔记(概念和搭建)-编程知识网
1 HMaster
功能:

  1. 监控RegionServer
  2. 处理RegionServer的故障转移
  3. 处理元数据的变更
  4. 处理region的分配或者移除
  5. 在空闲时间对数据进行负载均衡
  6. 通过Zookeeleer发布自己的位置给客户端

2 RegionServer
功能:

  1. 负责存储Hbase的实际数据
  2. 处理分配给它的region
  3. 刷新缓存到HDFS
  4. 维护Hlog
  5. 执行压缩
  6. 负责处理 Region分片

3 组件

  1. Write-Ahead logs
    HBase的修改记录,当对Hbase读写数据的时候,数据不是直接写入到磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定),但是吧数据保存在内存中可能会引起数据的丢失,为了解决这个问题,会先把数据写入一个叫做Write-Ahead logfile的文件中,然后在写入内存中,所以系统出现故障的时候,数据可以通过这个日志文件重建.
  2. Hfile
    这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件
  3. Store
    Hfile存储在Store中,一个Store对应Hbase中的一个列族
  4. MemStore
    顾名思义,就是内存存储,位于内存中,用来保存当前的数据操作,所以当数据保存在WAL中,RegionServer会在内存中存储键值对
  5. Region
    Hbase表的分片,Hbase表会根据RowKey值被切分成不同的Region存储在RegionServer中,在一个RegionServer可有不同的region

6.Hbase的集群环境搭建

注意:HBase强依赖zookeeper和hadoop,在安装Hbase之前一定要保证zookeeper和hadoop的启动成功,且服务正常运行.

第一步: 下载对应的Hbase安装包

  • 所有关于CDH版本的软件包下载地址如下
http://archive.cloudera.com/cdh5/cdh/5/
  • HBase对应的版本下载地址如下
http://archive.cloudera.com/cdh5/cdh/5/hbase.tar.gz

第二步:压缩包上传并解压
将我们的压缩包上传到hadoop01服务器的/export/softwares路径下并解压

cd /export/softwares/
tar -zxvf hbase-bin.tar.gz -C ../install/

第三步:修改配置文件

  • 第一台机器进行修改配置文件
cd /export/install/hbase/conf
  • 修改第一个配置文件hbase-env.sh
 vim hbase-env.sh 
export JAVA_HOME=/export/install/jdk1.8.0_141
export HBASE_MANAGES_ZK=false
  • 修改第二个配置文件hbase-site.xml
    修改hbase-site.xml
vim hbase-site.xml
<configuration><property><name>hbase.rootdir</name><value>hdfs://hadoop01:9000/hbase</value>  </property><property><name>hbase.cluster.distributed</name><value>true</value></property><!-- 0.98后的新变动,之前版本没有.port,默认端口为60000 --><property><name>hbase.master.port</name><value>16000</value></property><property><name>hbase.zookeeper.quorum</name><value>hadoop01:2181,hadoop02:2181,hadoop03:2181</value></property><property><name>hbase.zookeeper.property.dataDir</name><value> /export/data/zk</value></property>
</configuration>
  • 修改第三个配置文件regioninstall
vim regioninstall 
hadoop01
hadoop02
hadoop03
  • 创建back-masters配置文件,实现HMaster的高可用
cd /export/install/hbase/conf
vim backup-masters
hadoop01

第四步:安装包分发到其他机器
将我们第一台机器的hbase的安装包拷贝到其他机器上面去

cd /export/install/
scp -r hbase/ hadoop02:$PWD
scp -r hbase/ hadoop03:$PWD

第五步:三台机器创建软连接

  • 因为hbase需要读取hadoop的core-site.xml以及hdfs-site.xml当中的配置文件信息,所以我们三台机器都要执行以下命令创建软连接
ln -s /export/install/hadoop/etc/hadoop/hdfs-site.xml /export/install/hbase/conf/hdfs-site.xml

第六步:三台机器添加HBASE_HOME的环境变量

 vim /etc/profile
export HBASE_HOME=/export/install/hbase
export PATH=:$HBASE_HOME/bin:$PATH

第七步:HBase集群启动
第一台机器执行以下命令进行启动

cd /export/install/hbase
bin/start-hbase.sh

警告提示:HBase启动的时候会产生一个警告,这是因为jdk7与jdk8的问题导致的,如果linux服务器安装jdk8就会产生这样的一个警告
Hbase学习笔记(概念和搭建)-编程知识网
警告不影响我们正常运行,可以不用解决

启动完成后可以用jps查看对应的进程

Hbase学习笔记(概念和搭建)-编程知识网
为了解决HMaster单点故障问题,我们可以在hadoop02和hadoop03机器上面都可以启动HMaster节点的进程,以实现HMaster的高可用

bin/hbase-daemon.sh start master #开启
bin/hbase-daemon.sh stop master	#关闭

第七步:页面访问
浏览器页面访问

http://hadoop01:60010/master-status

7.Hbase的底层原理

系统架构

Hbase学习笔记(概念和搭建)-编程知识网
Client

  • 包含访问hbase的接口,client维护着一些cache来加快对hbase的访问,比如region的位置信息

Zookeeper

  • 保证任何时候,集群都只有一个master
  • 存储所有的region的寻址入口
  • 实时监控region server的状态,将RegionServer的上线和下线信息通知给master

Master职责

  • 为RegionServer分配region
  • 负责region server的负载均衡
  • 发现失效的region server并重新为其分配
  • HDFS上面的垃圾文件回收
  • 处理schema更新请求

RegionServer 职责

  1. RegionServer 负责维护Master分配给他的region,处理这些region的IO请求
  2. RegionServer 负责切分在运行过程中变得大的region

可以看到,client访问hbase上数据的过程并不需要master参加(寻址访问zookeeper和region server,数据读写访问region server),master仅仅维护table和region的元数据信息,负载很低的

Hbase的表数据模型

Hbase学习笔记(概念和搭建)-编程知识网
Row Key
与nosql数据库一样,row key是用来检索记录的主键,访问hbase table中的行,只有三种方式

  1. 通过单个的row key访问
  2. 通过row key的range
  3. 通过全表扫描

Row key行建可以是任意字符串(最大长度是64KB,实际应用中长度一般为10-100bytes),在hbase内部,row key保存为字节数组
hbase会对表中的数据按照rowkey排序(字典排序)

存储时,数据按照Row key的字典序(boty order) 排序存储,设计key时,要充分排序存储这个特性,将经常一起读取的行存储放在一起,

字典序对int排序的结果是
1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97

列族 Column Family
hbase表中的每个列,都归属于某个列族,列族是表的一部分(而列不是),必须在使用表之前定义

列名都是以列族作为前缀,例如course:history,course:math都数据course这个列族

访问控制,磁盘和内存的使用统计都是在列族层面进行的

列族越多,在取一行数据时,所需要的IO,搜寻的文件就越多,所有没有必要,不要设置太多的列族

列 Column
列族下面具体的列,属于某一个Column Family,类似于mysql中具体的列

时间戳
       base中通过row和columns确定一个存储单元为cell,每个cell都保存着同一份数据的多个版本,版本通过时间戳来索引,时间戳的类型是64位整型,时间戳可有hbase(在数据写入时自动)赋值,此时时间戳是精确到**毫秒的当前系统时间,**时间戳也可由客户显示赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳,每个cell中,不同版本的数据按照时间倒序排序,即最新的数据排在前面.

为了避免数据存在过多版本造成的管理(包括存储和索引)负担,hbase提供了两种数据版本回收的方式:
        1) 保存数据的最后n个版本
        2) 保存最近一段时间内的版本,(设置数据的生命周期)

cell

  • 由{row key,column(=+
  • cell的数据是没有类型的,全部是字节码存储

VersionNum

  • 数据的版本号,每天数据可以有多个版本号,默认值是系统的时间戳,类型为Long

8.物理存储

1.整体结构

Hbase学习笔记(概念和搭建)-编程知识网

  1. table中的所有行都按照row key的字典序排序
  2. table在行的方向上分割为多高Hergion
  3. region按照大小分割(默认大小是10G),每个表在开始的时候只有一个region,随着数据的不断插入,region不断增大,当增大到一个阈值的时候,Hregion就会对半的切分到两个新的Hregion中,当table中的行不断增多的时候,region也会增多
  4. Hregion是hbase中分布式存储和负载均衡最小的单元,最小单元就表示不同的Hregion可以分布在不同的Hregion server上,但一个Hregion是不会拆分到多个server上的
  5. HRegion虽然是负载均衡最小的单元,但并不是物理存储的最小单元,事实上,Hregion由一个或者多个Store组成的,每个Store保存的一个collumn family 每个Store又由一个memstore和0至多个storeFile组成的,如图所示
    Hbase学习笔记(概念和搭建)-编程知识网
2.store file 和hfile结构

StoreFile 以Hfile的格式保存在HDFS上

HFile的格式如下

Hbase学习笔记(概念和搭建)-编程知识网

3. Memstore 和store file
  • 一个region由多个store组成,每个store包含一个列族的所有数据
  • store包含位于内存的memstore和位于硬盘的storefile
  • 写操作的时候先写入memstore,当memstore中的数据量达到某个阈值,Hregionserver启动flashcache进程写入storefile中,每次写入形成一个单独的storefile
  • 当storefile大小超过一定的阈值的时候,会把当前的region分割成两个,并由Hmaster分配给相应的region服务器,实现负载均衡
  • 客户端检索数据时,现在memstore找,找不到在找storefile
4.Hlog(WAL Log0)
  • WAL意为Write ahead log,类似mysql中的binlog,是用来做灾难恢复的,Hlog记录数据的所有变更,一旦数据修改,就可以从log中恢复

  • 每个Region server维护一个Hlog,而不是每个Regio一个,这样不同的region(来自不同的table)日志会混在一起,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此可以提高对table的写性能,带来的麻烦是,如果一台region server下线,为了恢复其上的region,需要将region server上的log进行拆分,然后分发到其他region server上进行恢复

  • Hlog文件其上就是一个普通的Hadoop Sequence File
          1) Hlog Sequence File 的key 是HlogKey对象,HlogKey记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是”写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence numbe
          
          2) HLog Sequece File的Value是HBase的KeyValue对象,即对应HFile中的KeyValue,可参见上文描述。

9.Hbase的读写流程

读流程

  1. HregionServer保存着meta表以及表数据,要访问表数据,首先Client先去访问zookeeper,从zookeeper里面获取meta表所在的位置信息,即找到这个meta表在哪个RregionServer保存的
  2. 接着Client通过刚才获取的HregionServer的IP来访问Meta表所在的HRegionServer,从而读取到Meta,进而获取到Meta表中存储的元数据
  3. Client通过元数据中存储的信息,访问对应的HregionServer,然后扫描所在HRegionServer的Metastore和Storefile来查询数据
  4. 最后HregionServer吧查询到的数据响应给Client

写流程

  1. Client先访问zookeeper,找到Meta表,并获取meta表元数据,确定当前将要写入的数据所对应的Hregion和HRegionServer服务器
  2. Client向该HRegionServer服务器发送写入数据的请求,然后HRegionServer收到请求并响应
  3. Client先把数据写入到Hlog,防止数据的丢失,然后将数据写入到Memstore
  4. 如果Hlog和memstore均写入成功,则这条数据写入成功
  5. 如果Memstore达到阈值,会把Memstore中的数据flush到StoreFile中
  6. 当storefile越来越多的时候,会触发Compact合并操作,吧过多的StoreFile合并成一个大的StoreFile
  7. 当StoreFile越来越大,Region也会越来越大,达到阈值,会触发split操作将,Region一分为二

10.Hbase的region管理和Master工作机制

Region管理

1) region的分配

       任何时刻,一个region只能分配给一个region server。master记录了当前有哪些可用的region server。以及当前哪些region分配给了哪些region server,哪些region还没有分配。当需要分配的新的region,并且有一个region server上有可用空间时,master就给这个region server发送一个装载请求,把region分配给这个region server。region server得到请求后,就开始对此region提供服务。

2) region server上线

       master使用zookeeper来跟踪region server状态当某个region server启动时,会首先在zookeeper上的server目录下建立代表自己的znode。由于master订阅了server目录上的变更消息,当server目录下的文件出现新增或删除操作时,master可以得到来自zookeeper的实时通知。因此一旦region server上线,master能马上得到消息。

3) region server下线

       当region server下线时,它和zookeeper的会话断开,zookeeper而自动释放代表这台server的文件上的独占锁。master就可以确定:
        1 region server和zookeeper之间的网络断开了。
        2 region server挂了。
无论哪种情况,region server都无法继续为它的region提供服务了,此时master会删除server目录下代表这台region server的znode数据,并将这台region server的region分配给其它还活着的同志。

Master工作机制

1) master上线
master启动进行以下步骤:

  1. 从zookeeper上获取唯一一个代表active master的锁,用来阻止其它master成为master。
  2. 扫描zookeeper上的server父节点,获得当前可用的region server列表。
  3. 和每个region server通信,获得当前已分配的region和region server的对应关系。
  4. 扫描.META.region的集合,计算得到当前还未分配的region,将他们放入待分配region列表

2) master下线

  1. 由于master只维护表和region的元数据,而不参与表数据IO的过程,master下线仅导致所有元数据的修改被冻结(无法创建删除表,无法修改表的schema,无法进行region的负载均衡,无法处理region 上下线,无法进行region的合并,唯一例外的是region的split可以正常进行,因为只有region server参与),表的数据读写还可以正常进行。因此master下线短时间内对整个hbase集群没有影响
  2. 因此,一般hbase集群中总是有一个master在提供服务,还有一个以上的‘master’在等待时机抢占它的位置。

11.HBase三个重要机制

1.flush机制

  1. hbase.regionserver.global.memstore.size)默认;堆大小的40%
    regionServer的全局memstore的大小,超过该大小会触发flush到磁盘的操作,默认是堆大小的40%,而且regionserver级别的flush会阻塞客户端读写

  2. hbase.hregion.memstore.flush.size)默认:128M
    单个region里memstore的缓存大小,超过那么整个HRegion就会flush,

  3. hbase.regionserver.optionalcacheflushinterval)默认:1h
    内存中的文件在自动刷新之前能够存活的最长时间

  4. hbase.regionserver.global.memstore.size.lower.limit)默认:堆大小 * 0.4 * 0.95
    有时候集群的“写负载”非常高,写入量一直超过flush的量,这时,我们就希望memstore不要超过一定的安全设置。在这种情况下,写操作就要被阻塞一直到memstore恢复到一个“可管理”的大小, 这个大小就是默认值是堆大小 * 0.4 * 0.95,也就是当regionserver级别的flush操作发送后,会阻塞客户端写,一直阻塞到整个regionserver级别的memstore的大小为 堆大小 * 0.4 *0.95为止

  5. hbase.hregion.preclose.flush.size)默认为:5M
    当一个 region 中的 memstore 的大小大于这个值的时候,我们又触发了region的 close时,会先运行“pre-flush”操作,清理这个需要关闭的memstore,然后 将这个 region 下线。当一个 region 下线了,我们无法再进行任何写操作。 如果一个 memstore 很大的时候,flush 操作会消耗很多时间。“pre-flush” 操作意味着在 region 下线之前,会先把 memstore 清空。这样在最终执行 close 操作的时候,flush 操作会很快。

  6. hbase.hstore.compactionThreshold)默认:超过3个
    一个store里面允许存的hfile的个数,超过这个个数会被写到新的一个hfile里面 也即是每个region的每个列族对应的memstore在flush为hfile的时候,默认情况下当超过3个hfile的时候就会对这些文件进行合并重写为一个新文件,设置个数越大可以减少触发合并的时间,但是每次合并的时间就会越长

2.compact机制

当Region达到阈值,会把过大的Region一分为二。默认一个HFile达到10Gb的时候就会进行切分

3.split机制

当Region达到阈值,会把过大的Region一分为二。默认一个HFile达到10Gb的时候就会进行切分