Hbase介绍

目录

1 Hbase数据模型

2 Hbase架构

3 Hbase存储及WAL机制

3.1 Hbase存储

3.2 WAL机制

4 RegionServer的故障恢复

5 Hbase特点介绍

6 Hbase 部署

7 HBase开发代码实例

7.1 Maven依赖

7.2 批量插入数据

7.3 读取一行数据

7.4 读取多行数据

7.5 过滤查询

7.6 删除多行数据

8 Hbase 小结


Hbase是Hadoop Database的简称 ,Hbase项目是由Powerset公司的Chad Walters和Jim Kelleman在2006年末发起,根据Google的Chang等人发表的论文“Bigtable:A Distributed Storage System for Strctured Data“来设计的。2007年10月发布了第一个版本。2010年5月,Hbase从Hadoop子项目升级成Apache顶级项目。

Hbase是分布式、面向列的开源数据库(其实准确的说是面向列族)。HDFS为Hbase提供可靠的底层数据存储服务,MapReduce为Hbase提供高性能的计算能力,Zookeeper为Hbase提供稳定服务和Failover机制,因此我们说Hbase是一个通过大量廉价的机器解决海量数据的高速存储和读取的分布式数据库解决方案

1 Hbase数据模型

如同Google的Bigtable论文中的描述,HBase的数据模型是疏松的、分布式的、持久的多维有序键值对。另外也有一些文章中将HBase数据模型描述为表或面向列族的数据库,这两种描述也是正确的。

在本部分中,将会从“表”和“键值对”两种数据模型的角度展示和介绍HBase中的数据结构。而对于“面向列族”的数据模型,更侧重于数据的物理存储,将在下一章节“HBase系统架构”中有所体现。表的形式可以最简单直观地描述HBase的数据模型,如图6-1所示,该图用“表”数据模型展现了两行存储在HBase表中的两行数据,此表有两个列族,行与列的交叉点为单元格,每个单元格中的数据又分为多个版本。要注意的是,表中的每行都要有相同的列族,却可以有不同的列限定符,例如“00002”行中,只有“HikDepartment: Primary”和“HikProduct.Name”两列数据。HBase的“表”数据模型在HBase的客户端API中也有很直观的体现(详见“代码实例”部分)。

图6-1 Hbase数据模型展示

而更容易理解的一种HBase数据模型是“多维键值对”模型,如图6-2所示,该图将图6-1中HBase表的第一行数据呈现为了多维键值对。当检索行键“00001”下的列族“HikDepartment”时,将得到该列族下的“Primary”和“Secondary”键值对。

图6-2 Hbase数据模型多维键值对展示

2 Hbase架构

Hbase的架构图如下图6-3所示:

图6-3 Hbase架构

从图中可以看出Hbase是由ClientZookeeper、HMasterHRegionServerHDFS等几个组件组成,下面来介绍一下几个组建的相关功能:

1Client

Client包含了访问Hbase的接口,另外Client还维护了对应的cache来加速Hbase的访问,比如cache.META.元数据的信息。

2Zookeeper

Hbase通过Zookeeper来做master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:通过Zoopkeeper来保证集群中只有1master在运行,如果master异常,会通过竞争机制产生新的master提供服务;通过Zoopkeeper来监控RegionServer的状态,当RegionSevrer有异常的时候,通过回调的形式通知Master RegionServer上下限的信息;通过Zoopkeeper存储元数据的统一入口地址。

3Hmaster

master节点的主要职责如下:为RegionServer分配Region;维护整个集群的负载均衡;维护集群的元数据信息;发现失效的Region,并将失效的Region分配到正常的RegionServer上;当RegionSever失效的时候,协调对应Hlog的拆分

4HregionServer

HregionServer直接对接用户的读写请求,是真正的干活的节点。它的功能概括如下:管理master为其分配的Region;处理来自客户端的读写请求;负责和底层HDFS的交互,存储数据到HDFS;负责Region变大以后的拆分;负责Storefile的合并工作。

5HDFS

HDFSHbase提供最终的底层数据存储服务,同时为Hbase提供高可用(Hlog存储在HDFS)的支持,具体功能概括如下:提供元数据和表数据的底层分布式存储服务;数据多副本,保证的高可靠和高可用性。

3 Hbase存储及WAL机制

3.1 Hbase存储

HBase的存储模型如图6-4所示,其存储模型集中体现在HregionServer上,下面对模型中的各部分进行介绍:

图6-3 Hbase存储模型

1 HRegion

在Hbase中实现可扩展性和负载均衡的基本单元是HRegion。HRegion存储着一段行键范围内的数据。刚开始时,一个表就只有一个HRegion,当一个表随着数据增多而不断变大时,如果达到指定的大小后就会根据行键自动一分为二成两个HRegion。每个HRegion中保存着一个( startkey,endkey)。随着表的继续增大,每个HRegion又会自动拆分成更多的HRegion,每个HRegion只会由一个HRegionServer服务。当然,Region除了会拆分外,也可能进行合并以减少Region数目。

2 Store

