欢迎投稿

今日深度:

hbase简介,1.2HBase数据

hbase简介,1.2HBase数据


1.HBase简介

1.1 定义

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

1.2 HBase数据模型

1.2.1逻辑结构

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

实际上逻辑表中的数据是稀疏的,有些cell没有值       稀疏数组参考

1.2.2 HBase物理存储结构

以上即为稀疏数据的存储

1.2.3 数据模型

➢ Name Space

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

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

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

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

➢ Time Stamp

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

➢ Cell

由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元。cell 中的数 据是没有类型的,全部是字节码形式存贮

具体 参考官网

1.3 HBase 架构

1.3.1 Master

Master 是所有 Region Server 的管理者,其实现类为 HMaster(服务器上有个HMaster进程),主要作用如下: 对于表的操作:create, delete, alter对于 RegionServer 的操作:分配 regions 到每个 RegionServer,监控每个 RegionServer的状态,负载均衡和故障转移。即负责ddl操作

1.3.2 Region Server

Region Server 为 Region 的管理者,其实现类为 HRegionServer(服务器上有个HRegionServer进程),主要作用如下: 对于数据的操作:get, put, delete(负责dml操作);对于 Region 的操作:splitRegion、compactRegion。一个Region Server管理多个Region

1.3.3 Zookeeper

HBase 通过 Zookeeper 来做 Master 的高可用、RegionServer 的监控、元数据的入口以及 集群配置的维护等工作。(具体请看第5章高可用)

1.3.4 HDFS

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

2.HBase入门

2.1安装部署

2.1.1standalone

略  官网文档

简易安装

调整zk端口号

2.1.2Distributed

略 官网文档

配置注意

hbase_env.sh中

//不要使用内部的zk

export HBASE_MANAGES_ZK=false

hbase-site.xml中添加如下信息

<!-- 是否分布式 -->
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>
  <!-- 端口号 -->
  <property>
    <name>hbase.master.port</name>
    <value>16000</value>
  </property>
  <!-- hbase文件存储地址,设置为hdfs -->
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://localhost:9000/HBase</value>
  </property>
  <!--zk地址-->
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>localhost</value>
  </property>
  <!-- zk存储文件地址 -->
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/usr/local/zookeeper-3.4.14/zkData</value> 
  </property>

2.2 HBase Shell

-- 启动关闭相关
-- 1.启动hbase
bin/start-hbase.sh
-- 2.查看启动情况,
-- 单机版只会有 HMaster 进程
jps
-- 3.关闭hbase
bin/stop-hbase.sh


-- 基础命令
-- 1.进入 HBase 客户端命令行
bin/hbase shell
-- 2.查看帮助命令
help
-- 3.查看当前数据库中有哪些表
list


-- 表空间
-- 1.创建namespace
create_namespace 'nametest'  
-- 2.删除namespace
drop_namespace 'nametest'  
-- 3.查看namespace
describe_namespace 'nametest'  
-- 4.列出所有namespace
list_namespace  
-- 5.在namespace下创建表
create 'nametest:testtable', 'fm1'  
-- 6.查看namespace下的表
list_namespace_tables 'nametest'  

-- 表的操作
-- 1.创建表 , student 为表名,info为列族
create 'student','info'
-- 2.插入数据到表  1001 为rowkey , info:sex 为列族和列名,male为值
put 'student','1001','info:sex','male'
put 'student','1002','info:sex','female'
-- 3.扫描查看表数据
scan 'student'
scan 'student',{LIMIT=>10}
scan 'student',{STARTROW => '1001', STOPROW => '1001'}
scan 'student',{STARTROW => '1001'}
scan 'student',{LIMIT => 10,INTERVAL => 10000,CACHE => 10000}. # 一次查询10000行,cache 为10000. https://hbase.apache.org/book.html#_commands
-- 4.查看表结构
describe `student`
-- 5.更新指定字段的数据
put 'student','1001','info:name','Nick'
put 'student','1001','info:age','100'
-- 6.查看“指定行”或“指定列族:列”的数据
get 'student','1001'
get 'student','1001','info:name'
get 'student','1001',{COLUMN=>'info:name',VERSIONS=>1}
-- 7.统计表数据行数
count 'student',INTERVAL => 10000
-- 8.删除数据
-- 删除某 rowkey 的全部数据:
deleteall 'student','1001'
-- 删除某 rowkey 的某一列数据:
put 'student','1001','info:sex','male'
put 'student','1001','info:age','18'
delete 'student','1002','info:sex'
-- 9.清空表数据
truncate 'student'
-- 提示:清空表的操作顺序为先 disable,然后再 truncate 
-- 10.删除表
-- 首先需要先让该表为 disable 状态
disable 'student'
-- 然后才能 drop 这个表: 
drop 'student'
-- 提示:如果直接 drop 表,会报错:ERROR: Table student is enabled. Disable it first. 
-- 11.变更表信息
-- 将 info 列族中的数据存放 3 个版本:
alter 'student',{NAME=>'info',VERSIONS=>3} 
get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3}

