首页 > 其他 > 详细

Hbase入门

时间:2014-06-08 18:23:30      阅读:526      评论:0      收藏:0      [点我收藏+]


Hbase简介

Hbase 全称是Hadoop DataBase ,是一种开源的,可伸缩的,高可靠,高性能,面向列的分布式存储系统。

类似于GoogleBigTable,其分布式计算采用MapReduce,通过MapReduce完成大块数据加载和全表扫描操作。文件存储系统是HDFS,通过Zookeeper来完成状态管理协同服务。不过BigTable只支持一级索引,而Hbase支持一级和二级索引。

需要指出的是:Hbase是面向列的数据库是说的Hbase以列簇的模式进行存储,而不是说Hbase本身是面向列的数据库。Hbase充分利用Lee磁盘上列存储格式的特性,它和传统的Columner databases 还是有区别的。Columner databases擅长做实时数据分析访问,而hbase在基于key的单值访问和范围扫描比较突出。

 

 

Hbase安装

 

由于Hbase是基于Hadoop Mapreduc来处理数据的,而且数据也是存储在HDFS中,所以您需要先安装hadoop,本文是单机环境。您需要参考本人博客的CDH4_hadoop2.0安装来完成hadoop安装。

 

安装完成启动之后你只需要下边命令即可完成安装:

Yum install hbase-master 

Yum install hbase-rest

启动hbase-master服务

Service hbase-master start

Service hbase-rest start

启动完成之后你需要下边命令进入hbase的控制面板

hbase shell

Hbase简单语句介绍

查看Hbase服务状态

hbase(main):001:0> status

1 servers, 0 dead, 15.0000 average load


查看Hbase版本

hbase(main):003:0> version

0.94.6-cdh4.3.0, rUnknown, Mon May 27 20:22:05 PDT 2013

 

DDL操作

操作一个信息表来演示HBase用法。创建一个student表,结构如下:

RowKey

address

info

 

City

contry

province

Age

Birthday

sex

zhangsan

Bj

Cn

Bj

23

90

man

这个表中addressinfo都是有三个列的列簇。

①创建一个表student

 

hbase(main):007:0> create ‘student‘ ,‘class‘ , ‘class_id‘ , ‘address‘ , ‘info‘

0 row(s) in 1.7210 seconds

 

=> Hbase::Table - student

②列出所有表

hbase(main):001:0> list

TABLE

student

③查看表结构

hbase(main):019:0> describe ‘student‘

DESCRIPTION                                                                    ENABLED

 {NAME => ‘student‘, FAMILIES => [{NAME => ‘address‘, DATA_BLOCK_ENCODING => ‘ true

 NONE‘, BLOOMFILTER => ‘NONE‘, REPLICATION_SCOPE => ‘0‘, VERSIONS => ‘3‘, COMP

 RESSION => ‘NONE‘, MIN_VERSIONS => ‘0‘, TTL => ‘2147483647‘, KEEP_DELETED_CEL

 LS => ‘false‘, BLOCKSIZE => ‘65536‘, IN_MEMORY => ‘false‘, ENCODE_ON_DISK =>

 ‘true‘, BLOCKCACHE => ‘true‘}, {NAME => ‘class‘, DATA_BLOCK_ENCODING => ‘NONE

 ‘, BLOOMFILTER => ‘NONE‘, REPLICATION_SCOPE => ‘0‘, VERSIONS => ‘3‘, COMPRESS

 ION => ‘NONE‘, MIN_VERSIONS => ‘0‘, TTL => ‘2147483647‘, KEEP_DELETED_CELLS =

 > ‘false‘, BLOCKSIZE => ‘65536‘, IN_MEMORY => ‘false‘, ENCODE_ON_DISK => ‘tru

 e‘, BLOCKCACHE => ‘true‘}, {NAME => ‘class_id‘, DATA_BLOCK_ENCODING => ‘NONE‘

 , BLOOMFILTER => ‘NONE‘, REPLICATION_SCOPE => ‘0‘, VERSIONS => ‘3‘, COMPRESSI

 ON => ‘NONE‘, MIN_VERSIONS => ‘0‘, TTL => ‘2147483647‘, KEEP_DELETED_CELLS =>

  ‘false‘, BLOCKSIZE => ‘65536‘, IN_MEMORY => ‘false‘, ENCODE_ON_DISK => ‘true

 ‘, BLOCKCACHE => ‘true‘}, {NAME => ‘info‘, DATA_BLOCK_ENCODING => ‘NONE‘, BLO

 OMFILTER => ‘NONE‘, REPLICATION_SCOPE => ‘0‘, VERSIONS => ‘3‘, COMPRESSION =>

  ‘NONE‘, MIN_VERSIONS => ‘0‘, TTL => ‘2147483647‘, KEEP_DELETED_CELLS => ‘fal

 se‘, BLOCKSIZE => ‘65536‘, IN_MEMORY => ‘false‘, ENCODE_ON_DISK => ‘true‘, BL

 OCKCACHE => ‘true‘}]}

