• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

大数据技术-HBase学习笔记

武飞扬头像
笑一笑、
帮助1

HBase官方文档

HBase-安装部署

前置要求

Zookeeper正常启动、Hadoop正常部署

修改配置文件

conf/hbase-env.sh

export HBASE_MANAGES_ZK=false

hbase-site.xml

<configuration>
    <property>
        <name>hbase.rootdir</name>
        <value>hdfs://bigdata100:8020/hbase</value>
    </property>
    <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
    </property>
    <property> 
        <name>hbase.zookeeper.quorum</name>
        <value>bigdata100,bigdata102,bigdata104</value>
    </property>
</configuration>

conf/regionservers

bigdata100
bigdata102
bigdata104

软连接hadoop配置文件到HBase

ln -s /opt/module/hadoop-3.1.3/etc/hadoop/core-site.xml /opt/module/hbase/conf/core-site.xml
ln -s /opt/module/hadoop-3.1.3/etc/hadoop/hdfs-site.xml /opt/module/hbase/conf/hdfs-site.xml

HBase远程发送到其他集群

xsync hbase/

启动hbase

方式一

bin/hbase-daemon.sh start master
bin/hbase-daemon.sh start regionserver

bin/hbase-daemon.sh stop master
bin/hbase-daemon.sh stop regionserver

如果集群之间的节点时间不同步,会导致regionserver无法启动,抛出ClockOutOfSyncException异常,maxclockskew设置更大的值

<property>
        <name>hbase.master.maxclockskew</name>
        <value>180000</value>
        <description>Time difference of regionserver from master</description>
</property>

方式二

bin/start-hbase.sh
bin/stop-hbase.sh

学新通

HBase-架构

学新通

数据模型

NameSpace:命名空间,类似于关系型数据库的DatabBase概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是hbase和default,hbase中存放的是HBase内置的表,default表是用户默认使用的命名空间。

Region:类似于关系型数据库的表概念。不同的是,HBase定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往HBase写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase能够轻松应对字段变更的场景。

Row:HBase表中的每行数据都由一个RowKey和多个Column(列)组成,数据是按照RowKey的字典顺序存储的,并且查询数据时只能根据RowKey进行检索,所以RowKey的设计十分重要。

Column:HBase中的每个列都由ColumnFamily(列族)和ColumnQualifier(列限定符)进行限定,例如info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。

TimeStamp:用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入HBase的时间

Cell:由{rowkey,columnFamily:columnQualifier,timeStamp}唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮

基本架构

学新通

RegionServer:RegionServer为Region的管理者,其实现类为HRegionServer

  • 对于数据的操作:get,put,delete;
  • 对于Region的操作:splitRegion、compactRegion。

Master:Master是所有RegionServer的管理者,其实现类为HMaster

  • 对于表的操作:create,delete,alter
  • 对于RegionServer的操作:分配regions到每个RegionServer,监控每个RegionServer的状态,负载均衡和故障转移。

Zookeeper:HBase通过Zookeeper来做Master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。

HDFS:HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高可用的支持。

架构原理

学新通

StoreFile:保存实际数据的物理文件,StoreFile以HFile的形式存储在HDFS上。每个Store会有一个或多个StoreFile(HFile),数据在每个StoreFile中都是有序的。

MemStore:写缓存,由于HFile中的数据要求是有序的,所以数据是先存储在MemStore中,排好序后,等到达刷写时机才会刷写到HFile,每次刷写都会形成一个新的HFile。

WAL:由于数据要经MemStore排序后才能刷写到HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Aheadlogfile的文件中,然后再写入MemStore中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。

读流程

学新通

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

写流程

学新通

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

memStore刷写时机

学新通

当某个memstroe的大小达到了hbase.hregion.memstore.flush.size(默认值128M),其所在region的所有memstore都会刷写。当memstore的大小达到了hbase.hregion.memstore.flush.size(默认值128M)*hbase.hregion.memstore.block.multiplier(默认值4)时,会阻止继续往该memstore写数据

当regionserver中memstore的总大小达到java_heapsize*hbase.regionserver.global.memstore.size(默认值0.4)hbase.regionserver.global.memstore.size.lower.limit(默认值0.95),region会按照其所有memstore的大小顺序(由大到小)依次进行刷写。直到regionserver中所有memstore的总大小减小到上述值以下。当regionserver中memstore的总大小达到java_heapsizehbase.regionserver.global.memstore.size(默认值0.4)时,会阻止继续往所有的memstore写数据

到达自动刷写的时间,也会触发memstoreflush。自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval(默认1小时)

