欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

大数据技术之HBase系统知识整理(从安装到熟练操作)

程序员文章站 2022-09-06 11:22:29
HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库...

一、HBase简介

1.1 HBase定义

  HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库

1.2 HBase数据模型

  逻辑上,HBase的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从HBase的底层存储物理存储结构(K-V)来看,HBase跟像是一个multi-dimensional map

1.2.1 HBase逻辑结构

大数据技术之HBase系统知识整理(从安装到熟练操作)

1.2.2 HBase物理存储结构

大数据技术之HBase系统知识整理(从安装到熟练操作)

1.2.3 数据模型

  1. Name Space
      命名空间,类似于关系型数据库的DataBase概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是Hbase和default,hbase中存放是的HBase内置的表
  2. Region
      类似于关系型数据库的表概念。不同的是,HBase定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往HBase写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase能够轻松应对字段变更的场景
  3. Row
      HBase表中的每行数据都由一个RowKey和多个Column(列)组成,数据是按照RowKey的字典顺序存储的,并且查询数据时只能根据RowKey进行检索,所以RowKey的设计十分重要
  4. Column
      HBase中的每个列都由Column Family(列族)和Column Qualifier(列限定符)进行限定,例如info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义
  5. Time Stamp
      用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入HBase的时间
  6. Cell
      由{rowkey,column Family:column Qualifier,time Stamp}唯一确定的单元。cell中的数据是没有类型的,全都是字节码形式存贮

1.3 HBase基本架构

大数据技术之HBase系统知识整理(从安装到熟练操作)
架构角色:

  1. Region Server
    Region Server为Region的管理者,其实现类为HRegionServer,主要作用如下:
    对于数据的操作:get,put,delete
    对于Region的操作:splitRegion、compactRegion
  2. Master
    Master是所有Region Server的管理者,其实现类为HMaster,主要作用如下:
    对于表的操作:create、delete、alter
    对于RegionServer的操作:分配regions到每个RegionServer,监控每个RegionServer的状态,负载均衡和故障转移
  3. Zookeeper
    HBase通过Zookeeper来做Master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作
  4. HDFS
    HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高可用的支持

二、HBase快速入门

2.1 HBase安装部署

2.1.1 Zookeeper正常部署

首先保证Zookeeper集群的正常部署,并启动之:

[ironmanjay@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start
[ironmanjay@hadoop103 zookeeper-3.4.10]$ bin/zkServer.sh start
[ironmanjay@hadoop104 zookeeper-3.4.10]$ bin/zkServer.sh start 

2.1.2 Hadoop正常部署

Hadoop集群的正常部署并启动:注意:Hadoop集群安装部署看我这篇博客

[ironmanjay@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[ironmanjay@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh

2.1.3 HBase的解压

HBase官网下载相应版本,解压HBase到指定目录(目录自己指定):

[ironmanjay@hadoop102 software]$ tar -zxvf hbase-1.3.1-bin.tar.gz -C
/opt/module 

2.1.4 HBase的配置文件

修改HBase对应的配置文件

  1. hbase-env.sh修改如下。注意:JAVA_HOME路经按照自己的来,我的注释掉怕有的读者直接复制,切记改成自己的JAVA_HOME,否则HBase安装会失败
export JAVA_HOME=#/opt/module/jdk1.6.0_144
export HBASE_MANAGES_ZK=false 
  1. hbase-site.xml修改如下
<configuration>
 	<property>
  		<name>hbase.rootdir</name>
  		<value>hdfs://你的Hadoop地址: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>你的Hadoop集群名称</value>
	</property>
	<property>
  		<name>hbase.zookeeper.property.dataDir</name>
  		<value>你的Zookeeper安装地址/zkData</value>
	</property>
 <configuration>
  1. regionservers。注意:这里以我的为例,填写自己的Hadoop集群名称,不要有空格等
hadoop102
hadoop103
hadoop104
  1. 软连接hadoop配置文件到HBase。注意:根据自己目录情况修改即可
[ironmanjay@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml /opt/module/hbase/conf/coresite.xml
[ironmanjay@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml /opt/module/hbase/conf/hdfssite.xml 

2.1.5 HBase远程发送到其他集群

这里用到了集群远程分发脚本,具体脚本代码看我上面Hadoop部署的博客

[ironmanjay@hadoop102 module]$ xsync hbase/ 

2.1.6 HBase服务的启动

  1. HBase服务启动
[ironmanjay@hadoop102 hbase]$ bin/start-hbase.sh 
  1. HBase服务停止
[ironmanjay@hadoop102 hbase]$ bin/stop-hbase.sh 

2.1.7 查看HBase页面

启动成功后,可以通过“host:port”的方式来访问HBase管理页面,例如:
注意:16010端口不可改变,前面的Hadoop名称根据自己的修改即可

http://hadoop102:16010

2.2 HBase Shell操作

2.2.1 基本操作

  1. 进入HBase客户端命令行
[ironmanjay@hadoop102 hbase]$ bin/hbase shell 
  1. 查看帮助命令
hbase(main):001:0> help 
  1. 查看当前数据库中有哪些表
hbase(main):002:0> list 

2.2.2 表的操作

  1. 创建表
hbase(main):002:0> create 'student','info' 
  1. 插入数据到表
hbase(main):003:0> put 'student','1001','info:sex','male'
hbase(main):004:0> put 'student','1001','info:age','18'
hbase(main):005:0> put 'student','1002','info:name','Janna'
hbase(main):006:0> put 'student','1002','info:sex','female'
hbase(main):007:0> put 'student','1002','info:age','20' 
  1. 扫描查看表数据
hbase(main):008:0> scan 'student'
hbase(main):009:0> scan 'student',{STARTROW => '1001', STOPROW =>'1001'}
hbase(main):010:0> scan 'student',{STARTROW => '1001'} 
  1. 查看表结构
hbase(main):011:0> describe 'student'
  1. 更新指定字段的数据
hbase(main):012:0> put 'student','1001','info:name','Nick'
hbase(main):013:0> put 'student','1001','info:age','100' 
  1. 查看“指定行“或”指定列族:列“的数据
hbase(main):014:0> get 'student','1001'
hbase(main):015:0> get 'student','1001','info:name' 
  1. 统计表数据行数
hbase(main):021:0> count 'student' 
  1. 删除数据
    删除某rowkey的全部数据:
hbase(main):016:0> deleteall 'student','1001' 

         删除某rowkey的某一列数据:

hbase(main):017:0> delete 'student','1002','info:sex' 
  1. 清空表数据
    注意:清空表的操作顺序为先disable,然后再truncate:
hbase(main):018:0> truncate 'student' 
  1. 删除表
    首先需要先让该表为disable状态:
hbase(main):019:0> disable 'student' 

         然后才能drop这个表,如果直接drop表,会报错:ERROR: Table student is enabled. Disable it first

hbase(main):020:0> drop 'student' 
  1. 变更表信息
    将info列族中的数据存放3个版本
hbase(main):022:0> alter 'student',{NAME=>'info',VERSIONS=>3}
hbase(main):022:0> get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3} 

三、HBase进阶

3.1 架构原理

大数据技术之HBase系统知识整理(从安装到熟练操作)

  1. StoreFile
      保存实际数据的物理文件,StoreFile以HFile的形式存储在HDFS上。每个Store会有一个或多个StoreFile(HFile),数据在每个StoreFile中都是有序的
  2. MemStore
      写缓存,由于HFile中的数据要求是有序的,所以数据是先存储在MemStore中,排好序后,等到达刷写时机才会刷写到HFile,每次刷写都会形成一个新的HFile
  3. WAL
      由于数据要经MemStore排序后才能刷写到HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile的文件中,然后再写入Memstore中。所以在系统出现故障的时候,数据可以通过这个日志文件重建

3.2 写流程

大数据技术之HBase系统知识整理(从安装到熟练操作)
写流程:

  1. Client先访问zookeeper,获取hbase:meta表位于哪个Region Server
  2. 访问对应的Region Server,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache中,方便下次访问
  3. 与目标Region Server进行通讯
  4. 将数据顺序写入(追加)到WAL
  5. 将数据写入对应的MemStore,数据会在MemStore进行排序
  6. 向客户端发送ack
  7. 等达到MemStore的刷写时机后,将数据刷写到HFile

3.3 MemStore Flush

大数据技术之HBase系统知识整理(从安装到熟练操作)
MemStore刷写时机:

  1. 当某个memstore的大小达到了hbase.hregion.memstore.flush.size(默认值128M),其所在region的所有memstore都会刷写。当memstore的大小达到了hbase.hregion.memstore.flush.size(默认值128M),*hbase.hregion.memstore.block.multplier(默认值4)时,会阻止继续往该memstore写数据
  2. 当region server中memstore的总大小达到java_heapsize*hbase.regionserver.global.memstore.size(默认值0.4),*hbase.regionserver.global.memstore.size.lower.limit(默认值0.95),region会按照其所有memstore的大小顺序(由大到小)依次进行刷写。直到region server中所有memstore的总大小减小到上述值以下。当region server中memstore的总大小达到java_heapsize*hbase.regionserver.global.memstore.size(默认值0.4)时,会阻止继续往所有的memstore写数据
  3. 到达自动刷写的时间,也会触发memstore flush。自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval(默认1小时)
  4. 当WAL文件的数量超过hbase.regionserver.max.logs,region会按照时间顺序依次进行刷写,直到WAL文件数量减小到hbase.regionserver.max.log以下(该属性名已经废弃,现无需手动设置,最大值为32)

3.4 读流程

大数据技术之HBase系统知识整理(从安装到熟练操作)
读流程:

  1. Client先访问zookeeper,获取hbase:meta表位于哪个Region Server
  2. 访问对应的Region Server,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问
  3. 与目标Region Server进行通讯
  4. 分别在Block Cache(读缓存),MemStore和Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此外所有数据是指同一条数据的不同版本(timestamp),或者不同的类型(Put/Delete)
  5. 将从文件中查询到的数据块(Block,HFile数据存储单元,默认大小为64KB)缓存到Block Cache
  6. 将合并后的最终结果返回给客户端

3.5 StoreFile Compaction

  由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类型的(Put/Delete)有可能会分布在不同的HFile中,因此查询时需要遍历所有的HFile。为了减少HFile的个数,以及清理掉过期和删除的数据,会进行StoreFile Compaction
  Compaction分为两种,分别是Minor Compaction和Major Compaction。Minor Compaction会将临近的若干较小的HFile合并成一个较大的HFile,但不会清理过期和删除的数据。Major Compaction会将一个Store下的所有HFile合并成一个大HFile,并且会清理掉过期和删除的数据
大数据技术之HBase系统知识整理(从安装到熟练操作)

3.6 Region Split

  默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的Region Server,但出于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的Region Server
    Region Split时机:

  1. 当一个region中的某个Store下的所有StoreFile的总大小超过hbase.hregion.max.filesize,该Region就会拆分(0.94版本之前)
  2. 当一个region中的某个Store下所有StoreFile的总大小超过Min(R^2 * “hbase.hregion.memstore.flush.size”,“hbase.hregion.max.filesize”),该Region就会进行拆分,其中R为当前Region Server中属于该Table的个数(0.94版本之后)
    大数据技术之HBase系统知识整理(从安装到熟练操作)

四、HBase API

4.1 环境准备

使用Idea新建Maven项目后在pom.xml添加依赖

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

4.2 HBase API

  1. 获取Configuration对象
public static Configuration conf;

static{	
	//使用 HBaseConfiguration 的单例方法实例化
 	conf = HBaseConfiguration.create();
 	conf.set("hbase.zookeeper.quorum", "你的集群地址");
 	conf.set("hbase.zookeeper.property.clientPort", "2181");
}
  1. 判断表是否存在
public static boolean isTableExist(String tableName) throws MasterNotRunningException,ZooKeeperConnectionException, IOException{
 	//在 HBase 中管理、访问表需要先创建 HBaseAdmin 对象
 	HBaseAdmin admin = new HBaseAdmin(conf);
 	return admin.tableExists(tableName);
}
  1. 创建表
public static void createTable(String tableName, String...columnFamily) throws MasterNotRunningException, ZooKeeperConnectionException,IOException{ HBaseAdmin admin = new HBaseAdmin(conf);
 	//判断表是否存在
 	if(isTableExist(tableName)){
  		System.out.println("表" + tableName + "已存在");
 	}else{
  		//创建表属性对象,表名需要转字节
  		HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(tableName));
  		//创建多个列族
  		for(String cf : columnFamily){
   			descriptor.addFamily(new HColumnDescriptor(cf));
  	    	}
  	//根据对表的配置,创建表
  	admin.createTable(descriptor);
  	System.out.println("表" + tableName + "创建成功! ");
   }
}
  1. 删除表
public static void dropTable(String tableName) throws MasterNotRunningException,ZooKeeperConnectionException, IOException{
 	HBaseAdmin admin = new HBaseAdmin(conf);
 	if(isTableExist(tableName)){
  		admin.disableTable(tableName);
  		admin.deleteTable(tableName);
  		System.out.println("表" + tableName + "删除成功! ");
 	}else{
 		System.out.println("表" + tableName + "不存在! ");
	}
}
  1. 获取所有数据
public static void getAllRows(String tableName) throws IOException{
 	HTable hTable = new HTable(conf, tableName);
  	//得到用于扫描 region 的对象
  	Scan scan = new Scan();
  	//使用 HTable 得到 resultcanner 实现类的对象
  	ResultScanner resultScanner = hTable.getScanner(scan);
  	for(Result result : resultScanner){
   		Cell[] cells = result.rawCells();
  		for(Cell cell : cells){
   			//得到 rowkey
   			System.out.println(" 行 键 :" +
   			Bytes.toString(CellUtil.cloneRow(cell)));
   		//得到列族
   		System.out.println(" 列 族 " +
  		Bytes.toString(CellUtil.cloneFamily(cell)));
   		System.out.println(" 列 :" +
   		Bytes.toString(CellUtil.cloneQualifier(cell)));
   		System.out.println(" 值 :" +Bytes.toString(CellUtil.cloneValue(cell)));
  		}
 	}
}
  1. 获取某一行指定“列族:列“的数据
public static void getRowQualifier(String tableName, String rowKey,String family, String qualifier) throws IOException{
 	HTable table = new HTable(conf, tableName);
 	Get get = new Get(Bytes.toBytes(rowKey));
 	get.addColumn(Bytes.toBytes(family),
 	Bytes.toBytes(qualifier));
 	Result result = table.get(get);
 	for(Cell cell : result.rawCells()){
  		System.out.println(" 行 键 :" +
  		Bytes.toString(result.getRow()));
  		System.out.println(" 列 族 " +
  		Bytes.toString(CellUtil.cloneFamily(cell)));
  		System.out.println(" 列 :" +
  		Bytes.toString(CellUtil.cloneQualifier(cell)));
  		System.out.println(" 值 :" +
  		Bytes.toString(CellUtil.cloneValue(cell)));
 	}
}

4.3 MapReduce

  通过 HBase 的相关 JavaAPI,我们可以实现伴随 HBase 操作的 MapReduce 过程,比如使用
MapReduce 将数据从本地文件系统导入到 HBase 的表中,比如我们从 HBase 中读取一些原
始数据后使用 MapReduce 做数据分析

  1. 查看HBase的MapReduce任务的执行
bin/hbase mapredcp 
  1. 配置永久生效:在/etc/profile配置
export HBASE_HOME=你的HBase安装目录
export HADOOP_HOME=你的Hadoop安装目录 
  1. 在hadoop-env.sh中配置,注意:在for循环之后配
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:你的HBase安装目录/lib/* 
  1. 运行官方的MapReduce任务,统计Student表中有多少行数据
你的hadoop安装目录/bin/yarn jar lib/hbase-server-1.3.1.jar rowcounter student 

五、HBase与Hive的对比

  1. Hive
    ①:数据仓库
      Hive 的本质其实就相当于将 HDFS 中已经存储的文件在 Mysql 中做了一个双射关系,以
    方便使用 HQL 去管理查询
    ②:用于数据分析、清洗
      Hive 适用于离线的数据分析和清洗,延迟较高
    ③:基于HDFS、MapReduce
      Hive存储的数据依旧在DataNode上,编写的HQL语句终将是转换为MapReduce代码执行
  2. HBase
    ①:数据库
      是一种面向列族存储的非关系型数据库
    ②:用于存储结构化和非结构化的数据
      适用于单表非关系型数据的存储,不适合做关联查询,类似JOIN等操作
    ③:基于HDFS
      数据持久化存储的体现是HFile,存放于DataNode中,被Region Server以region的形式进行管理④:延迟较低,接入在线业务使用
      面对大量的企业数据,HBase可以进行单表大量数据的存储,同时提供了高效的数据访问速度

六、HBase优化

6.1 高可用

  在 HBase 中 HMaster 负责监控 HRegionServer 的生命周期,均衡 Region Server 的负载,如果 HMaster 挂掉了,那么整个 HBase 集群将陷入不健康的状态,并且此时的工作状态并不会维持太久。所以 HBase 支持对 HMaster 的高可用配置

  1. 关闭HBase集群(如果没有开启则跳过此步)
[ironmanjay@hadoop102 hbase]$ bin/stop-hbase.sh 
  1. 在conf目录下创建backup-masters文件
[ironmanjay@hadoop102 hbase]$ touch conf/backup-masters 
  1. 在backup-masters文件中配置高可用HMaster节点
[ironmanjay@hadoop102 hbase]$ echo hadoop103 > conf/backup-masters 
  1. 将整个conf目录scp到其他机器节点
[ironmanjay@hadoop102 hbase]$ scp -r conf/hadoop103:/opt/module/hbase/
[ironmanjay@hadoop102 hbase]$ scp -r conf/hadoop104:/opt/module/hbase/ 
  1. 打开测试页面查看
http://hadoop102:16010/

6.2 预分区

  每一个 region 维护着 StartRow 与 EndRow,如果加入的数据符合某个 Region 维护的RowKey 范围,则该数据交给这个 Region 维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高 HBase 性能。

  1. 手动设定预分区
Hbase> create 'staff1','info','partition1',SPLITS => ['1000','2000','3000','4000'] 
  1. 生成十六进制序列预分区
create 'staff2','info','partition2',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'} 
  1. 按照文件中设置的规则预分区
    创建splits.txt文件内容如下
aaaa
bbbb
cccc
dddd 

         然后执行

create 'staff3','partition3',SPLITS_FILE => 'splits.txt' 
  1. 使用JavaAPI创建预分区
//自定义算法,产生一系列 hash 散列值存储在二维数组中
byte[][] splitKeys = 某个散列值函数
//创建 HbaseAdmin 实例
HBaseAdmin hAdmin = new HBaseAdmin(HbaseConfiguration.create());
//创建 HTableDescriptor 实例
HTableDescriptor tableDesc = new HTableDescriptor(tableName);
//通过 HTableDescriptor 实例和散列值二维数组创建带有预分区的 Hbase 表
hAdmin.createTable(tableDesc, splitKeys);

6.3 内存优化

  HBase 操作过程中需要大量的内存开销,毕竟 Table 是可以缓存在内存中的,一般会分配整个可用内存的 70%给 HBase 的 Java 堆。但是不建议分配非常大的堆内存,因为 GC 过程持续太久会导致 Region Server 处于长期不可用状态,一般16~48G内存就可以了,如果因为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死

6.4 基础优化

  1. 允许在HDFS的文件中追加内容
    hdfs-site.xml、 hbase-site.xml
属性:dfs.support.append
解释:开启 HDFS 追加同步,可以优秀的配合 HBase 的数据同步和持久化。默认值为 true 
  1. 优化 DataNode 允许的最大文件打开数
    hdfs-site.xml
属性:dfs.datanode.max.transfer.threads
解释:HBase一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为 4096 或者更高。默认值:4096 
  1. 优化延迟高的数据操作的等待时间
    hdfs-site.xml
属性:dfs.image.transfer.timeout
解释:如果对于某一次数据操作来讲,延迟非常高,socket需要等待更长的时间,建议把该值设置为更大的值(默认60000 毫秒),以确保socket不会被timeout掉
  1. 设置 RPC 监听数量
    hbase-site.xml
属性:Hbase.regionserver.handler.count
解释:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值 
  1. 优化 HStore 文件大小
    hbase-site.xml
属性:hbase.hregion.max.filesize
解释:默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile 
  1. 优化 HBase 客户端缓存
    hbase-site.xml
属性:hbase.client.write.buffer
解释:用于指定Hbase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的 

本文地址:https://blog.csdn.net/IronmanJay/article/details/107291472