>。
如果用传统的概念来将BigTable作解释,那么BigTable可以看作一个DBSchema,每一个Row就是一个表,Rowkey就是表名,这个表根据列的不同可以划分为多个版本,同时每个版本的操作都会有时间戳关联到操作的行。
每一个行可以多个family,每一个family可以包含无数个Column,每一个Column都可以有一个不同于其他列的时间戳。
在通用数据库中当表创建时我们就已经定义了列,如果修改表结构的话会非常困难(比如:
添加一列)。
在HBase中我们可以很轻松地添加一个列族或列。
2.2物理数据模型
虽然从逻辑模型来看每个表格是由很多行组成,但是在物理存储上面,它是按照列来保存的,这点在数据设计和程序开发的时候必须牢记。
上面的逻辑模型在物理存储的时候应该表现成下面那样子:
RowKey
TimeStamp
Column "contents:
"
"n.www"
t6
"..."
t5
"..."
t3
"..."
RowKey
TimeStamp
Column "anchor:
"
"n.www"
t9
"anchor:
"
"CNN"
t8
"anchor:
my.look.ca"
"CNN.com"
RowKey
TimeStamp
Column "mime:
"
"n.www"
t6
"text/html"
需要注意的是在概念视图上面有些列是空白的,这样的列实际上并不会被存储,当请求这些空白的单元格的时候,会返回null值。
如果在查询的时候不提供时间戳,那么会返回距离现在最近的那一个版本的数据。
因为在存储的时候,数据会按照时间戳排序。
物理数据模型其实就是将逻辑模型中的一个Row分割成为根据Columnfamily存储的物理模型。
对于BigTable的数据模型操作的时候,会锁定Row,并保证Row的原子操作。
2.3HBase架构图
图2-1Hbase架构图
2.4Hbase与Hypertabler的区别
无疑,这两个项目的出发点都是解答同一问题的——开源的Bigtable。
Hypertable是C++语言编写的,而HBase是用Java语言编写的。
HBase参与开放开发的时间更长、提交者及外部捐助者的数量更多。
与Hypertable比较起来,选择Java使我们可以和Hadoop集成得更加紧密——当我们使用了HDFS,就不需要另启动一个进程担任Java和C++之间的代理了,也不需要跨过JNI“分水岭(greatdivide)”。
而且,因为我们使用Java,我们就有了后援,因为相当一部分核心类型和功能已经由Hadoop核心项目的“SmartFolks”社区编写和测试过了。
Hypertable项目非常关注“性能”而且强烈感觉只有C++能解决这一问题。
有趣的是,据我所知,Hadoop开发的大部分工作是由Yahoo的一个团队做的,他们过去由于与Hypertable所说一样的原因而使用C++,据说现在已经回到了JavaMapReduce框架。
很明显,Hadoop团队已经克服了这一问题;在Java存在性能问题的地方,他们采取了适当校正,而性能上并无大碍的部分,继续以前的方式。
例如,Hadoop/HBase使用本地类库来进行压缩,因为Java在这方面性能非常差。
围绕性能问题HBase确实需要做大量工作——上面提到的核心类型及RPC传输都需要彻底改造以更适合HBase使用模式——但是现在我们把精力放在别处。
我们将追随Hadoop项目所采取的路线,首先把精力集中在健壮性、扩展性、正确性以及社区建立上。
之后,我们再提高速度。
当时机成熟时,我们将会在速度方面把HBase和Hypertable进行全方位比较。
和体育比赛不同, Hypertable的伙计们是我们的同伴。
我们在公平规则基础上进行对话并互相帮助。
三、HBase的试用
3.1Hbase的安装环境配置
1)需要环境
PC-1 SuseLinux9 10.192.1.1
PC-2 SuseLinux9 10.192.1.2
PC-3 SuseLinux9 10.192.1.3
PC-4 SuseLinux9 10.192.1.4
其中,PC-1做namenode节点,PC-2、PC-3和PC-4做datanode节点。
并且已经安装成功Hadoop-0.20.1及以上版本。
2)需要安装包
zookeeper-3.2.1.tar.gz(stable版本)
hbase-0.20.1.tar.gz(stable版本)
3)安装步骤
安装和配置ZooKeeper
HBase从0.20.0开始,需要首先安装ZooKeeper。
从apache上下载zookeeper-3.2.1.tar.gz(Stable版本),解压到/home/hdfs/目录下。
(1)在namenode节点新建zookeeper目录,在该目录下新建myid文件。
(2)在zookeeper-3.2.1/conf目录下,拷贝zoo_sample.cfg为zoo.cfg。
在zoo.cfg中将dataDir改为/home/hdfs/zookeeper,在文件末位添加所有的主机:
server.1=10.192.1.1:
2888:
3888
server.2=10.192.1.2:
2888:
3888
server.3=10.192.1.3:
2888:
3888
server.4=10.192.1.4:
2888:
3888
server.5=10.192.1.5:
2888:
3888
server.6=10.192.1.62888:
3888
(3)用scp命令将namenode节点的的/home/hdfs/zookeeper-3.2.1和/home/hdfs/zookeeper拷贝到其余所有主机的/home/hdfs目录下。
(4)参照zoo.cfg中的配置,在各主机myid文件中写入各自的编号。
如:
10.192.1.1写入1,10.192.1.2写入2
(5)在所有节点上执行bin/zkServer.shstart,分别启动。
执行bin/zkCli.sh-serverxxx.xxx.xxx.xxx:
2181,检查指定服务器是否成功启动。
3.2安装和配置HBase
下载HBase0.20.1版本,解压到namenode节点的/home/hdfs目录下。
(1)系统所有配置项的默认设置在hbase-default.xml中查看,如果需要修改配置项的值,在hbase-site.xml中添加配置项。
在分布式模式下安装HBase,需要添加的最基本的配置项如下:
hbase.rootdir
hdfs:
//namenode.hdfs:
54310/hbase
Thedirectorysharedbyregionservers.
hbase.cluster.distributed
true
Themodetheclusterwillbein.Possiblevaluesare
false:
standaloneandpseudo-distributedsetupswithmanagedZookeeper
true:
fully-distributedwithunmanagedZookeeperQuorum
(seehbase-env.sh)
(2)在conf/hbase-env.sh中修改添加配置项:
exportJAVA_HOME=/usr/java/jdk1.6.0_16
exportHBASE_MANAGES_ZK=false
exportHBASE_CLASSPATH=/home/hdfs/hadoop-0.20.1/conf
并把~/hadoop-0.20.1/conf/hdfs-site.xml拷贝至~/hbase-3.2.1/conf/目录下。
(3)将ZooKeeper的配置文件zoo.cfg添加到HBase所有主机的CLASSPATH中。
(4)在conf/regionservers中添加hadoop-0.20.1/conf/slaves中所有的datanode节点。
3.3启动和接口说明
Hadoop、ZooKeeper和HBase之间应该按照顺序启动和关闭:
启动Hadoop—>启动ZooKeeper集群—>启动HBase—>停止HBase—>停止ZooKeeper集群—>停止Hadoop。
在namenode节点执行bin/hbase-daemon.sh,启动master。
执行bin/start-hbase.sh和bin/stop-hbase.sh脚本启动和停止HBase服务。
HBase按列存储结构化数据,支持建表、插入记录、查询记录、删除记录和索引操作等等,不支持连接和更新操作。
3.4开发步骤
在Windows客户端编写JAVA程序操作HBase,需要引入一些JAR包。
需要引入的JAR如下:
hadoop-0.20.1-core.jar,commons-logging-1.0.4.jar,commons-logging-api-1.0.4.jar,zookeeper-3.2.1.jar,hbase-0.20.1.jar,log4j-1.2.15.jar。
HBase的基本操作
HBase提供了一个类似于mysql等关系型数据库的shell.通过该shell我们可以对HBase的内的相关表以及列族进行控制和处理.HBaseshell的help命令比较详细的列出了HBase所支持的命令.以下是我们用一个学生成绩表作为例子,对HBase进行的基本操作:
下面是学生的成绩表:
name
grad
course:
math
course:
art
Tom
1
87
97
Jerry
2
100
80
这里grad对于表来说是一个列,course对于表来说是一个列族,这个列族由两个列组成:
math和art,当然我们可以根据我们的需要在course中建立更多的列族,如computer,physics等相应的列添加入course列族.
根椐上面的想法和需求,我们就在HBase中建立相应的数据表。
1.建立一个表格scores具有两个列族grad和courese
hbase(main):
002:
0>create'scores','grade','course'
0row(s)in4.1610seconds
2.查看当先HBase中具有哪些表
hbase(main):
003:
0>list
scores
1row(s)in0.0210seconds
3.查看表的构造
hbase(main):
004:
0>describe'scores'
{NAME=>'scores',IS_ROOT=>'false',IS_META=>'false',FAMILIES=>[{NAME=>'course',BLOOMFILTER=>'false',IN_MEMORY=>'false',LENGTH=>'2147483647',BLOCKCACHE=>'false',VERSIONS=>'3',TTL=>'-1',COMPRESSION=>'NONE'},{NAME=>'grade',BLOOMFILTER=>'false',IN_MEMORY=>'false',LENGTH=>'2147483647',BLOCKCACHE=>'false',VERSIONS=>'3',TTL=>'-1',COMPRESSION=>'NONE'}]}
1row(s)in0.0130seconds
4.加入一行数据,行名称为Tom列族grad的列名为””值位1
hbase(main):
005:
0>put'scores','Tom','grade:
','1'
0row(s)in0.0070seconds
5.给Tom这一行的数据的列族添加一列
hbase(main):
006:
0>put'scores','Tom','course:
math','87'
0row(s)in0.0040seconds
6.给Tom这一行的数据的列族添加一列
hbase(main):
007:
0>put'scores','Tom','course:
art','97'
0row(s)in0.0030seconds
7.加入一行数据,行名称为Jerry列族grad的列名为””值位2
hbase(main):
008:
0>put'scores','Jerry','grade:
','2'
0row(s)in0.0040seconds
8.给Jerry这一行的数据的列族添加一列
hbase(main):
009:
0>put'scores','Jerry','course:
math','100'
0row(s)in0.0030seconds
9.给Jerry这一行的数据的列族添加一列
hbase(main):
010:
0>put'scores','Jerry','course:
art','80'
0row(s)in0.0050seconds
10.查看scores表中Tom的相关数据
hbase(main):
011:
0>get'scores','Tom'
COLUMN CELL
course:
art timestamp=1224726394286,value=97
course:
math timestamp=1224726377027,value=87
grade:
timestamp=1224726360727,value=1
3row(s)in0.0070seconds
11.查看scores表中所有数据
hbase(main):
012:
0>scan'scores'
ROW COLUMN+CELL
Tom column=course:
art,timestamp=1224726394286,value=97
Tom column=course:
math,timestamp=1224726377027,value=87
Tom column=grade,timestamp=1224726360727,value=1
Jerry column=course:
art,timestamp=1224726424967,value=80
Jerry column=course:
math,timestamp=1224726416145,value=100
Jerry column=grade,timestamp=1224726404965,value=2
6row(s)in0.0410seconds
12.查看scores表中所有数据courses列族的所有数据
hbase(main):
013:
0>scan'scores',['course:
']
ROW COLUMN+CELL
Tom column=course:
art,timestamp=1224726394286,value=97
Tom column=course:
math,timestamp=1224726377027,value=87
Jerry column=course:
art,timestamp=1224726424967,value=80
Jerry column=course:
math,timestamp=1224726416145,value=100
4row(s)in0.0200seconds
四、结束语
在我们四个人相互合作经过将近一周的努力下,初步完成了对开源分布式数据库系统的探究并初步达到了预期目标。
以上就是我们对HBase进行的基本shell操作,从中我们体会到hbase的shell还是比较简单易用的,从中我们也可以体会出HBaseshell缺少很多传统sql中的一些类似于like等相关操作,当然,HBase作为BigTable的一个开源实现,而BigTable是作为google业务的支持模型,很多sql语句中的一些东西可能还真的不太需要。
但还有很多地方需要改进的。
此外通过此次的合作完成论文提高了我们的团队合作能力和动手能力,这将是我们步入社会时的保贵财富。
参考文