当WAL文件的数量超过hbase.regionserver.max.logs,region会按照时间顺序依次进行刷写,直到WAL文件数量减小到hbase.regionserver.max.log以下(该属性名已经废弃,现无需手动设置,最大值为32)

StoreFile Compaction

由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类型(Put/Delete)有可能会分布在不同的HFile中,因此查询时需要遍历所有的HFile为了减少HFile的个数,以及清理掉过期和删除的数据,会进行StoreFileCompaction
Compaction分为两种,分别是MinorCompaction和MajorCompaction。MinorCompaction会将临近的若干个较小的HFile合并成一个较大的HFile,但不会清理过期和删除的数据。MajorCompaction会将一个Store下的所有的HFile合并成一个大HFile,并且会清理掉过期和删除的数据

学新通

Region Split

默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。
RegionSplit时机
当1个region中的某个Store下所有StoreFile的总大小超过hbase.hregion.max.filesize,该Region就会进行拆分(0.94版本之前)。
当1个region中的某个Store下所有StoreFile的总大小超过Min(R^2*“hbase.hregion.memstore.flush.size”,hbase.hregion.max.filesize"),该Region就会进行拆分,其中R为当前RegionServer中属于该Table的个数(0.94版本之后)

学新通

HBase-SHELL操作

进入HBase客户端命令行

bin/hbase shell

查看帮助命令

help

查看当前数据库中有哪些表

list

创建表

create 'student','info'

插入数据到表

put 'student','1001','info:sex','male'
put 'student','1001','info:age','18'
put 'student','1002','info:name','Janna'
put 'student','1002','info:sex','female'
put 'student','1002','info:age','20'

扫描查看表数据

scan 'student'
scan 'student',{STARTROW => '1001', STOPROW => '1002'}
scan 'student',{STARTROW => '1001'}

查看表结构

describe 'student'

更新指定字段的数据

put 'student','1001','info:name','Nick'
put 'student','1001','info:age','100'

统计表数据行数

count 'student'

删除数据

# 删除某rowkey的全部数据
deleteall 'student','1001'
# 删除某rowkey的某一列数据
delete 'student','1002','info:sex'

清空表数据

# 清空表的操作顺序为先 disable,然后再 truncate。
truncate 'student'

删除表

如果直接drop表会报错

# 首先需要先让该表为disable状态
disable 'student'
# 然后才能drop这个表:
drop 'student'

HBase-API操作

引入依赖

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

代码案例地址

HBase-MapReduce

官方MapReduce

查看HBase的MapReduce任务执行

bin/hbase mapredcp

查看mapreduce的参数指令

hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.5.jar

学新通

导入环境变量

命令行操作,临时生效

export HBASE_HOME=/opt/module/hbase-2.0.5
export HADOOP_HOME=/opt/module/hadoop-3.1.3
export HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath`

配置文件方式,永久生效,在/etc/profile配置,并在hadoop-env.sh中配置(在for循环之后配置)

# /etc/profile配置
export HBASE_HOME=/opt/module/hbase-2.0.5
export HADOOP_HOME=/opt/module/hadoop-3.1.3
# hadoop-env.sh配置
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/opt/module/hbase-2.0.5/lib/*

运行MapReduce任务

# 统计student表中有多少行数据
${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.5.jar rowcounter student

执行MapReduce到HBase表中

# 创建HBase表
hive> create 'fruit','info'
# 创建数据
hdfs dfs -mkdir /input_fruit
hdfs dfs -put fruit.tsv /input_fruit
# 执行
yarn jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.5.jar importtsv \
-Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:color fruit \
hdfs://bigdata100:8020/input_fruit/
# 查看结果
hive> scan 'fruit'

自定义MapReduce

通过MapReduce将数据从一张表迁入另外一张表

案例地址

通过MapReduce将HDFS数据写入到Hbase

案例地址

HBase-集成Hive

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

环境准备

拷贝Hive所依赖的Jar包

export HBASE_HOME=/opt/module/hbase
export HIVE_HOME=/opt/module/hive

ln -s $HBASE_HOME/lib/hbase-common-2.0.5.jar $HIVE_HOME/lib/hbase-common-2.0.5.jar
ln -s $HBASE_HOME/lib/hbase-server-2.0.5.jar $HIVE_HOME/lib/hbase-server-2.0.5.jar
ln -s $HBASE_HOME/lib/hbase-client-2.0.5.jar $HIVE_HOME/lib/hbase-client-2.0.5.jar
ln -s $HBASE_HOME/lib/hbase-protocol-2.0.5.jar $HIVE_HOME/lib/hbase-protocol-2.0.5.jar
ln -s $HBASE_HOME/lib/hbase-it-2.0.5.jar $HIVE_HOME/lib/hbase-it-2.0.5.jar
ln -s $HBASE_HOME/lib/htrace-core-3.2.0-incubating.jar $HIVE_HOME/lib/htrace-core-3.2.0-incubating.jar
ln -s $HBASE_HOME/lib/hbase-hadoop2-compat-2.0.5.jar $HIVE_HOME/lib/hbase-hadoop2-compat-2.0.5.jar
ln -s $HBASE_HOME/lib/hbase-hadoop-compat-2.0.5.jar $HIVE_HOME/lib/hbase-hadoop-compat-2.0.5.jar

学新通

同时在hive-site.xml中修改zookeeper的属性,如下

<property>
    <name>hive.zookeeper.quorum</name>
    <value>bigdata100,bigdata102,bigdata104</value>
</property>
<property>
    <name>hive.zookeeper.client.port</name>
    <value>2181</value>
</property>

建立Hive表,关联HBase表,插入数据到Hive表的同时能够影响HBase表

CREATE TABLE hive_hbase_emp_table(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno")
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");

Hive和HBase分别都生成了对应的表

学新通

学新通

不能直接将数据load进hive所关联的hbase的表中,需要通过临时添加,即可完成数据同步

 insert into table hive_hbase_emp_table select * from emp;

建立Hive外部表,关联HBase表

CREATE EXTERNAL TABLE relevance_hbase_emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int)
STORED BY 
'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno")
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");

关联后就可以使用Hive函数进行分析操作

hive (default)> select * from relevance_hbase_emp;

HBase-优化

高可用

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

环境配置

在conf目录下创建backup-masters文件,在backup-masters文件中配置高可用HMaster节点,分发到其他集群,启动Hbase

touch backup-masters
echo bigdata102 > backup-masters
xsync backup-masterssh

学新通

预分区

手动设置预分区

create 'staff1','info','partition1',SPLITS => ['1000','2000','3000','4000']

生成16进制序列预分区

create 'staff2','info','partition2',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}

按照文件中设置的规则预分区

# splits.txt
aaaa
bbbb
cccc
# sql
create 'staff3','partition3',SPLITS_FILE => '/root/splits.txt'

使用Java创建预分区

public static void prePartition(String tableName, String... columnFamily) throws IOException {
    HBaseAdmin admin = ConfigurationUtils.getHBaseAdmin();
    // 判断表是否存在
    if (isTableExist(tableName)) {
        System.out.println("表 "   tableName   "已存在");
    } else {
        // 自定义算法 产生一系列 hash 散列值存储在二维数组中
        byte[][] bys = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        // 创建表属性对象 表名需要转字节
        HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(tableName));
        // 创建多个列族
        for (String cf : columnFamily) {
            descriptor.addFamily(new HColumnDescriptor(cf));
        }
        // 通过HTableDescriptor实例和散列值二维数组创建带有预分区的Hbase表
        admin.createTable(descriptor, bys);
        System.out.println("表 "   tableName   "创建成功");
    }
}
学新通

RowKey设计

一条数据的唯一标识就是rowKey,那么这条数据存储于哪个分区,取决于rowKey处于哪个一个预分区的区间内,设计rowKey的主要目的,就是让数据均匀的分布于所有的region中,在一定程度上防止数据倾斜

  • 生成随机数、hash、散列值(SHA1)

  • 字符串反转

  • 字符串拼接

基础优化

允许在HDFS的文件中追加内容

配置文件:hdfs-site.xmlhbase-site.xml

属性:dfs.support.append

说明:开启HDFS追加同步,可以优秀的配合HBase的数据同步和持久化,默认值为true

优化DataNode允许的最大文件打开数

配置文件:hdfs-site.xml
属性:dfs.datanode.max.transfer.threads
说明:HBase一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为4096或者更高。默认值:4096

优化延迟高的数据操作的等待时间

属性:dfs.image.transfer.timeout
说明:如果对于某一次数据操作来讲,延迟非常高,socket需要等待更长的时间,建议把该值设置为更大的值(默认60000毫秒)以确保socket不会被timeout掉

优化数据的写入效率

配置文件:mapred-site.xml
属性:mapreduce.map.output.compressmapreduce.map.output.compress.codec
说明:开启这两个数据可以大大提高文件的写入效率,减少写入时间。第一个属性值修改为true,第二个属性值修改为:org.apache.hadoop.io.compress.GzipCodec或者其他压缩方式

设置RPC监听数量

配置文件:hbase-site.xml
属性:hbase.regionserver.handler.count
说明:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值

优化HStore文件大小

配置文件:hbase-site.xml
属性:hbase.hregion.max.filesize
说明:默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile

优化HBase客户端缓存

配置文件:hbase-site.xml
属性:hbase.client.write.buffer
说明:用于指定Hbase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的

指定scan.next扫描HBase所获取的行数

配置文件:hbase-site.xml
属性:hbase.client.scanner.caching
说明:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大

flush、compact、split机制

当MemStore达到阈值,将Memstore中的数据Flush进Storefile;compact机制则是把flush出来的小文件合并成大的Storefile文件。split则是当Region达到阈值,会把过大的Region一分为二

属性:hbase.hregion.memstore.flush.size:134217728,128M就是Memstore的默认阈值

这个参数的作用是当单个HRegion内所有的Memstore大小总和超过指定值时,flush该HRegion的所有memstore。RegionServer的flush是通过将请求添加一个队列,模拟生产消费模型来异步处理的。那这里就有一个问题,当队列来不及消费,产生大量积压请求时,可能会导致内存陡增,最坏的情况是触发OOM

hbase.regionserver.global.memstore.upperLimit:0.4

hbase.regionserver.global.memstore.lowerLimit:0.38

当MemStore使用内存总量达到hbase.regionserver.global.memstore.upperLimit指定值时将会有多个MemStoresflush到文件中,MemStoreflush顺序是按照大小降序执行的,直到刷新到MemStore使用内存略小于lowerLimit

Hive-环境搭建

Hive引擎介绍

Hive引擎包括:默认MR、tez、spark

Hive on Spark:Hive既作为存储元数据又负责SQL的解析优化,语法是HQL语法,执行引擎变成了Spark,Spark负责采用RDD执行

Spark on Hive : Hive只作为存储元数据,Spark负责SQL解析优化,语法是Spark SQL语法,Spark负责采用RDD执行

Hive on Spark配置

兼容性说明

官网下载的Hive3.1.2和Spark3.0.0默认是不兼容的。因为Hive3.1.2支持的Spark版本是2.4.5,所以需要重新编译Hive3.1.2版本。

编译步骤:官网下载Hive3.1.2源码,修改pom文件中引用的Spark版本为3.0.0,如果编译通过,直接打包获取jar包。如果报错,就根据提示,修改相关方法,直到不报错,打包获取jar包

Hive所在节点部署Spark

解压安装spark

tar -zxvf spark-3.0.0-bin-hadoop3.2.tgz -C /opt/module/
mv /opt/module/spark-3.0.0-bin-hadoop3.2 /opt/module/spark

配置环境变量

vim /etc/profile.d/my_env.sh

# SPARK_HOME
export SPARK_HOME=/opt/module/spark
export PATH=$PATH:$SPARK_HOME/bin

# 使环境配置生效
source /etc/profile.d/my_env.sh

学新通

Hive添加Spark配置文件

vim /opt/module/hive/conf/spark-defaults.conf


# 添加如下内容(在执行任务时,会根据如下参数执行)
spark.master                           yarn
spark.eventLog.enabled                 true
spark.eventLog.dir                     hdfs://node01:8020/spark-history
spark.executor.memory                  1g
spark.driver.memory                    1g

学新通
在HDFS创建如下路径,用于存储历史日志

hadoop fs -mkdir /spark-history

学新通

向HDFS上传Spark纯净版jar包

由于Spark3.0.0非纯净版默认支持的是hive2.3.7版本,直接使用会和安装的Hive3.1.2出现兼容性问题。所以采用Spark纯净版jar包,不包含hadoop和hive相关依赖,避免冲突。

Hive任务最终由Spark来执行,Spark任务资源分配由Yarn来调度,该任务有可能被分配到集群的任何一个节点。所以需要将Spark的依赖上传到HDFS集群路径,这样集群中任何一个节点都能获取到。

# 解压安装
tar -zxvf /opt/software/spark-3.0.0-bin-without-hadoop.tgz

# 上传Spark纯净版jar包
hadoop fs -mkdir /spark-jars
hadoop fs -put spark-3.0.0-bin-without-hadoop/jars/* /spark-jars

学新通

修改配置文件

vim /opt/module/hive/conf/hive-site.xml
<!--Spark依赖位置(注意:端口号8020必须和namenode的端口号一致)-->
<property>
    <name>spark.yarn.jars</name>
    <value>hdfs://node01:8020/spark-jars/*</value>
</property>

<!--Hive执行引擎-->
    <property>
    <name>hive.execution.engine</name>
    <value>spark</value>
</property>

学新通

hive on spark测试

# 启动hive客户端
bin/hive
# 创建测试表
create table student(id int, name string);
# insert测试效果
insert into table student values(1,'abc');

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhghbbgg
系列文章
更多 icon
同类精品
更多 icon
继续加载