参考
hbase-shell-command

FILTER

2.3 Shell Fiter

2.3.1 介绍

scan命令我们经常会大量使用Filter,hbase shell提供的filter都可以在hbase client包中找到对应的类,它们都是Filter的子类,很多命令都是通过filter来进行实现的 

{}中的语法是ruby的map的语法,FILTER必须大写,filter的参数是根据构造方法来的,也就是相当于java中的new Filter('param1','param2')等,这里只是省略了new参数而已。
当然同样可以使用ruby中new对象的方式,只是那样就必须使用全限定名称。后面会举一个全限定名称的例子

使用show_filters命令查看shell中定义了哪些filter常量,如果想要使用shell中未定义的常量,在使用的时候必须手动import filter的全路径。各类的使用说明: org.apache.hadoop.hbase.filter

  • DependentColumnFilter
  • KeyOnlyFilter
  • ColumnCountGetFilter
  • SingleColumnValueFilter
  • PrefixFilter
  • SingleColumnValueExcludeFilter
  • FirstKeyOnlyFilter
  • ColumnRangeFilter
  • TimestampsFilter
  • FamilyFilter
  • QualifierFilter
  • ColumnPrefixFilter
  • RowFilter
  • MultipleColumnPrefixFilter
  • InclusiveStopFilter
  • PageFilter
  • ValueFilter
  • ColumnPaginationFilter

比较器

HBase的filter有四种比较器:

比较运算符

HBase的filter中有7个比较运算符:

2.3.2 使用

ruby中正则表达式

# 过滤 test 表中 cf a,列为 info,值不为 空的数据 
scan 'test',{LIMIT => 10,FILTER => "SingleColumnValueFilter('a','info',=,'regexstring:\\S')"}
# 列前缀为  parent的数据
scan 'test',{LIMIT => 10,FILTER => "ColumnPrefixFilter('parent')"}

后续再补充啦。。。

还可以有如下写法

import org.apache.hadoop.hbase.filter.SingleColumnValueFilter
import org.apache.hadoop.hbase.filter.CompareFilter
import org.apache.hadoop.hbase.filter.BinaryComparator
scan ‘tweet0’, { FILTER => SingleColumnValueFilter.new(Bytes.toBytes(‘info’), Bytes.toBytes(‘id’), CompareFilter::CompareOp.valueOf(‘EQUAL’), BinaryComparator.new(Bytes.toBytes(‘1001158684’))), COLUMNS=>[‘info:id’]}


# 注意:
# 1)如果scan中指定了COLUMNS,则FILTER中所使用的列需要包含在所指定的COLUMNS中,否则,filter不起作用。
# 2)HBase中主要的操作对象是一个个的cell,每个cell都可以有多个版本。如果使用过滤器ValueFilter,就会只有那些符合条件的cell被查出来。跟关系数据库的查询不同,关系数据库查出来的结果中各行都有相同的列。而HBase,查出来的结果中,不同的行会有不同的列。
# 3)filter不会降低服务方的IO,它会把符合条件的子集传给客户端。即,它是在对查出的结果进行过滤,而不是象原来sql中的where子句。所以,如果要查出的结果中不包含filter需要的列,则filter就不能发挥作用。

3.HBase进阶

3.1架构原理

➢ Region

table在行的方向上分隔为多个RegionRegion是HBase中分布式存储和负载均衡的最小单元,即不同的region可以分别在不同的Region Server上,但同一个Region是不会拆分到多个server上。Region按大小分隔,表中每一行只能属于一个region。随着数据不断插入表,region不断增大,当region的某个列族达到一个阈值,时就会分成两个新的region

➢ Store

每一个region有一个或多个store组成,至少是一个store,hbase会把一起访问的数据放在一个store里面,即为每个ColumnFamily建一个store(即有几个ColumnFamily,也就有几个Store)。一个Store由一个memStore0多个StoreFile组成

