0%

概述

HBase是一个K/V存储型NoSQL数据库,与一般k/v数据库不同的是,Hbase的valuerowkeycolumn family:qualifierTimeStamp这个三个维度快速定位。

HBase中rowkey可以唯一标识一行记录,在HBase查询的时候,有两种方式:

  • 通过get方式,指定rowkey获取唯一一条记录
  • 通过scan方式,设置startRow和stopRow参数进行范围匹配
  • 全表扫描,即直接扫描整张表中所有行记录

rowkey长度原则

rowkey是一个二进制码流,可以是任意字符串,最大长度64kb,实际应用中一般为10-100bytes,以byte[]形式保存,一般设计成定长。

建议越短越好,不要超过16个字节

rowkey散列原则

  • 尽量不要将rowkey设计成连续的值,如时间戳;
  • 为rowkey增加随机散列字段,使数据均衡分布在每个RegionServer;
  • 如果没有散列字段,所有的数据都会集中在一个RegionServer上,这样在数据检索的时候负载会集中在个别的RegionServer上,造成热点问题,会降低查询效率。

什么是热点?
热点发生在大量的client直接访问集群的一个或极少数个节点(访问可能是读,写或者其他操作)。大量访问会使热点region所在的单个机器超出自身承受能力,引起性能下降甚至region不可用.

rowkey唯一原则

必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的.

设计方法

  • Salting: 指将随机数据添加到行键的开头。
  • Hashing: 哈希会使同一行永远用一个前缀加盐。
  • 反转: 以手机号为rowkey,可以将手机号反转后的字符串作为rowkey
  • 时间戳反转: Long.Max_Value - timestamp
  • 尽量保持 ColumnFamily 名称尽可能小,最好是一个字符
  • 虽然详细的属性名称更易于阅读,但更喜欢使用较短的属性名称来存储在HBase中。

参考链接

Hbase版本数量

Hbase版本数量分为最大版本数量最小版本数量

  • HBase最大版本数量:HBase 通过 HColumnDescriptor 为每个列族配置要存储的最大行数版本。最大版本的默认值为1。最大版本的数量可能需要根据应用程序需求增加或减少。不建议将最高版本数设置为极高的级别(例如,数百个或更多)。
  • HBase最小版本数量:与最大行版本数一样,HBase 通过 HColumnDescriptor 为每个列族配置要保留的最小行数版本。最小版本的默认值为0,这意味着该功能被禁用。行版本参数的最小数目与生存时间参数一起使用,并且可以与行版本参数的数目组合在一起,以允许诸如“保留最多T分钟值的数据,最多N个版本,但是至少保留 M 个版本 “(其中M 是最小行版本数的值,M < N )。仅当对列族启用了生存时间并且必须小于行版本的数量时,才应设置此参数。

HBase 生存时间(TTL)

  • ColumnFamilies 可以以为单位来设置 TTL(Time To Live)长度,一旦达到到期时间,HBase 将自动删除行。
  • 也支持设置时间以每个单元为基础生存。
  • 单元 TTL 以毫秒为单位而不是秒。
  • 单元 TTL 不能将一个单元的有效生命周期延长超过 ColumnFamily 级 TTL 设置。

测试

默认Hbase列族最多保存一个版本的数据,可以通过下面命令修改,也可以使用HColumnDescriptor

alter 'test', NAME => 'cf', VERSIONS => 3

创建表的时候指定版本数量:

hbase(main):018:0> create 'test',{NAME=>'base_info',VERSIONS=>3 },{NAME=>'extra_info',VERSIONS=>1 } 
0 row(s) in 4.2670 seconds

更多详细的用法可以参考help 'create':

hbase(main):016:0> help 'create'
Creates a table. Pass a table name, and a set of column family
specifications (at least one), and, optionally, table configuration.
Column specification can be a simple string (name), or a dictionary
(dictionaries are described below in main help output), necessarily
including NAME attribute.
Examples:

Create a table with namespace=ns1 and table qualifier=t1
  hbase> create 'ns1:t1', {NAME => 'f1', VERSIONS => 5}

Create a table with namespace=default and table qualifier=t1
  hbase> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'}
  hbase> # The above in shorthand would be the following:
  hbase> create 't1', 'f1', 'f2', 'f3'
  hbase> create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, BLOCKCACHE => true}
  hbase> create 't1', {NAME => 'f1', CONFIGURATION => {'hbase.hstore.blockingStoreFiles' => '10'}}
  hbase> create 't1', {NAME => 'f1', IS_MOB => true, MOB_THRESHOLD => 1000000, MOB_COMPACT_PARTITION_POLICY => 'weekly'}