Store是核心存储单元。在一个HRegion中可能存在多个列族,那么Store中被指定只能存储一个列族。不同的列族存储在不同的Store中(所以在创建列族时,尽量将经常需要一起访问的列放到一个列族中,这样可以减少访问Store的数目)。一个Store由一个MemStore和0至多个StoreFile组成。

3 MemStore

Hbase在将数据写入StoreFile之前,会先写入MemStore。MemStore是一个有序的内存缓冲器。当MemStore中的数据量达到设定的大小(Flush Size)时,HRegionServer就会执行Flush操作,将MemStore中的数据flush到StoreFile中。

4 StoreFile和HFile

StoreFile是HFile的抽象,对HFile做了一层包装。HFile是数据真正存储的地方,它通过DFS Client写入到HDFS中。HFile基于BigTable的SSTable File和Hadoop的TFile,HFile在物理上被切分为多个大小相等的HFileBlock块,作为HFile的I/O单元。

5 HLog

HLog是一种WAL(Write-Ahead-Log,预写日志),WAL记录了该HRegionServer上所有数据的变更,用来做灾难恢复使用,一旦HRegionServer宕机,就可以从HLog中进行恢夏。

3.2 WAL机制

数据的存储流程见下图:

图6-3 Hbase存储流程

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

4 RegionServer的故障恢复

Hbase有较高的容错机制,我们下面讲解RegionServer宕机的故障恢复。

RegionServer的相关信息保存在ZK中,在RegionServer启动的时候,会在Zookeeper中创建对应的临时节点。RegionServer通过Socket和Zookeeper建立session会话,RegionServer会周期性地向Zookeeper发送ping消息包,以此说明自己还处于存活状态。而Zookeeper收到ping包后,则会更新对应session的超时时间。

当Zookeeper超过session超时时间还未收到RegionServer的ping包,则Zookeeper会认为该RegionServer出现故障,ZK会将该RegionServer对应的临时节点删除,并通知Master,Master收到RegionServer挂掉的信息后就会启动数据恢复的流程。Master启动数据恢复流程后,其实主要的流程如下:

RegionServer宕机->ZK检测到RegionServer异常->Master启动数据恢复->Hlog切分->Region重新分配->Hlog重放->恢复完成并提供服务。

5 Hbase特点介绍

Hbase的主要特点,如下图所示:

图6-4 Hbase特点

1 海量存储

Hbase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与Hbase的极易扩展性息息相关。正式因为Hbase良好的扩展性,才为海量数据的存储提供了便利。

2 列式存储

这里的列式存储其实说的是列族存储,Hbase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。为了加深对Hbase列族的理解,下面是一个简单的关系型数据库的表和Hbase数据库的表,如图6-56-6所示:

图6-5 RDBMS表
图6-6 Hbase表

下图是针对Hbase和关系型数据库表的基本比较

图6-7 表对比

3 易扩展

Hbase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)。通过横向添加RegionSever的机器,进行水平扩展,提升Hbase上层的处理能力,提升Hbsae服务更多Region的能力。

备注:RegionServer的作用是管理region、承接业务的访问。通过横向添加Datanode的机器,进行存储层扩容,提升Hbase的数据存储能力和提升后端存储的读写能力。

4 高并发

由于目前大部分使用Hbase的架构,都是采用的廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,主要是在并发的情况下,Hbase的单个IO延迟下降并不多。能获得高并发、低延迟的服务。

5 稀疏

稀疏主要是针对Hbase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。

6 Hbase 部署

HBase分布式集群的搭建依赖于HadoopZookeeper,在搭建HBase的时首先要搭建HadoopZookeeper,此处不再讲解HadoopZookeeper的搭建。

1.root权限打开/etc/profile文件,编辑添加Hbase环境变量

export HBASE_HOME=/home/hadoop/hbase

export PATH=$HBASE_HOME/bin:$PATH

2. 编辑hbase配置文件

vim conf/hbase-env.sh

  添加java环境目录

export JAVA_HOME=/home/hadoop/jdk1.8.0_101

不采用系统自带的zookeeper,设置为false

export HBASE_MANAGES_ZK=false

3.配置hbase-site.xml文件

<configuration>

         <property>

               <name>hbase.rootdir</name>

               <value>hdfs://master:9000/hbase</value>

         </property>

         <property>

               <name>hbase.cluster.distributed</name>

               <value>true</value>

         </property>

         <property>

               <name>hbase.master</name>

               <value>hdfs://master:60000</value>

         </property>

         <property>

               <name>hbase.zookeeper.quorum</name>

               <value>Master:2181,Slave1:2181,Slave2:2181</value>

         </property>

</configuration>

4 配置regionservers

vim regionservers

Master

Slave1

Slave2

Slave3

5.配置完毕分发到其他机器上

scp -r  hadoop /hbase/  Slave1:/home/hadoop/ hbase /

scp -r  hadoop /hbase/  Slave2:/home/hadoop/ hbase /

scp -r  hadoop /hbase/  Slave3:/home/hadoop/ hbase /

6. 在主节点启动hbase

  启动zookeeper

./zkServer.sh start

  在主节点启动Hadoop

./start-all.sh

  在主节点上启动Hbase