➢ StoreFile

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

➢ WAL(Hlog)

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

➢ MemStore

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

个人理解:

1.store(源码中一个类)理解为对应管理column Family,一个列族对应hdfs文件系统中一个文件夹(和hive中分区类似)

2.一个store可以多个storefile,其文件格式为hfile(类似hive中orc,parquet)

3.刷写一次产生一个hfile

4.zk分担了和客户端和hmaster的交互。即客户端进行读写请求直接查询zk,然后去操作HRegion Server。因此,如果只是读写数据,HMaster挂了也同样可以正常运转,如果是修改元数据则会报错(ddl)

5.Hlog理解为对应mysql中binlog

3.2 写流程

写流程:

3.3 MemStore Flush

MemStore 刷写时机:

  • 当某个 memstore 的大小达到了 hbase.hregion.memstore.flush.size(默认值 128M),其所在 region 的所有 memstore 都会刷写。 当 memstore 的大小达到了hbase.hregion.memstore.flush.size(默认值 128M)* hbase.hregion.memstore.block.multiplier(默认值 4)时,会阻止继续往该 memstore 写数据
  • 当 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 写数据
  • 到达自动刷写的时间,也会触发memstoreflush。自动刷新的时间间隔由该属性进行 配置 hbase.regionserver.optionalcacheflushinterval(默认 1 小时)
  • 当 WAL 文件的数量超过 hbase.regionserver.max.logs,region 会按照时间顺序依次进 行刷写,直到 WAL 文件数量减小到 hbase.regionserver.max.log 以下(该属性名已经废弃, 现无需手动设置,最大值为 32)

3.4读流程

读流程

3.5 StoreFile Compaction

由于 memstore 每次刷写都会生成一个新的 HFile,且同一个字段的不同版本(timestamp) 和不同类型(Put/Delete)有可能会分布在不同的 HFile 中,因此查询时需要遍历所有的 HFile为了减少 HFill的个数,以及清理掉过期和删除的数据,会进行 StoreFile Compaction

Compaction 分为两种,分别是 Minor Compaction 和 Major Compaction。Minor Compaction会将临近的若干个较小的HFile 合并成一个较大的 HFile,但不会清理过期和删除的数据。 Major Compaction 会将一个 Store 下的所有的 HFile 合并成一个大 HFile,并且会清理掉过期 和删除的数据

触发机制:

➢  由hbase.hregion.majorcompaction参数指定,默认为7天(7天触发一次)。此操作比较耗资源,生产环境建议关掉,改手动触发

➢ hbase.hstore.compactionThreshold设置阈值,默认为3,当hfile超过3时(不包括3),自动触发合并

具体参考  compaction

3.6 Region Split

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

Region Split 时机:

Apache HBase Region Splitting and Merging - Cloudera Bloghttps://blog.cloudera.com/apache-hbase-region-splitting-and-merging/

4.HBaseAPI

4.1HBaseAPI

关于删除

参考代码

4.2MapReduce

参考代码

4.3与 Hive 的集成

4.3.1 HBase 与 Hive 的对比

1.Hive

2.HBase

4.3.2案例

➢ 建立 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:co
mm,info:deptno")
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");

1.完成之后,可以分别进入 Hive 和 HBase 查看,都生成了对应的表

2.不能将数据直接 load 进 Hive 所关联 HBase 的那张表中
➢ 在 HBase 中已经存储了某一张表 hbase_emp_table,然后在 Hive 中创建一个外部表来 关联 HBase 中的 hbase_emp_table 这张表,使之可以借助 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:co mm,info:deptno")
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");

一般是此操作

5.HBase优化

5.1高可用

在 HBase 中 HMaster 负责监控 HRegionServer 的生命周期,均衡 RegionServer 的负载, 如果 HMaster 挂掉了,那么整个 HBase 集群将陷入不健康的状态,并且此时的工作状态并 不会维持太久。所以 HBase 支持对 HMaster 的高可用配置。只需 conf 目录下创建 backup-masters 文件,写入比用hmaster即可

HMaster和zk进行交互,当HMaster挂了后,backup-Master和zk通信升级成HMaster,如果有多个backup,则谁先到谁成HMaster

5.2 预分区

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

5.3 RowKey 设计

我司设计rowkey 统一采用规则:concat(substring(md5(biz_key),1,4),'_',biz_key)