Table configuration options can be put at the end.
Examples:

  hbase> create 'ns1:t1', 'f1', SPLITS => ['10', '20', '30', '40']
  hbase> create 't1', 'f1', SPLITS => ['10', '20', '30', '40']
  hbase> create 't1', 'f1', SPLITS_FILE => 'splits.txt', OWNER => 'johndoe'
  hbase> create 't1', {NAME => 'f1', VERSIONS => 5}, METADATA => { 'mykey' => 'myvalue' }
  hbase> # Optionally pre-split the table into NUMREGIONS, using
  hbase> # SPLITALGO ("HexStringSplit", "UniformSplit" or classname)
  hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
  hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit', REGION_REPLICATION => 2, CONFIGURATION => {'hbase.hregion.scan.loadColumnFamiliesOnDemand' => 'true'}}
  hbase> create 't1', 'f1', {SPLIT_ENABLED => false, MERGE_ENABLED => false}
  hbase> create 't1', {NAME => 'f1', DFS_REPLICATION => 1}

You can also keep around a reference to the created table:

  hbase> t1 = create 't1', 'f1'

Which gives you a reference to the table named 't1', on which you can then
call methods.

节点 端口号 协议 使用 说明
zookeeper 2181 zkCli.sh -server zookeeper1:2181 客户端接入
2888 N/A 集群内部通讯
3888 N/A 集群内部通讯
HDFS Namenode 9000 HDFS hdfs dfs -ls hdfs://namenode1:9000/ 客户端接入
50070 HTTP http://namenode1:50070/ 集群监控
HDFS SecondaryNamenode 50090 HTTP http://namenode1:50090/ secondary监控
HDFS Datanode 50010 N/A 客户端接入/其他节点接入
50020 N/A
50075 HTTP http://datanode1:50075/ 节点监控
HBase Master 16000 hbase-client-1.x.x.jar RegionServer接入
16010 HTTP http://namenode1:16010/ 集群监控
HBase RegionServer 16020 N/A 客户端接入
16030 HTTP http://datanode1:16030/ 节点监控

hbase-default.xml默认配置中常用的的配置项:

配置项 说明 默认值
hbase.tmp.dir 本地文件系统上的临时目录。将此设置更改为指向比“/tmp”更持久的位置,因为在重新启动计算机时清除了“/tmp”目录。 ${java.io.tmpdir}/hbase-${user.name}
hbase.rootdir 这个目录是region servers共享的目录。 ${hbase.tmp.dir}/hbase
hbase.cluster.distributed 群集所处的模式。对于独立模式,可能的值为false,对于分布式模式,可能的值为true。 false
hbase.zookeeper.quorum 使用逗号分隔的ZooKeeper集合中的服务器列表 localhost
zookeeper.recovery.retry.maxsleeptime 在重试 zookeeper操作之前的最大睡眠时间(以毫秒为单位) 60000
hbase.local.dir 将本地文件系统上的目录用作本地存储。 ${hbase.tmp.dir}/local/
hbase.master.port HBase Master应该绑定的端口。 16000
hbase.master.info.port HBase Master Web UI的端口。如果您不想运行UI实例,请将其设置为-1。 16010
hbase.master.info.bindAddress HBase Master Web UI的绑定地址 0.0.0.0
hbase.master.logcleaner.ttl WAL在归档({hbase.rootdir} / oldWALs)目录中保留多久,之后将由主线程清除。该值以毫秒为单位。 600000
hbase.master.procedurewalcleaner.ttl 程序WAL将在归档目录中保留多久,之后将由主线程清除。该值以毫秒为单位。 604800000
hbase.master.fileSplitTimeout 分割一个区域,在放弃尝试之前等待文件分割步骤需要多长时间。 600000
hbase.regionserver.port HBase RegionServer绑定的端口。 16020
hbase.regionserver.info.port HBase RegionServer Web UI的端口如果您不希望RegionServer UI运行,请将其设置为-1。 16030
hbase.regionserver.info.bindAddress HBase RegionServer Web UI的地址 0.0.0.0
hbase.regionserver.msginterval 从RegionServer到Master的消息间隔(以毫秒为单位)。 3000
hbase.regionserver.regionSplitLimit 限制区域数量,之后不再发生区域分割。这并不是硬性限制区域数量,而是作为区域服务商在一定限度之后停止分裂的指导方针。默认设置为1000。 1000
zookeeper.session.timeout ZooKeeper会话超时(以毫秒为单位)。它使用两种不同的方式。首先,这个值用于HBase用来连接到集合的ZK客户端。当它启动一个ZK服务器时它也被HBase使用 90000
zookeeper.znode.parent ZooKeeper中用于HBase的Root ZNode。所有配置了相对路径的HBase的ZooKeeper文件都会在这个节点下。 /hbase
zookeeper.znode.acl.parent Root ZNode用于访问控制列表。 acl
hbase.zookeeper.dns.interface ZooKeeper服务器应从中报告其IP地址的网络接口的名称。 default
hbase.zookeeper.peerport ZooKeeper同伴使用的端口进行彼此会话。 2888
hbase.zookeeper.leaderport ZooKeeper用于leader选举的端口。 3888
hbase.zookeeper.property.dataDir 来自ZooKeeper的配置zoo.cfg的属性。快照存储的目录。 ${hbase.tmp.dir}/zookeeper
hbase.zookeeper.property.clientPort 来自ZooKeeper的配置zoo.cfg的属性。客户端将连接的端口。 2181
hbase.zookeeper.property.maxClientCnxns 来自ZooKeeper的配置zoo.cfg的属性。限制由IP地址标识的单个客户端的并发连接数量 300
hbase.column.max.version 新的列族描述符将使用此值作为要保留的默认版本数。 1