1 row(s) in 0.0980 seconds

 

④删除一个列簇。删除一个列簇 需要2步,首先disable表,最后要enable表。

之前简历了3个列簇,但是classclass_id我们用不到,所以准备删除他。

命令如下:

hbase(main):041:0> disable ‘student‘

0 row(s) in 2.4160 seconds

删除:

 

hbase(main):042:0> alter ‘student‘ , {NAME=>‘class‘,METHOD=>‘delete‘}

Updating all regions with the new schema...

1/1 regions updated.

Done.

0 row(s) in 2.4710 seconds

 

启用student

hbase(main):006:0> enable ‘student‘

0 row(s) in 2.2060 seconds

⑤删除表

hbase(main):012:0> disable ‘abc‘

0 ro(s) in 2.1720 seconds

hbase(main):014:0> drop ‘abc‘

0 row(s) in 1.1720 seconds

⑥验证表是否存在

hbase(main):001:0> exists ‘abc‘

Table abc does not exist

0 row(s) in 1.0410 seconds

 

⑦判断表是否enable

hbase(main):005:0> is_enabled ‘student‘

true

0 row(s) in 0.0220 seconds

⑧判断表是否disable

hbase(main):009:0> is_disabled ‘student‘

false

0 row(s) in 0.0090 seconds

⑨增加一个列簇

hbase(main):016:0> alter ‘student‘ , {NAME=>‘test‘ ,VERSIONS=>5}

Updating all regions with the new schema...

1/1 regions updated.

Done.

0 row(s) in 1.1850 seconds



DML操作

①向表中插入几条数据

hbase(main):026:0> put ‘student‘ , ‘zhangsan‘,‘info:age‘,‘23‘

0 row(s) in 0.0870 seconds

 

hbase(main):027:0> put ‘student‘ , ‘zhangsan‘,‘info:birthday‘,‘90‘

0 row(s) in 0.0890 seconds

 

hbase(main):028:0> put ‘student‘ , ‘zhangsan‘,‘info:sex‘,‘man‘

0 row(s) in 0.0830 seconds

 

hbase(main):029:0> put ‘student‘ , ‘zhangsan‘,‘address:city‘,‘bj‘

0 row(s) in 0.0510 seconds

 

hbase(main):030:0> put ‘student‘ , ‘zhangsan‘,‘address:contry‘,‘cn‘

0 row(s) in 0.0880 seconds

 

hbase(main):031:0> put ‘student‘ , ‘zhangsan‘,‘address:provinc‘,‘bj‘

0 row(s) in 0.0100 seconds

 

②获取一条数据

获取一个ID的所有数据:

 

hbase(main):049:0> get ‘student‘,‘zhangsan‘