5.4 内存优化

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

6 Hbase数据结构&存储结果

6.1 Hbase之LSM

6.1.1 核心思想

如上图所示,LSM树有以下三个重要组成部分:

1) MemTable

MemTable是在内存中的数据结构,用于保存最近更新的数据,会按照Key有序地组织这些数据,LSM树对于具体如何组织有序地组织数据并没有明确的数据结构定义,例如Hbase使跳跃表来保证内存中key的有序。

因为数据暂时保存在内存中,内存并不是可靠存储,如果断电会丢失数据,因此通常会通过WAL(Write-ahead logging,预写式日志)的方式来保证数据的可靠性。

2) Immutable MemTable

当 MemTable达到一定大小后,会转化成Immutable MemTable。Immutable MemTable是将转MemTable变为SSTable的一种中间状态。写操作由新的MemTable处理,在转存过程中不阻塞数据更新操作。

3) SSTable(Sorted String Table)

有序键值对集合,是LSM树组在磁盘中的数据结构。为了加快SSTable的读取,可以通过建立key的索引以及布隆过滤器来加快key的查找。

这里需要关注一个重点,LSM树(Log-Structured-Merge-Tree)正如它的名字一样,LSM树会将所有的数据插入、修改、删除等操作记录(注意是操作记录)保存在内存之中,当此类操作达到一定的数据量后,再批量地顺序写入到磁盘当中。这与B+树不同,B+树数据的更新会直接在原数据所在处修改对应的值,但是LSM数的数据更新是日志式的,当一条数据更新是直接append一条更新记录完成的。这样设计的目的就是为了顺序写,不断地将Immutable MemTable flush到持久化存储即可,而不用去修改之前的SSTable中的key,保证了顺序写 

6.1.2 定义

 

  • 图中分成了左侧绿色的内存部分和右侧蓝色的磁盘部分(定义1)。
  • 图左侧绿色的内存部分只包含Level 0树,右侧蓝色的磁盘部分则包含Level 1-n等多棵"树"(定义2)
  • 图左侧绿色的内存部分中Level 0是一颗二叉排序树(定义3)。注意这里的有序性,该性质决定了LSM树优异的读写性能。
  • 图右侧蓝色的磁盘部分所包含的Level 1到Level n多颗树,虽然叫做“树”,但本质是按数据key排好序后,顺序写在磁盘上的一个个文件(定义4) ,注意这里再次出现了有序性。
  • 内存中的Level 0树在达到阈值后,会在内存中遍历排好序的Level 0树并顺序写入磁盘的Level 1。同样的,在磁盘中的Level n(n>0)达到阈值时,则会将Level n层的多个文件进行归并,写入Level n+1层。(定义5)
  • 除了内存中的Level 0层做原地更新外,对已写入磁盘上的数据,都采用Append形式的磁盘顺序写,即更新和删除操作并不去修改老数据,只是简单的追加新数据。图1中右侧蓝色的磁盘部分,Level 1和Level 2均包含key为2的数据,同时图1左侧绿色内存中的Level 0树也包含key为2的数据节点。(定义6)

6.1.3 优缺点

优:增、删、改操作飞快,写吞吐量极大。

缺:读操作性能相对被弱化;不擅长区间范围的读操作; 归并操作较耗费资源

以上是对LSM树基本操作以及优缺点的分析,我们可以据此得出LSM树的设计原则:

如果说B/B+树的读写性能基本平衡的话,LSM树的设计原则通过舍弃部分读性能,换取了无与伦比的写性能。该数据结构适合用于写吞吐量远远大于读吞吐量的场景,得到了NoSQL届的喜爱和好评

常用的一下组件,如rocksdb,clickhouse、kafka 都有用到 LSM

具体可参考如下:

深入浅出分析LSM树(日志结构合并树) - 知乎

LSM树详解 - 知乎

6.2 Hbase之跳表

HBase--内存结构之跳表数据结构浅析_Keep hunger的博客-CSDN博客

6.3 Hbase之布隆过滤器

布隆过滤器在HBase中的应用 | 布兰特 | 不忘初心

待整理。。。

www.htsjk.Com true http://www.htsjk.com/hbase/45718.html NewsArticle hbase简介,1.2HBase数据 1.HBase简介 1.1 定义 HBase 是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。 1.2 HBase数据模型 1.2.1逻辑结构 逻辑上HBase 的数据模型同关系型数据库很类似数...
评论暂时关闭