./start-hbase.sh

Hbase默认的Web端口是60010,启动Hbase后,在浏览器地址栏输入hostname:60010即可访问Hbase的Web UI,在Web UI中可以浏览Hbase集群的各种状态信息,如图6-8所示:

图6-8 HBase Web UI

7 HBase开发代码实例

7.1 Maven依赖

在maven工程中,pom.xml文件添加以下依赖:

<dependency>
   	<groupId>org.apache.hbase</groupId>
   	<artifactId>hbase-client</artifactId>
   	<version>1.2.1</version>
</dependency>
<dependency>
   	<groupId>org.apache.hbase</groupId>
   	<artifactId>hbase</artifactId>
   	<version>1.2.1</version>
</dependency>

注:具体的项目可根据本地Hbase版本,替换pom文件中Hbase jar版本

7.2 批量插入数据

public void saveByTable(){
    try{
        Connection connection= ConnectionFactory.createConnection(hbaseTemplate.getConfiguration());
        Admin admin=connection.getAdmin();
        TableName tableName= TableName.valueOf("user");
        Table table=connection.getTable(tableName);
        Put put1=new Put(Bytes.toBytes("3"));
        put1.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("yb3"));
        put1.addColumn(Bytes.toBytes("info"), Bytes.toBytes("email"), Bytes.toBytes("yb3.hikvision.com"));
        put1.addColumn(Bytes.toBytes("info"), Bytes.toBytes("password"), Bytes.toBytes("123456"));
        Put put2=new Put(Bytes.toBytes("4"));
        put2.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("yb4"));
        put2.addColumn(Bytes.toBytes("info"), Bytes.toBytes("email"), Bytes.toBytes("yb4.hikvision.com"));
        put2.addColumn(Bytes.toBytes("info"), Bytes.toBytes("password"), Bytes.toBytes("123456"));
        table.put(put2);
        List<Put> putList=new ArrayList<>();
        putList.add(put1);
        putList.add(put2);
        table.put(putList);
        table.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

7.3 读取一行数据

public void getData(){
    	try{
        	Connection connection= ConnectionFactory.createConnection(hbaseTemplate.getConfiguration());
        	Table table= connection.getTable(TableName.valueOf("user"));
        	Get get=new Get("3".getBytes());
        	get.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"));
        	Result result=table.get(get);
        	table.close();
    	}catch (Exception e){
        	e.printStackTrace();
    	}
}

7.4 读取多行数据

public void getDataList(){
    	try{
        	Connection connection= ConnectionFactory.createConnection(hbaseTemplate.getConfiguration());
        	Table table= connection.getTable(TableName.valueOf("user"));
        	Scan scan=new Scan();
        	//scan.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"));
        	scan.setStartRow("3".getBytes());
        	scan.setStopRow("5".getBytes());
        	//scan.setCaching(10);
        	ResultScanner resultScanner=table.getScanner(scan);
        	for(Result result:resultScanner){
            	System.out.println(result);
        	}
        	resultScanner.close();
        	table.close();
    	}catch (Exception e){
        	e.printStackTrace();
    	}
}

7.5 过滤查询

public void getDataListByScanAndFilter(){
    try{
        Connection connection= ConnectionFactory.createConnection(hbaseTemplate.getConfiguration());
        Table table= connection.getTable(TableName.valueOf("user"));
        Scan scan=new Scan();
        scan.setStartRow("3".getBytes());
        scan.setStopRow("5".getBytes());
        //单列值过滤
        Filter filter=new SingleColumnValueFilter(
                Bytes.toBytes("info"), Bytes.toBytes("name"), CompareFilter.CompareOp.LESS_OR_EQUAL,new BinaryComparator( Bytes.toBytes("yb3")));
        scan.setFilter(filter);
        ResultScanner resultScanner=table.getScanner(scan);
        Iterator resultIterator =resultScanner.iterator();
        if(resultIterator.hasNext()){
            System.out.println(resultIterator.next());
        }
        resultScanner.close();
        table.close();
    }catch (Exception e){
        e.printStackTrace();
    }
}

7.6 删除多行数据

public void deleteDataRows() {
    	try {
        	String tableName="user";
        	String[] rowKeys={"3","4"};
        	Connection conn= ConnectionFactory.createConnection(hbaseTemplate.getConfiguration());
        	Table table = conn.getTable(TableName.valueOf(tableName));
        	List<Delete> deleteList = new ArrayList<>(rowKeys.length);
        	Delete delete;
        	for (String rowKey : rowKeys) {
            	delete = new Delete(Bytes.toBytes(rowKey));
            	deleteList.add(delete);
        	}
        	table.delete(deleteList);
        	table.close();
    	} catch (Exception e) {
        	e.printStackTrace();
    	}
}

8 Hbase 小结

HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可搭建起大规模结构化存储集群。

Hbase与HDFS对比:HDFS采用顺序读取访问数据,并具有海量数据的存储能力,而Hbase则具有随机写入、数据快速随机访问能力;hbase是支持更新存储机制的组件;与Hbase相比,HDFS更加适合超级大的数据量。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值