COLUMN                          CELL

 address:city                   timestamp=1401937717401, value=bj

 address:contry                 timestamp=1401937730454, value=cn

 address:provinc                timestamp=1401937746616, value=bj

 info:age                       timestamp=1401937660360, value=23

 info:birthday                  timestamp=1401937675146, value=90

 info:sex                       timestamp=1401937698368, value=man

6 row(s) in 0.1020 seconds

③获取一个ID,一个列簇的所有数据

hbase(main):060:0> get ‘student‘ , ‘zhangsan‘ , ‘info‘

COLUMN                          CELL

 info:age                       timestamp=1401937660360, value=23

 info:birthday                  timestamp=1401937675146, value=90

 info:sex                       timestamp=1401937698368, value=man

3 row(s) in 0.0680 seconds

④获取一个ID,一个列簇中的一个列的所有数据

hbase(main):067:0> get ‘student‘ , ‘zhangsan‘ , ‘info:age‘

COLUMN                          CELL

 info:age                       timestamp=1401937660360, value=23

1 row(s) in 0.0500 seconds

⑤更新一条记录

将张三的性别改成women

hbase(main):072:0> put ‘student‘, ‘zhangsan‘ , ‘info:sex‘ , ‘women‘

0 row(s) in 0.0810 seconds

 

hbase(main):073:0> get ‘student‘,‘zhangsan‘,‘info:sex‘

COLUMN                          CELL

 info:sex                       timestamp=1401938013194, value=women

1 row(s) in 0.0120 seconds

⑥全表扫描

hbase(main):085:0> scan ‘student‘

ROW                             COLUMN+CELL

 zhangsan                       column=address:city, timestamp=1401937717401, value=bj

 zhangsan                       column=address:contry, timestamp=1401937730454, value=cn

 zhangsan                       column=address:provinc, timestamp=1401937746616, value=bj

 zhangsan                       column=info:age, timestamp=1401937660360, value=23

 zhangsan                       column=info:birthday, timestamp=1401937675146, value=90

 zhangsan                       column=info:sex, timestamp=1401938013194, value=women

1 row(s) in 0.0820 seconds

⑦删除ID为张三的,’info:age’字段的值

 

hbase(main):095:0> delete ‘student‘ , ‘zhangsan‘ , ‘info:age‘

0 row(s) in 0.0180 seconds

 

hbase(main):096:0> get ‘student‘ , ‘zhangsan‘

COLUMN                          CELL

 address:city                   timestamp=1401937717401, value=bj

 address:contry                 timestamp=1401937730454, value=cn

 address:provinc                timestamp=1401937746616, value=bj

 info:birthday                  timestamp=1401937675146, value=90

 info:sex                       timestamp=1401938013194, value=women

5 row(s) in 0.0180 seconds

⑧查询表中有多少行

hbase(main):114:0> count ‘student‘

1 row(s) in 0.0260 seconds

⑨清空整张表

hbase(main):129:0> truncate ‘student‘

Truncating ‘student‘ table (it may take a while):

 - Disabling table...

 - Dropping table...

 - Creating table...

0 row(s) in 4.4990 seconds


Hbase Shell 脚本

您也可以将你的hbase命令写到一个文件里边,然后执行hbase shell test.sh

即可。

Hbase基本架构


①架构图

bubuko.com,布布扣

 

图中可以看出,HBase的核心有HMaster HregionServerHlogHRegion等。而Hbase外部依赖zookeeperHMaster

1)HMaster(类似于Hadoop中的NamenodeMapreduce中的jobtracker)是用来管理HRegionServer的。它负责监控集群中HRegionServer的状态信息变化。它主要功能点如下:

 1.管理HRegionServer的负载均衡,调整Region的分布。这个通过HMaster的后台进程LoadBalancer来完成。LoadBalancer会定期将Region进行移动,以使各个HRegionServer达到Load均衡。

 2.Region Split后,负责新Region的分配。

 3.HRegionServerFailOver处理,当一个HRegionServer宕机之后,Hmaster负责将它的HRegion进行转移。

 4.CataLogJanitor。它会定期清理和检查.Meta.