参考链接

通用命令

命令 说明
status 提供HBase的状态,例如,服务器的数量。
version 提供正在使用HBase版本。
table_help 表引用命令提供帮助。
whoami 提供有关用户的信息。

数据定义

命令 说明
create 用于创建一个表。
list 用于列出HBase的所有表。
disable 用于禁用表。
is_disabled 用于验证表是否被禁用。
enable 用于启用一个表。
is_enabled 用于验证表是否已启用。
describe 用于提供了一个表的描述。
alter 用于改变一个表。
exists 用于验证表是否存在。
drop 用于从HBase中删除表。
drop_all 用于丢弃在命令中给出匹配“regex”的表。

数据操作语言

命令 说明
put 用于把指定列在指定的行中单元格的值在一个特定的表。
get 用于取行或单元格的内容。
delete 用于删除表中的单元格值。
deleteall 用于删除给定行的所有单元格。
scan 用于扫描并返回表数据。
count 用于计数并返回表中的行的数目。
truncate 用于禁用、删除和重新创建一个指定的表。清空表。

Centos7上部署单机版hbase

下载安装包

hbase

hbase官网

解压

tar -zxvf hbase-2.2.4.bin.tar.gz

配置hbase-env.sh

部署JDK,查看JAVA_HOME路径。

[root@node1 hbase]# echo $JAVA_HOME
/usr/local/bin/jdk1.8.0_112

配置conf/hbase-env.sh

...
# 配置java路径
export JAVA_HOME=/usr/local/bin/jdk1.8.0_112
# 配置是否使用自身Zookeeper
export HBASE_MANAGES_ZK=true
...

编辑conf/hbase-site.xml

<configuration>
    <property>
        <name>hbase.rootdir</name>
        <value>file:///root/hbase/rootdir</value>
        <description>The directory shared byregion servers.</description>
    </property>
    <property>
        <name>fs.defaultFS</name>
&nbsp;       <value>file:///root/hbase/dfs</value>
    </property>
    <!-- hbase的端口 -->
    <!-- <property>
        <name>hbase.zookeeper.property.clientPort</name>
        <value>2181</value>
        <description>Property from ZooKeeper'sconfig zoo.cfg. The port at which the clients will connect.
        </description>
    </property> -->
    <!--&nbsp; 超时时间 -->
    <!-- <property>
        <name>zookeeper.session.timeout</name>
        <value>120000</value>
    </property> -->
    <!--&nbsp; zookeeper 集群配置。如果是集群,则添加其它的主机地址 -->
    <!-- <property>
        <name>hbase.zookeeper.quorum</name>
        <value>localhost:2181</value>
    </property> -->
    <property>
        <name>hbase.tmp.dir</name>
        <value>/root/hbase/tmp</value>
    </property>
    <!-- <property>
        <name>hbase.cluster.distributed</name>
        <value>false</value>
    </property> -->
    <property>
        <name>hbase.zookeeper.property.dataDir</name>
        <value>/root/hbase/datadir</value>
    </property>
    <property>
        <name>zookeeper.znode.parent</name>
        <value>/hbase</value>
    </property>
