扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
Hbase 安装,架构,使用
安装 hbase :
下载安装包:
hbase-1.0.0-bin.tar.gz
mdkir /data/hbase
mdkir /data/hbase/tmp
mkdir /data/hbase/
hadoop dfs -mkdir /user/hadoop/rongxin/hbase
2.解压
[hadoop@master hbase]$ tar -zxvf hbase-1.0.0-bin.tar.gz
3. 进入 hbase 的 lib 目录,替换 hadoop jar 包的版本
修改配置文件
hbase-env.sh
hbase-site.xml
[hadoop@master hbase]$ vim hbase-1.0.0/conf/regionservers
slave1
slave2
vim /etc/profile
export HBASE_HOME=/data/hbase/hbase-1.0.0
export PATH=$PATH:$HBASE_HOME/bin
source /etc/profile
启动 hbase:
[hadoop@master hbase]$ start-hbase.sh
通过 jps 检查是否已经启动:
[hadoop@master hbase]$ jps
32211 HMaster
[hadoop@slave1 lib]$ jps
20584 HRegionServer
[hadoop@slave2 lib]$ jps
2698 HRegionServer
通过 web 检查是否已经启动了 hbase:
http://master:16030/master-status
H He base 的 常用命令行工具:
名称 命令表达式
创建表 create '表名称', '列名称 1','列名称 2','列名称 N'
添加记录 put '表名称', '行名称', '列名称:', '值'
查看记录 get '表名称', '行名称'
查看表中的记录总数 count '表名称'
删除记录 delete '表名' ,'行名称' , '列名称'
删除一张表
先要屏蔽该表,才能对该表进行删除,第一步 disable '表名称' 第
二步 drop '表名称'
查看所有记录 scan "表名称"
查看某个表某个列中所
有数据
scan "表名称" , ['列名称:']
更新记录 就是重写一遍进行覆盖
下面是一些常见命令的说明,在 hbaseshell 中输入 help 的帮助信息,在本文中,我们先介
绍前 3 个,后面 2 个,将在下一篇博文中介绍。
COMMAND GROUPS:
Group name: general
Commands: status, version
Group name: ddl
Commands: alter, create, describe, disable,drop, enable, exists, is_disabled, is_enabled, list
Group name: dml
Commands: count, delete, deleteall, get,get_counter, incr, put, scan, truncate
Group name: tools
Commands: assign, balance_switch, balancer,close_region, compact, flush, major_compact, move,
split, unassign, zk_dump
Group name: replication
Commands: add_peer, disable_peer,enable_peer, remove_peer, start_replication, stop_replication
一、一般操作
1.查询服务器状态
hbase(main):024:0>status
3 servers, 0 dead,1.0000 average load
2.查询 hive 版本
hbase(main):025:0>version
0.90.4, r1150278,Sun Jul 24 15:53:29 PDT 2011
二、L DDL 操作
1.创建一个表
hbase(main):011:0>create 'member','member_id','address','info'
0 row(s) in 1.2210seconds
2.获得表的描述
hbase(main):012:0>list
TABLE
member
1 row(s) in 0.0160seconds
hbase(main):006:0>describe 'member'
DESCRIPTION ENABLED
{NAME => 'member', FAMILIES => [{NAME=> 'address', BLOOMFILTER => 'NONE',
REPLICATION_SCOPE => '0', true
VERSIONS => '3', COMPRESSION => 'NONE',TTL => '2147483647', BLOCKSIZE =>
'65536', IN_MEMORY => 'fa
lse', BLOCKCACHE => 'true'}, {NAME =>'info', BLOOMFILTER => 'NONE',
REPLICATION_SCOPE => '0', VERSI
ONS => '3', COMPRESSION => 'NONE', TTL=> '2147483647', BLOCKSIZE => '65536',
IN_MEMORY => 'false',
BLOCKCACHE =>
'true'}]}
1 row(s) in 0.0230seconds
3.删除一个列族,alter,disable,enable
我们之前建了 3 个列族,但是发现 member_id 这个列族是多余的,因为他就是主键,所以
我们要将其删除。
hbase(main):003:0>alter 'member',{NAME=>'member_id',METHOD=>'delete'}
ERROR: Table memberis enabled. Disable it first before altering.
报错,删除列族的时候必须先将表给 disable 掉。
hbase(main):004:0>disable 'member'
0 row(s) in 2.0390seconds
hbase(main):005:0>alter'member',{NAME=>'member_id',METHOD=>'delete'}
0 row(s) in 0.0560seconds
hbase(main):006:0>describe 'member'
DESCRIPTION ENABLED
{NAME => 'member', FAMILIES => [{NAME=> 'address', BLOOMFILTER => 'NONE',
REPLICATION_SCOPE => '0',false
VERSIONS => '3', COMPRESSION => 'NONE',TTL => '2147483647', BLOCKSIZE =>
'65536', IN_MEMORY => 'fa
lse', BLOCKCACHE => 'true'}, {NAME =>'info', BLOOMFILTER => 'NONE',
REPLICATION_SCOPE => '0', VERSI
ONS => '3', COMPRESSION => 'NONE', TTL=> '2147483647', BLOCKSIZE => '65536',
IN_MEMORY => 'false',
BLOCKCACHE =>
'true'}]}
1 row(s) in 0.0230seconds
该列族已经删除,我们继续将表 enable
hbase(main):008:0> enable 'member'
0 row(s) in 2.0420seconds
4.列出所有的表
hbase(main):028:0>list
TABLE
member
temp_table
2 row(s) in 0.0150seconds
5.drop 一个表
hbase(main):029:0>disable 'temp_table'
0 row(s) in 2.0590seconds
hbase(main):030:0>drop 'temp_table'
0 row(s) in 1.1070seconds
6.查询表是否存在
hbase(main):021:0>exists 'member'
Table member
doesexist
0 row(s) in 0.1610seconds
7.判断表是否 enable
hbase(main):034:0>is_enabled 'member'
true
0 row(s) in 0.0110seconds
8.判断表是否 disable
hbase(main):032:0>is_disabled 'member'
false
0 row(s) in 0.0110seconds
三、 DML 操作
1.插入几条记录
put'member','scutshuxue','info:age','24'
put'member','scutshuxue','info:birthday','1987-06-17'
put'member','scutshuxue','info:company','alibaba'
put'member','scutshuxue','address:contry','china'
put'member','scutshuxue','address:province','zhejiang'
put'member','scutshuxue','address:city','hangzhou'
put'member','xiaofeng','info:birthday','1987-4-17'
put'member','xiaofeng','info:favorite','movie'
put'member','xiaofeng','info:company','alibaba'
put'member','xiaofeng','address:contry','china'
put'member','xiaofeng','address:province','guangdong'
put'member','xiaofeng','address:city','jieyang'
put'member','xiaofeng','address:town','xianqiao'
2.获取一条数据
获取一个 id 的所有数据
hbase(main):001:0>get 'member','scutshuxue'
COLUMN CELL
address:city timestamp=1321586240244,
value=hangzhou
address:contry timestamp=1321586239126,
value=china
address:province timestamp=1321586239197,
value=zhejiang
info:age timestamp=1321586238965,
value=24
info:birthday timestamp=1321586239015, value=1987-06-
17
info:company timestamp=1321586239071,
value=alibaba
6 row(s) in 0.4720seconds
获取一个 id,一个列族的所有数据
hbase(main):002:0>get 'member','scutshuxue','info'
COLUMN CELL
info:age timestamp=1321586238965,
value=24
info:birthday timestamp=1321586239015, value=1987-06-
17
info:company timestamp=1321586239071,
value=alibaba
3 row(s) in 0.0210seconds
获取一个 id,一个列族中一个列的所有数据
hbase(main):002:0>get 'member','scutshuxue','info:age'
COLUMN CELL
info:age timestamp=1321586238965,
value=24
1 row(s) in 0.0320seconds
6.更新一条记录
将 scutshuxue 的年龄改成 99
hbase(main):004:0>put 'member','scutshuxue','info:age' ,'99'
0 row(s) in 0.0210seconds
hbase(main):005:0>get 'member','scutshuxue','info:age'
COLUMN CELL
info:age timestamp=1321586571843,
value=99
1 row(s) in 0.0180seconds
3.通过 timestamp 来获取两个版本的数据
hbase(main):010:0>get
'member','scutshuxue',{COLUMN=>'info:age',TIMESTAMP=>1321586238965}
COLUMN CELL
info:age timestamp=1321586238965,
value=24
1 row(s) in 0.0140seconds
hbase(main):011:0>get
'member','scutshuxue',{COLUMN=>'info:age',TIMESTAMP=>1321586571843}
COLUMN CELL
info:age timestamp=1321586571843,
value=99
1 row(s) in 0.0180seconds
4.全表扫描:
hbase(main):013:0>scan 'member'
ROW COLUMN+CELL
scutshuxue column=address:city, timestamp=1321586240244,
value=hangzhou
scutshuxue column=address:contry, timestamp=1321586239126,
value=china
scutshuxue column=address:province, timestamp=1321586239197,
value=zhejiang
scutshuxue column=info:age,timestamp=1321586571843,
value=99
scutshuxue column=info:birthday, timestamp=1321586239015, value=1987-06-
17
scutshuxue column=info:company, timestamp=1321586239071,
value=alibaba
temp column=info:age, timestamp=1321589609775,
value=59
xiaofeng column=address:city, timestamp=1321586248400,
value=jieyang
xiaofeng column=address:contry, timestamp=1321586248316,
value=china
xiaofeng column=address:province, timestamp=1321586248355,
value=guangdong
xiaofeng column=address:town, timestamp=1321586249564,
value=xianqiao
xiaofeng column=info:birthday, timestamp=1321586248202, value=1987-4-
17
xiaofeng column=info:company, timestamp=1321586248277,
value=alibaba
xiaofeng column=info:favorite, timestamp=1321586248241,
value=movie
3 row(s) in 0.0570seconds
5.删除 id 为 temp 的值的‘info:age’字段
hbase(main):016:0>delete 'member','temp','info:age'
0 row(s) in 0.0150seconds
hbase(main):018:0>get 'member','temp'
COLUMN CELL
0 row(s) in 0.0150seconds
6.删除整行
hbase(main):001:0>deleteall 'member','xiaofeng'
0 row(s) in 0.3990seconds
7.查询表中有多少行:
hbase(main):019:0>count 'member'
2 row(s) in 0.0160seconds
8.给‘xiaofeng’这个 id 增加'info:age'字段,并使用 counter 实现递增
hbase(main):057:0*incr 'member','xiaofeng','info:age'
COUNTER VALUE = 1
hbase(main):058:0>get 'member','xiaofeng','info:age'
COLUMN CELL
info:age timestamp=1321590997648,
value=\x00\x00\x00\x00\x00\x00\x00\x01
1 row(s) in 0.0140seconds
hbase(main):059:0>incr 'member','xiaofeng','info:age'
COUNTER VALUE = 2
hbase(main):060:0>get 'member','xiaofeng','info:age'
COLUMN CELL
info:age timestamp=1321591025110,
value=\x00\x00\x00\x00\x00\x00\x00\x02
1 row(s) in 0.0160seconds
获取当前 count 的值
hbase(main):069:0>get_counter 'member','xiaofeng','info:age'
COUNTER VALUE = 2
9.将整张表清空:
hbase(main):035:0>truncate 'member'
Truncating 'member'table (it may take a while):
- Disabling table...
- Dropping table...
- Creating table...
0 row(s) in 4.3430seconds
可以看出,hbase 是先将掉 disable 掉,然后 drop 掉后重建表来实现 truncate 的功能的。
e Hbase 的架构:
HBase 访问接口
1. Native Java API,最常规和高效的访问方式,适合 Hadoop MapReduce Job 并行批处理
HBase 表数据
2. HBase Shell,HBase 的命令行工具,最简单的接口,适合 HBase 管理使用
3. Thrift Gateway,利用 Thrift 序列化技术,支持 C++,PHP,Python 等多种语言,适
合其他异构系统在线访问 HBase 表数据
4. REST Gateway,支持 REST 风格的 Http API 访问 HBase, 解除了语言限制
5. Pig,可以使用 Pig Latin 流式编程语言来操作 HBase 中的数据,和 Hive 类似,本质最
终也是编译成 MapReduce Job 来处理 HBase 表数据,适合做数据统计
6. Hive,当前 Hive 的 Release 版本尚没有加入对 HBase 的支持,但在下一个版本 Hive
0.7.0 中将会支持 HBase,可以使用类似 SQL 语言来访问 HBase
HBase 数据模型
Table & Column Family
Row
Key
Timestamp
Column Family
URI Parser
r1
t3 url=http://www.taobao.com title=天天特价
t2 host=taobao.com
t1
r2 t5 url=http://www.alibaba.com content=每天…
t4 host=alibaba.com
? Row Key: 行键,Table 的主键,Table 中的记录按照 Row Key 排序
? Timestamp: 时间戳,每次数据操作对应的时间戳,可以看作是数据的 version number
? Column Family:列簇,Table 在水平方向有一个或者多个 Column Family 组成,一个
Column Family 中可以由任意多个 Column 组成,即 Column Family 支持动态扩展,无需预先
定义 Column 的数量以及类型,所有 Column 均以二进制格式存储,用户需要自行进行类型
转换。
Table & Region
当 Table 随着记录数不断增加而变大后,会逐渐分裂成多份 splits,成为 regions,一个
region 由[startkey,endkey)表示,不同的 region 会被 Master 分配给相应的 RegionServer 进行管
理:
-ROOT- && .META. Table
HBase 中有两张特殊的 Table,-ROOT-和.META.
? .META.:记录了用户表的 Region 信息,.META.可以有多个 regoin
? -ROOT-:记录了.META.表的 Region 信息,-ROOT-只有一个 region
? Zookeeper 中记录了-ROOT-表的 location
Client 访问用户数据之前需要首先访问 zookeeper,然后访问-ROOT-表,接着访问.META.
表,最后才能找到用户数据的位置去访问,中间需要多次网络操作,不过 client 端会做
cache 缓存。
MapReduce on HBase
在 HBase 系统上运行批处理运算,最方便和实用的模型依然是 MapReduce,如下图:
HBase Table 和 Region 的关系,比较类似 HDFS File 和 Block 的关系,HBase 提供了配套的
TableInputFormat 和 TableOutputFormat API,可以方便的将 HBase Table 作为 Hadoop
MapReduce 的 Source 和 Sink,对于 MapReduce Job 应用开发人员来说,基本不需要关注
HBase 系统自身的细节。
HBase 系统架构
Client
HBase Client 使用 HBase 的 RPC 机制与 HMaster 和 HRegionServer 进行通信,对于管理类操
作,Client 与 HMaster 进行 RPC;对于数据读写类操作,Client 与 HRegionServer 进行 RPC
Zookeeper
Zookeeper Quorum 中除了存储了-ROOT-表的地址和 HMaster 的地址,HRegionServer 也会
把自己以 Ephemeral 方式注册到 Zookeeper 中,使得 HMaster 可以随时感知到各个
HRegionServer 的健康状态。此外,Zookeeper 也避免了 HMaster 的单点问题,见下文描述
HMaster
HMaster 没有单点问题,HBase 中可以启动多个 HMaster,通过 Zookeeper 的 Master Election
机制保证总有一个 Master 运行,HMaster 在功能上主要负责 Table 和 Region 的管理工作:
1. 管理用户对 Table 的增、删、改、查操作
2. 管理 HRegionServer 的负载均衡,调整 Region 分布
3. 在 Region Split 后,负责新 Region 的分配
4. 在 HRegionServer 停机后,负责失效 HRegionServer 上的 Regions 迁移
HRegionServer
HRegionServer 主要负责响应用户 I/O 请求,向 HDFS 文件系统中读写数据,是 HBase 中最
核心的模块。
HRegionServer 内部管理了一系列 HRegion 对象,每个 HRegion 对应了 Table 中的一个
Region,HRegion 中由多个 HStore 组成。每个 HStore 对应了 Table 中的一个 Column Family
的存储,可以看出每个 Column Family 其实就是一个集中的存储单元,因此最好将具备共同
IO 特性的 column 放在一个 Column Family 中,这样最高效。
HStore 存储是 HBase 存储的核心了,其中由两部分组成,一部分是 MemStore,一部分是
StoreFiles。MemStore 是 Sorted Memory Buffer,用户写入的数据首先会放入 MemStore,当
MemStore 满了以后会 Flush 成一个 StoreFile(底层实现是 HFile),当 StoreFile 文件数量增
长到一定阈值,会触发 Compact 合并操作,将多个 StoreFiles 合并成一个 StoreFile,合并过
程中会进行版本合并和数据删除,因此可以看出 HBase 其实只有增加数据,所有的更新和
删除操作都是在后续的 compact 过程中进行的,这使得用户的写操作只要进入内存中就可
以立即返回,保证了 HBase I/O 的高性能。当 StoreFiles Compact 后,会逐步形成越来越大
的 StoreFile,当单个 StoreFile 大小超过一定阈值后,会触发 Split 操作,同时把当前 Region
Split 成 2 个 Region,父 Region 会下线,新 Split 出的 2 个孩子 Region 会被 HMaster 分配到相
应的 HRegionServer 上,使得原先 1 个 Region 的压力得以分流到 2 个 Region 上。下图描述
了 Compaction 和 Split 的过程:
在理解了上述 HStore 的基本原理后,还必须了解一下 HLog 的功能,因为上述的 HStore 在
系统正常工作的前提下是没有问题的,但是在分布式系统环境中,无法避免系统出错或者
宕机,因此一旦 HRegionServer 意外退出,MemStore 中的内存数据将会丢失,这就需要引
入 HLog 了。每个 HRegionServer 中都有一个 HLog 对象,HLog 是一个实现 Write Ahead Log
的类,在每次用户操作写入 MemStore 的同时,也会写一份数据到 HLog 文件中(HLog 文
件格式见后续),HLog 文件定期会滚动出新的,并删除旧的文件(已持久化到 StoreFile 中
的数据)。当 HRegionServer 意外终止后,HMaster 会通过 Zookeeper 感知到,HMaster 首先
会处理遗留的 HLog 文件,将其中不同 Region 的 Log 数据进行拆分,分别放到相应 region
的目录下,然后再将失效的 region 重新分配,领取 到这些 region 的 HRegionServer 在 Load
Region 的过程中,会发现有历史 HLog 需要处理,因此会 Replay HLog 中的数据到
MemStore 中,然后 flush 到 StoreFiles,完成数据恢复。
HBase 存储格式
HBase 中的所有数据文件都存储在 Hadoop HDFS 文件系统上,主要包括上述提出的两种文
件类型:
1. HFile, HBase 中 KeyValue 数据的存储格式,HFile 是 Hadoop 的二进制格式文件,
实际上 StoreFile 就是对 HFile 做了轻量级包装,即 StoreFile 底层就是 HFile
2. HLog File,HBase 中 WAL(Write Ahead Log) 的存储格式,物理上是 Hadoop 的
Sequence File
HFile
下图是 HFile 的存储格式:
首先 HFile 文件是不定长的,长度固定的只有其中的两块:Trailer 和 FileInfo。正如图中所
示的,Trailer 中有指针指向其他数据块的起始点。File Info 中记录了文件的一些 Meta 信
息,例如:AVG_KEY_LEN, AVG_VALUE_LEN, LAST_KEY, COMPARATOR,
MAX_SEQ_ID_KEY 等。Data Index 和 Meta Index 块记录了每个 Data 块和 Meta 块的起始
点。
Data Block 是 HBase I/O 的基本单元,为了提高效率,HRegionServer 中有基于 LRU 的
Block Cache 机制。每个 Data 块的大小可以在创建一个 Table 的时候通过参数指定,大号的
Block 有利于顺序 Scan,小号 Block 利于随机查询。每个 Data 块除了开头的 Magic 以外就是
一个个 KeyValue 对拼接而成, Magic 内容就是一些随机数字,目的是防止数据损坏。后面会
详细介绍每个 KeyValue 对的内部构造。
HFile 里面的每个 KeyValue 对就是一个简单的 byte 数组。但是这个 byte 数组里面包含了很
多项,并且有固定的结构。我们来看看里面的具体结构:
开始是两个固定长度的数值,分别表示 Key 的长度和 Value 的长度。紧接着是 Key,开始
是固定长度的数值,表示 RowKey 的长度,紧接着是 RowKey,然后是固定长度的数值,表
示 Family 的长度,然后是 Family,接着是 Qualifier,然后是两个固定长度的数值,表示
Time Stamp 和 Key Type(Put/Delete)。Value 部分没有这么复杂的结构,就是纯粹的二进
制数据了。
HLogFile
上图中示意了 HLog 文件的结构,其实 HLog 文件就是一个普通的 Hadoop Sequence File,
Sequence File 的 Key 是 HLogKey 对象,HLogKey 中记录了写入数据的归属信息,除了 table
和 region 名字外,同时还包括 sequence number 和 timestamp,timestamp 是“写入时间”,
sequence number 的起始值为 0,或者是最近一次存入文件系统中 sequence number。
站在用户的角度思考问题,与客户深入沟通,找到双桥网站设计与双桥网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站建设、网站设计、企业官网、英文网站、手机端网站、网站推广、空间域名、雅安服务器托管、企业邮箱。业务覆盖双桥地区。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流