一个HBase集群中可以有多个HMaster。不过Zookeeper的选举制保证只有一个Hmaster运行。当一个HMaster出问题后,其他的HMaster将启动代替。

2)从结构图中可以看出,HBase客户端只与zookeeperHRegion Server打交道。并不和HMaster打交道。如果HMaster出问题,短时间内HBase是可以对外提供服务的,但是,因为HMaster掌握HRegionServer的的一些功能,例如:HRegionServerFailOver操作,所以长时间未回复正常,将影响Hbase对外提供服务的准确度。

3)Hbase2CateLog表:-Root- .Meta.-Root-表中存储了.Meta.表的位置。即.Meta.表的Region Server.Meta.表存储所有的Region位置和每个Region所包含的Rowkey范围。-Root-表存储位置记录在Zookeeper中,表.Meta.的存储位置记录在-Root-表中。

4)当客户端发起一个请求之后流程是什么样的呢?

首先客户端会连接上Zookeeper集群,获取-Root-表存放的在哪一个HRegionServer上,找到HRegionServer后就能根据-Root-表中存放的.Meta.表的位置。客户端根据.Meta.表存储的HRegion位置到相应的HRegionServer中取对应的HRegion的数据信息。经过一次查询以后,访问CataLog表的过程将被缓存起来,下次客户端就可以直接访问HRegion获取数据信息了。

5)Hbase集成了HDFS,最终数据都会通过HDFSAPI将数据持久化到HDFS中。

6)一个HBase集群拥有多个HRegionServer,(参考HDFS中的DataNode MapReduce中的TaskTracker),由一个HMaster来管理。每个HRegionServer拥有一个WALwrite Ahead Log,日志文件,用作数据恢复)和多个HRegion(可以简单理解为存储为一个表中的某些行)。一个HRegion拥有多个Store(存储一个ColumnFamily列簇)。一个Store又由一个MemStore(持有对该store的所有更改,在内存中)和0到多个StoreFilesHfile,数据存储的地方)组成。示意图如下:

bubuko.com,布布扣


HBase基本元素

1、RowKey

行标记,类似于传统数据库表中的行号。RowKeys具有不变性。除非该行被删除或者被重新插入了新的数据。Hbase中支持基于RowKey的单行查询和范围扫描。在Hbase的Auto-Sharding中,也是基于RowKey进行自动切分的。

2、Column Family

HBase中基本单元就是列。而列簇是由一个或多个列组成。使用时,一般讲性质差不多的放在一个列簇。因为Hbase是面向列存储的,也就是说一个列簇的所有列是存储在一起的。即上图中一个Store存储一个列簇。

注意一个表中被限定不能超过10个列簇。

3TimeStamp

HBase支持时间戳的概念。即允许一个Cell存储多个版本值。版本之间通过时间戳来划分。就是说某一列的某一行存在多个值。一般默认是3,最近的版本存在最上面。HBase中有一个TTL(Time to Live)的配置,这是基于列簇维度的,一旦过期,列簇就会自动删除所有行。

4、HRegion Server

 

HRegionServer是负责服务和管理Region的。类似于我们所说的主从服务器,HMaster就是主服务器,HRegionServer就是从服务器。用户执行CRUD的时候,需要HRegionServer来定位到HRegin来操作。

5WAL

WAL的全名是Write  Ahead Log,类似于MysqlBinary LogWAL记录了HRegionServer上的所有的数据变更。一旦这个HRegionServer宕机,导致数据丢失后,WAL就起作用了。平时WAL是不起作用的,只是为了不可预知的错误预备的。