</configuration>

启动

./bin/start-hbase.sh

Web UI

http://192.168.41.128:16010

进入shell命令行

./bin/hbase shell

简单测试

创建一个表,需要指明table nameColumnFamily name

hbase(main):002:0> create 'test', 'cf'
Created table test
Took 0.8251 seconds
=> Hbase::Table - test

确认

hbase(main):004:0> list 'test'
TABLE
test
1 row(s)
Took 0.0077 seconds
=> ["test"]

describe ‘test’

hbase(main):005:0> describe 'test'
Table test is ENABLED
test
COLUMN FAMILIES DESCRIPTION
{NAME => 'cf', 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', REPL
ICATION_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 => '65536'} 

1 row(s)

QUOTAS                                                                                                                                                                  0 row(s)
Took 0.2132 seconds 

写入数据

hbase(main):003:0> put 'test', 'row1', 'cf:a', 'value1'
0 row(s) in 0.0850 seconds

hbase(main):004:0> put 'test', 'row2', 'cf:b', 'value2'
0 row(s) in 0.0110 seconds

hbase(main):005:0> put 'test', 'row3', 'cf:c', 'value3'
0 row(s) in 0.0100 seconds

查看写入的数据

hbase(main):006:0> scan 'test'
ROW                                      COLUMN+CELL
 row1                                    column=cf:a, timestamp=1586504678931, value=value1
 row2                                    column=cf:b, timestamp=1586504712029, value=value2
 row3                                    column=cf:c, timestamp=1586504717104, value=value3
3 row(s) in 0.0230 seconds

获取一行数据

hbase(main):007:0> get 'test', 'row1'
COLUMN                                   CELL
 cf:a                                    timestamp=1586504678931, value=value1
1 row(s) in 0.0350 seconds

获取一个字段

hbase(main):007:0> get 'test', 'row1','cf:a'
COLUMN                                   CELL
 cf:a                                    timestamp=1586504678931, value=value1
1 row(s) in 0.0350 seconds

返回一个字段的多个版本值

默认Hbase列族最多保存一个版本的数据,可以通过下面命令修改,也可以使用HColumnDescriptor

alter 'test', NAME => 'cf', VERSIONS => 3

HBase 0.98.2开始,您可以通过在hbase-site.xml中设置hbase.column.max.version为所有新创建列保留的最大版本数指定一个全局默认值。

get 'test', 'row1', {COLUMN=>'cf:a',VERSIONS=>3}

禁用或者恢复表

hbase(main):008:0> disable 'test'
0 row(s) in 1.1820 seconds

hbase(main):009:0> enable 'test'
0 row(s) in 0.1770 seconds

添加一个列族

hbase(main):012:0> alter 'test',{NAME=>'haha'}
Updating all regions with the new schema...
1/1 regions updated.
Done.
Took 2.0149 seconds 
hbase(main):014:0> alter 'test',NAME=>'hehe'
Updating all regions with the new schema...
1/1 regions updated.
Done.
Took 1.9555 seconds 

删除一个列族

hbase(main):009:0> alter 'test',{NAME=>'haha',METHOD=>'delete'}
Updating all regions with the new schema...
1/1 regions updated.
Done.
Took 1.9296 seconds
hbase(main):013:0> alter 'test','delete'=>'haha'
Updating all regions with the new schema...
1/1 regions updated.
Done.
Took 1.8706 seconds 
# 添加一个列族,同时删除一个列族
hbase(main):011:0> alter 'test', {NAME => 'hehe'}, {NAME => 'myInfo', METHOD => 'delete'}
Updating all regions with the new schema...
1/1 regions updated.
Done.
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 3.8260 seconds

清空表

hbase(main):013:0> truncate 'test'
Truncating 'test' table (it may take a while):
 - Disabling table...
 - Truncating table...
0 row(s) in 3.6760 seconds

删除表

删除表或者修改表的配置前,需要禁用表

hbase(main):011:0> drop 'test'
0 row(s) in 0.1370 seconds

退出Shell

quit 或者 Ctrl+D

停止Hbase

./bin/stop-hbase.sh