Hbase

2020-06-09  本文已影响0人  笔记本一号

概念

hbase是一个分布式的、面向列式存储的、高可扩展高性能的非关系型数据库,其技术是仿照了Google的文件系统Bigtable,是建立在hadoop集群的基础之上并利用hdfs实现了分布式存储,基于hadoop的hdfs进行存储的同时也利用了hdfs的容错实现了高容错性,hbase具有对数据进行实时的读写的能力,内部使用哈希表存储索引,所以可以在hdfs中快速查找数据。

场景

Hadoop 只能执行批量处理,并且只以顺序方式访问数据。这意味着必须搜索整个数据集, 即使是最简单的搜索工作。 当处理结果在另一个庞大的数据集,也是按顺序处理一个巨大的数据集。在这一点上,一个 新的解决方案,需要访问数据中的任何点(随机访问)单元
hbase可以作为Hadoop的随机存取数据库,适用于非结构化数据的存储,不适用于存储关系复杂的数据模型,是建立在 HDFS 之上,被设计用来提供高可靠性、高性能、列存储、可伸缩、多版本的 NoSQL 的分布式数据存储系统,实现对大型数据的实时、随机的读写访问

HBase 中的表特点

1、大表:一个表可以有上十亿行,上百万列

2、面向列:面向列(族)的存储和权限控制。

3、稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。

4、无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一 张表中不同的行可以有截然不同的列

Rowkey的概念

由于Hbase只支持3中查询方式:

1、基于Rowkey的单行查询

2、基于Rowkey的范围扫描

3、全表扫描

因此,Rowkey对Hbase的性能影响非常大,Rowkey的设计就显得尤为的重要。设计的时候要兼顾基于Rowkey的单行查询也要键入Rowkey的范围扫描。具体Rowkey要如何设计后续会整理相关的文章做进一步的描述。这里大家只要有一个概念就是Rowkey的设计极为重要。

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

Column的概念

列,可理解成MySQL列。

ColumnFamily的概念

列族, HBase引入的概念。

Hbase通过列族划分数据的存储,列族下面可以包含任意多的列,实现灵活的数据存取。就像是家族的概念,我们知道一个家族是由于很多个的家庭组成的。列族也类似,列族是由一个一个的列组成(任意多)。

Hbase表的创建的时候就必须指定列族。就像关系型数据库创建的时候必须指定具体的列是一样的。

Hbase的列族不是越多越好,官方推荐的是列族最好小于或者等于3。我们使用的场景一般是1个列族。

TimeStamp的概念

TimeStamp对Hbase来说至关重要,因为它是实现Hbase多版本的关键。在Hbase中使用不同的timestame来标识相同rowkey行对应的不通版本的数据。

HBase 中通过 rowkey 和 columns 确定的为一个存储单元称为 cell。每个 cell 都保存着同一份 数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64 位整型。时间戳可以由 hbase在数据写入时自动赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。 每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。
为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,hbase 提供了两种数据版 本回收方式:
  - 保存数据的最后 n 个版本
  - 保存最近一段时间内的版本(设置数据的生命周期 TTL)。
用户可以针对每个列簇进行设置。

单元格(Cell)

由{rowkey, column( = + ), version} 唯一确定的单元。 Cell 中的数据是没有类型的,全部是字节码形式存贮。

根据hbase的结构,我们可以简单的列出几个增删改的语句

创建表
# 语法:create <table>, {NAME => <family>, VERSIONS => <VERSIONS>}
# 例如:创建表t1,有两个family name:f1,f2,且版本数均为2
hbase(main)> create 't1',{NAME => 'f1', VERSIONS => 2},{NAME => 'f2', VERSIONS => 2}
添加数据
# 语法:put <table>,<rowkey>,<family:column>,<value>,<timestamp>
# 例如:给表t1的添加一行记录:rowkey是rowkey001,family name:f1,column name:col1,value:value01,timestamp:系统默认
hbase(main)> put 't1','rowkey001','f1:col1','value01'
查询数据
a)查询某行记录

# 语法:get <table>,<rowkey>,[<family:column>,....]
# 例如:查询表t1,rowkey001中的f1下的col1的值
hbase(main)> get 't1','rowkey001', 'f1:col1'
# 或者:
hbase(main)> get 't1','rowkey001', {COLUMN=>'f1:col1'}
# 查询表t1,rowke002中的f1下的所有列值
hbase(main)> get 't1','rowkey001'
b)扫描表
# 语法:scan <table>, {COLUMNS => [ <family:column>,.... ], LIMIT => num}
# 另外,还可以添加STARTROW、TIMERANGE和FITLER等高级功能
# 例如:扫描表t1的前5条数据
hbase(main)> scan 't1',{LIMIT=>5}
c)查询表中的数据行数

# 语法:count <table>, {INTERVAL => intervalNum, CACHE => cacheNum}
# INTERVAL设置多少行显示一次及对应的rowkey,默认1000;CACHE每次去取的缓存区大小,默认是10,调整该参数可提高查询速度
# 例如,查询表t1中的行数,每100条显示一次,缓存区为500
hbase(main)> count 't1', {INTERVAL => 100, CACHE => 500}
删除数据
a )删除行中的某个列值

# 语法:delete <table>, <rowkey>,  <family:column> , <timestamp>,必须指定列名
# 例如:删除表t1,rowkey001中的f1:col1的数据
hbase(main)> delete 't1','rowkey001','f1:col1'
注:将删除改行f1:col1列所有版本的数据
b )删除行