WAL的实现类是HLog。因为在一个HRegionServer中只有一个WAL所以对于一个HRegionServer的所有的HRegion来说WAL是全局的,共享的。当HRegion的实例创建的时候,在HRegionServer实例中的HLog就会作为HRegion的构造函数的参数传递给Hregion。当HRegion接收到一个变更的时候,HRegion就可以直接通过HLog将变更日志追加到共享的WAL中。当然基于性能考虑,HBase还提供了一个setWriteToWALfalse)方法。一旦用户调用该方法,变更日志将不在记录到WAl中。

HLog还有一个重要的特性就是:跟踪变更。在HLog中有一个原子类型的变量,HLog会读取StoreFiles中最大的sequence numberHLog中每一条变更日志都有一个number号,因为对于一个HRegionServer中所有的HRegion都是共享HLog的,所以变更日志会顺序写入WALStoreFile中也持有该number),并存放到变量中。这样HLog就知道已经存储到哪个位置了。

WAL还有2个比较重要的类,一个是LogSyncer,另外一个是LogRoller

在创建表时,有一个参数设置:Deferred Log Flush,默认是false,表示log一旦更新就立即同步到filesystem。如果设置为true,则HRegionServer会缓存那些变更,并由后台任务LogSyncer定时将变更信息同步到filesystem
  
2WAL是有容量限制的,LogRoller是一个后台线程,会定时滚动logfile,用户可以设定这个间隔时间(hbase.regionserver.logroll.period,默认是一小时)。当检查到某个logfile文件中的所有sequence number均小于那个最大的sequence number时,就会将此logfile移到.oldLog目录。
  
如下是WAL的文件结构,目前WAL采用的是HadoopSequenceFile,其存储记录格式是key/value键值对的形式。其中Key保存了HLogkey的实例,HLogKey包含数据所属的表名及RegionNametimeStampsequenceNumber等信息。Value保存了WALEdit实例,WALEdit包含客户端每一次发来的变更信息。

bubuko.com,布布扣



6、Region

HBase中实现可扩展性和负载均衡的基本单元式RegionRegion存储着连续的RowKey数据。刚开始一个表只有一个Region,随着数据的增多,达到某个阀值时就会根据RowKey自动一分为二,每个Region存储着【StartKeyendKey】。随着表的继续增大,那么当前的Region还会继续分裂,每个Region只会由一个HRegionServer服务。这就是所谓的Hbase的AutoSharding特性。当然,Region除了会spilt外,也可能进行合并以减少Region数目(这就是Hbase的compaction特性)

7、Store

 

Store是核心存储单元。在一个HRegion中可能存在多个ColumnFamily,那么Store中被指定只能存储一个ColumnFamily。不同的ColumnFamily存储在不同的Store中(所以在创建ColumnFamily时,尽量将经常需要一起访问的列放到一个ColumnFamily中,这样可以减少访问Store的数目)。一个Store由一个MemStore0至多个StoreFile组成

8、MemStore

Hbase在将数据写入StoreFile之前,会先将数据写入MemStore中。MemStore是一个有序的内存缓冲器。当MemStore中数据达到阀值(Flush Size)的时候,HRegionServer就将执行Flush操作,将MemStore中的数据flushStoreFile中。

MemStore正在向StoreFileflush数据的时候,MemStore还是可以向外提供读写数据服务的。这个事通过MesStore的滚动机制实现的,通过滚动MemStore,新的空的块就可以接受变更,而老的满的块就会执行flush操作。

9、StoreFile/HFile

 

StoreFileHFile的实现,对HFile做了一层包装。HFile是数据真正存储的地方。HFile是基于BigTableSSTable FileHadoopTFileHFile是以keyvalue的格式存储数据的。(Hbase之前使用过HadoopMapFile,因为其性能上相当糟糕而放弃。)下图是HFile中版本1的格式,版本2稍有改变(详见Hbase wiki):

bubuko.com,布布扣

