HBase入门

2021-02-04 10:16:11 浏览数 (1)

HBase

安装单机

环境

Centos7 Hbase

安装JDK

代码语言:txt复制
yum install java-1.8.0-openjdk* -y

下载HBASE

http://mirror.bit.edu.cn/apache/hbase/2.2.6/

解压到Linux

代码语言:txt复制
tar -xf hbase-1.2.8-bin.tar.gz
cd hbase-2.2.6

修改JAVA_HOME配置文件

代码语言:txt复制
vim conf/hbase-env.sh
// 注意这个是在CentOS上的java位置
export JAVA_HOME=/etc/alternatives/java_sdk_1.8.0/

启动

代码语言:txt复制
./bin/start-hbase.sh

查看Web-UI

http://localhost:16010查看Hbase的Web UI,以便查看是否启动成功。

Client

自带的Client

代码语言:txt复制
./hbase shell

# 查看帮助
help

创建表

需指定表名称列簇名

代码语言:txt复制
hbase(main):105:0> create 'mytest', 'lt'
Created table mytest
Took 0.7247 seconds

=> Hbase::Table - mytest

查看当前表信息

代码语言:txt复制
hbase(main):001:0> list 'mytest'
TABLE
mytest
1 row(s)
Took 0.2895 seconds
=> ["mytest"]

查看表详细信息