# 语法:deleteall <table>, <rowkey>,  <family:column> , <timestamp>,可以不指定列名,删除整行数据
# 例如:删除表t1,rowk001的数据
hbase(main)> deleteall 't1','rowkey001'
c)删除表中的所有数据

# 语法: truncate <table>
# 其具体过程是:disable table -> drop table -> create table
# 例如:删除表t1的所有数据
hbase(main)> truncate 't1'
表的管理
1)查看有哪些表
hbase(main)> list
2)创建表

# 语法:create <table>, {NAME => <family>, VERSIONS => <VERSIONS>}
# 例如:创建表t1,有两个family name:f1,f2,且版本数均为2
hbase(main)> create 't1',{NAME => 'f1', VERSIONS => 2},{NAME => 'f2', VERSIONS => 2}
3)删除表
分两步:首先disable,然后drop
例如:删除表t1

hbase(main)> disable 't1'
hbase(main)> drop 't1'
4)查看表的结构

# 语法:describe <table>
# 例如:查看表t1的结构
hbase(main)> describe 't1'
5)修改表结构
修改表结构必须先disable

# 语法:alter 't1', {NAME => 'f1'}, {NAME => 'f2', METHOD => 'delete'}
# 例如:修改表test1的cf的TTL为180天
hbase(main)> disable 'test1'
hbase(main)> alter 'test1',{NAME=>'body',TTL=>'15552000'},{NAME=>'meta', TTL=>'15552000'}
hbase(main)> enable 'test1'

hbase架构

HBase 依赖于 HDFS 做底层的数据存储,HBase 依赖于 MapReduce 做数据计算,HBase 依赖于 ZooKeeper 做服务协调
hbases是java编写的,通过java api实现了提供内部的各个功能,hbases架构是一个典型的M-Z-S(Master-Zookeeper-Slaves)体系架构,主要进行存储工作的还是hdfs,所以说hbase的存储是基于hdfs实现的,写入到hbase的数据最终是会落地到hdfs中

在hbase架构中主要有HMaster、RegionServer、region还有Zookeeper组成

主要负责Table和Region的管理工作,在hbase架构中充当主节点,负责监控集群中从节点RegionServer的信息,包括健康状况信息,管理着哪些region的信息分布在哪些RegionServer,在RegionServer挂掉时HMaster会将挂掉的RegionServer中的region转移到其他的RegionServer中;

HMaster还负责管理用户对hbase表的增删改操作,维护和管理HBase表的结构、和各个Region的元数据信息,可以决定分配哪些region到哪个RegionServer节点,从而协调集群的负载达到负载均衡;

HMaster不会进行处理读写请求。hbase支持HA集群模式,所以hbase集群是有多个HMaster存在的,但是处于活跃状态的就只有一个,活跃的HMaster宕机时,会从其他备用的HMaster选举一个作为活跃的HMaster,实现了hbase的高可用。

HRegionServer管理一些列HRegion对象,每个HRegion对应Table中一个Region,HRegion由多个HStore组成,每个HStore对应Table中一个Column Family的存储。

HRegionServer处理region的读写,region会随着插入的数据越来越多,会进行拆分,默认大小是10G一个,

此外RegionServer还会定时的向HMaster和Zookeeper报告HRegion的健康状况和维护的region的信息 可以看出HBase只有增添数据,所有的更新和删除操作都是在后续的Compact历程中举行的,使得用户的写操作只要进入内存就可以立刻返回,实现了HBase I/O的高性能。
HBase中的所有数据文件都存储在Hadoop HDFS文件系统上,格式主要有两种:

工作流程

写流程

客户端发向Zoopeeker发起写请求获取RegionServer的地址,客户端获取到RegionServer的地址后向地址的RegionServer发起写请求,RegionServer接收到写请求后先会检查本机的region的状态,检查完成后会就会对region中的memstore进行写入操作,这一过程是原子性的要全部失败要么全部成功,当memstore达到预期的大小后,就会进行Flush操作,将缓存中的数据写入文件形成一个个storeFile文件,当storeFile到达一定数量会进行合并(Compaction),Compaction将多个storeFile合并成一个大的storeFile,当storeFile文件大小超过预定值一般为10G,就会触发拆分(split),split操作会把一个region分为两份,HMaster会对这两份region分配给相应的RegionServer,在写操作完成后会将storeFile落地到hdfs中存储

读流程

客户端发向Zoopeeker发起读请求获取RegionServer的地址,客户端获取到RegionServer的地址后向地址的RegionServer发起读请求,RegionServer接收到读请求后先会扫描自身的memstore,在扫描blockcache,如果没有找到相应的数据就会到StoreFile读取数据返回给客户端

Hbase环境搭建

先装好hadoop和jdk,完事后进行安装hbase
编辑hbase安装目录的conf目录,编辑hbase-env.sh

image.png

注释掉jdk7的配置

image.png

使用hbase自带的zk

image.png

将hadoop的core-site.xml和hdfs-site.xml拷贝到安装目录的conf目录下


image.png

编辑hbase安装目录的conf文件中的hbase-site.xml,端口配置为装好的hadoop的端口

image.png

配置好后启动hbase,进入安装目录的bin文件夹 ./start-hbase.sh 启动,jps查看是否启动成功

image.png

输入ip:16010可以查看hbase的管理界面 例如:192.168.200.128:16010


image.png

启动完成后hbase会在hdfs中创建一个目录,查看hdfs中的目录

image.png
上一篇 下一篇

猜你喜欢

热点阅读