从上图中看出,HFile是由多个数据块组成。大部分数据块是不定长的,唯一固定长度的只有两个数据块:File InfoTrailerDataIndexMetaIndex分别记录了Data块和Meta块的起始位置。每个data块由一些kevalue键值对和Magic header组成。Data块的大小可以再创建表时通过HColumnDescriptor设定。Magic记录了一串随机的数字,防治数据丢失和损坏。
  
如果用户想绕过Hbase直接访问HFile时,比如检查HFile的健康状态,dump HFile的内容,可以通过HFile.main()方法完成。
  
如下图是KeyValue的格式:



bubuko.com,布布扣


  
KeyValue是一个数组,对byte数组做了一层包装。Key LengthValue Length都是固定长度的数值。Key包含的内容有行RowKey的长度及值,列族的长度及值,列,时间戳,key类型(Put, Delete, DeleteColumn, DeleteFamily)。
  
从上图可以看出,每一个keyValue只包含一列,即使对于同一行的不同列数据,会创建多个KeyValue实例。此外KeyValue不能被Split,即使此KeyValue值超过Block的大小,比如:
  
Block大小为16Kb,而KeyValue值有8Mb,那么KeyValue会通过相连的多个Block进行存储。  

 

 

总结

 

 

以上对Hbase的基本元素做了一个大体的介绍。下图是Hbase的存储结构图。记录了客户端发起变更或者新增操作时,Hbase内部的存储流程。

bubuko.com,布布扣


下面分析下整个存储流程

1)当客户端提交变更操作的时候,首先客户端连接Zookeeper找到-Root-表,通过-Root-提供的.Meta.表的位置找到.Meta.表,根据.Meta.中信息找到对应的Region所在的HRegionServer。数据变更信息会首先通过HRegionServer写入一个Commit log,也就是WAL。写入WAL成功之后,数据变更信息会储存到MEMStore中,当MemStore达到阀值(默认64MB)的时候,MemStore会执行flush操作,将数据持久化到HFile中。Flush过程中通过MemStore的滚动机制继续对用户提供读写服务。随着Flush操作不断进行,HFile会越来越多。当HFile超过设定数量的时候,HbaseHouseKeeping机制通过Compaction特性将小的HFile合并成一个更大的HFile文件。Compaction的过程中,会进行版本的合并以及数据的删除。由于storeFiles是不变的,用户执行删除操作时,并不能简单地通过删除其键值对来删除数据内容。Hbase提供了一个delete marker机制(也称为tombstone marker),会告诉HRegionServer那个指定的key已经被删除了。这样其它用户检索这个key的内容时,因为已经被标记为删除,所以也不会检索出来。在进行Compaction操作中就会丢弃这些已经打标的记录。经过多次Compaction后,HFile文件会越来越大,当达到设定的值时,会触发Split操作。将当前的Region根据RowKey对等切分成两个子Region,当期的那个Region被废弃,两个子Region会被分配到其他HRegionServer上。所以刚开始时一个表只有一个Region,随着不断的split,会产生越来越多的Region,通过HMaster的LoadBalancer调整,Region会均匀遍布到所有的HRegionServer中。

2HLog满时,HRegionServer就会启动LogRoller,通过执行rollWriter方法将那些所有sequence number均小于最大的那个sequence numberlogfile移动到.oldLog目录中等待被删除。如果用户设置了Deferred Log FlushtrueHRegionServer会缓存有关此表的所有变更,并通过LogSyncer调用sync()方法定时将变更信息同步到filesystem。默认为false的话,一旦有变更就会立刻同步到filesystem

3在一个HRegionServer中只有一个WAL,所有Region共享此WALHLog会根据Region提交变更信息的先后顺序依次顺序写入WAL中。如果用户设置了setWriteToWAL(false)方法,则有关此表的所有Region变更日志都不会写入WAL中。这也是上图中Region将变更日志写入WAL的那个垂直向下的箭头为什么是虚线的原因。

 





Hbase入门,布布扣,bubuko.com

Hbase入门

原文:http://blog.csdn.net/qzlzwhx/article/details/28638897

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!