代码语言:txt复制
hbase(main):002:0> describe 'mytest'
Table mytest is ENABLED
mytest
COLUMN FAMILIES DESCRIPTION
{NAME => 'lt', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS
 => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', RE
PLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_
WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '6553
6'}
1 row(s)
QUOTAS
0 row(s)
Took 0.1686 seconds

写入数据

随便写入4条数据

其实并不随便,对应的解释,可以看后面的数据模型部分。

代码语言:txt复制
hbase(main):003:0> put 'mytest','row1','lt:a','value1'
Took 0.0392 seconds
hbase(main):004:0> put 'mytest','row2','lt:b','value2'
Took 0.0042 seconds
hbase(main):005:0> put 'mytest','row3','lt:c','value3'
Took 0.0025 seconds
hbase(main):006:0> put 'mytest','row3','lt:d','value4'
Took 0.0054 seconds 

查看表中所有数据

代码语言:txt复制
hbase(main):007:0> scan 'mytest'
ROW                            COLUMN CELL
 row1                          column=lt:a, timestamp=1609210379880, value=value1
 row2                          column=lt:b, timestamp=1609210387527, value=value2
 row3                          column=lt:c, timestamp=1609210396636, value=value3
 row3                          column=lt:d, timestamp=1609210494696, value=value4
3 row(s)
Took 0.0188 seconds

查看一条信息

案例1

代码语言:txt复制
get 'mytest' , 'row1'
COLUMN                         CELL
 lt:a                          timestamp=1609210379880, value=value1
1 row(s)
Took 0.0202 seconds 

案例2

代码语言:txt复制
hbase(main):009:0> get 'mytest' , 'row3'
COLUMN                         CELL
 lt:c                          timestamp=1609210396636, value=value3
 lt:d                          timestamp=1609210494696, value=value4
1 row(s)
Took 0.0059 seconds

可以看到,row1,row2实则是key

而获取到的数据,也不太一样,这是因为,在写入时,为row3多写入了一条属性。

其他

可输入help,查看更多命令。

HBASE的数据模型

Table

对应上面的案例mytest

Hbase的table由多个行组成

Row

对应上面的案例row1...

一个行在Hbase中由一个或多个有值的列组成。Row按照字母进行排序,因此行健的设计非常重要。这种设计方式可以让有关系的行非常的近,通常行健的设计是网站的域名反转,比如(org.apache.www, org.apache.mail, org.apache.jira),这样的话所有的Apache的域名就很接近。

Column

对应上面的案例lt:

列由列簇加上列的标识组成,一般是“列簇:列标识”,创建表的时候不用指定列标识

Column Family

对应上面的案例lt:a、lt:b....

列簇在物理上包含了许多的列与列的值,每个列簇都有一些存储的属性可配置。例如是否使用缓存,压缩类型,存储版本数等。在表中,每一行都有相同的列簇,尽管有些列簇什么东西也没有存。

Column Qualifier

列簇的限定词,理解为列的唯一标识。但是列标识是可以改变的,因此每一行可能有不同的列标识

Cell

Cell是由row,column family,column qualifier包含时间戳与值组成的{row key,column(=<family> <qualifier>),version},一般表达唯一确定的单元.

一般get出来的为最新版本,也可以指定,如下为

显示最新的2个版本的数据

代码语言:txt复制
hbase(main):004:0> get 'mytest','row3',{COLUMNS=>['lt:c','lt:d'],VERSIONS=>2}
COLUMN                         CELL  
 lt:c                          timestamp=1609210396636, value=value3 
 lt:d                          timestamp=1609210494696, value=value4
1 row(s)
Took 0.0050 seconds

Timestamp

对应上面的案例timestamp=1609210494696...

时间戳一般写在value的旁边,代表某个值的版本号,默认的时间戳是你写入数据的那一刻,但是你也可以在写入数据的时候指定不同的时间戳

关于索引

HBase 是一个稀疏的、分布式、持久、多维、排序的映射,它以行键(row key),列键(column key)和时间戳(timestamp)为索引。

关于排序

Hbase在存储数据的时候,有两个SortedMap,首先按照rowkey进行字典排序,然后再对Column进行字典排序。

代码语言:txt复制
hbase(main):009:0> get 'mytest' , 'row3'
COLUMN                         CELL
 lt:c                          timestamp=1609210396636, value=value3
 lt:d                          timestamp=1609210494696, value=value4
1 row(s)
Took 0.0059 seconds

所以,刚刚的查询单条数据时,可以看到是,先根据 row*,进行字典排序,在把row3的属性,也就是lt:*进行字典排序。

Hbase与关系型数据库对比

属性

Hbase

RDBMS

数据类型

只有字符串

丰富的数据类型

数据操作

增删改查,不支持join

各种各样的函数与表连接

存储模式

基于列式存储

基于表结构和行式存储

数据保护

更新后仍然保留旧版本

替换

可伸缩性

轻易增加节点

需要中间层,牺牲性能

Hbase设计时要考虑的因素

Hbase关键概念:rowkey列簇时间戳

  • 这个表应该有多少列簇
  • 列簇使用什么数据
  • 每个列簇有有多少列
  • 列名是什么,尽管列名不必在建表时定义,但读写数据是要知道的
  • 单元应该存放什么数据
  • 每个单元存储多少时间版本
  • 行健(rowKey)结构是什么,应该包含什么信息

设计要点

行键设计

关键部分,直接关系到后续服务的访问性能。如果行健设计不合理,后续查询服务效率会成倍的递减。

  • 避免单调的递增行健,因为Hbase的行健是有序排列的,这样可能导致一段时间内大部分写入集中在某一个Region上进行操作,负载都在一台节点上。可以设计成: metric_type,不同的metric_type可以将压力分散到不同的region上
  • 行健短到可读即可,因为查询短键不必长键性能好多少,所以设计时要权衡长度。
  • 行健不能改变,唯一可以改变的方式是先删除后插入
列簇设计

列簇是一些列的集合,一个列簇的成员有相同的前缀,以冒号(:)作为分隔符。

  • 现在Hbase不能很好处理2~3个以上的列簇,所以尽可能让列簇少一些,如果表有多个列簇,列簇A有100万行数据,列簇B有10亿行,那么列簇A会分散到很多的Region导致扫描列簇A的时候效率底下。
  • 列簇名的长度要尽量小,一个为了节省空间,另外加快效率,比如d表示data,v表示value
列簇属性配置

HFile数据块,默认是64KB,数据库的大小影响数据块索引的大小。数据块大的话一次加载进内存的数据越多,扫描查询效果越好。但是数据块小的话,随机查询性能更好。

代码语言:txt复制
> create 'mytable',{NAME => 'lt1', BLOCKSIZE => '65536'}

数据块缓存,数据块缓存默认是打开的,如果一些比较少访问的数据可以选择关闭缓存

代码语言:txt复制
> create 'mytable',{NAME => 'lt1', BLOCKCACHE => 'FALSE'}

数据压缩,压缩会提高磁盘利用率,但是会增加CPU的负载,看情况进行控制

代码语言:txt复制
> create 'mytable',{NAME => 'lt1', COMPRESSION => 'SNAPPY'}

Hbase表设计是和需求相关的,但是遵守表设计的一些硬性指标对性能的提升还是很有帮助的,这里整理了一些设计时用到的要点。

0 人点赞