一直以来对HBase的了解仅仅限于理论上的,最近想进行深入的学习下,当然对一个东东的学习最为直接的就是直接进行体验一下。为此,我在一个VM的Hadoop集群上安装了一个Hbase集群,期间也遇到了好几种不同的错误,现记录如下,以供后续参考。
Hbase集群配置信息如下:
Hadoop:hadoop-0.20.2,1 个Master节点 1 个Slave节点
Zookeeper:zookeeper-3.3.2 3个Zookeeper节点
Hbase:hbase-0.90.2 一个HMasterServer节点,1个HRegionServer节点
机器环境(3个VM节点):
192.168.43.201 zhangzk01 (物理机器A)
192.168.43.202 zhangzk02 (物理机器A)
192.168.43.203 zhangzk03 (物理机器B)
由于是在家里的试用环境,所以想尽量简单一点,最开始是期待能以一台机器A上的两个VM节点来完成Hbase的集群搭建的,但是多次尝试失败了,后续改为再启动机器B上的节点也作为一个zookeeper节点,才顺利搞定了。
在安装过程中遇到过如下两个问题:
(1)hadoop与hbase的版本不匹配
这个问题的解决办法比较简单,将hbase/lib下的hadoop*.jar删除掉,再把hadoop/hadoop*.jar复制到hbase/lib即可。
(2)Zookeeper的节点数不合理
zookeeper的节点数要求为奇数的,对于我来讲就是1个或者3个了,当然我也实验过2个节点的,反正是不成功的。只有一个zookeeper节点的时候,hbase.zookeeper.quorum中只能配一个了,这个时候由于参与选举的节点为1个,所以基本上不生效的,也失败了;不过理论上讲应该1个节点也是可以的啊,只一票就生效的,后续有时间再研究下究竟错在哪里了。
安装与配置过程
(1)Hadoop
详见在Redhat AS6上搭建Hadoop集群总结,在这里就不再重复描述了
(2)zookeeper
1、将zookeeper-3.3.3/conf下的zoo_sample.cfg重命名为zoo.cfg
2、修改zoo.cfg内容如下
# The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. dataDir=/home/zhangzk/zookeeper-3.3.2/data_dir # the port at which the clients will connect clientPort=2181 server.1=192.168.43.201:2888:3888 server.2=192.168.43.202:2888:3888 server.3=192.168.43.203:2888:3888
3、在zookeeper-3.3.2下新建目录data_dir
cd /home/zhangzk/zookeeper-3.3.2 mkdir data_dir
4、在/home/zhangzk/zookeeper-3.3.3/data_dir目录下新建文件myid
5、在myid中写入该节点的序号值,与步骤2中的server.X中的X的值一致
注意除第5步在各节点上有配置差异之外,其它配置在各节点上完全一致。
(3)hbase
1、修改hbase-0.90.2/conf/hbase-site.xml文件内容如下
<configuration> <property> <name>hbase.rootdir</name> <value>hdfs://zhangzk01:9000/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>zhangzk01,zhangzk02,zhangzk03</value> </property> <property> <name>zookeeper.session.timeout</name> <value>60000</value> </property> <property> <name>hbase.zookeeper.property.clientPort</name> <value>2222</value> </property> </configuration>
2、修改regionservers内容
zhangzk02
(4)使用Hbase shell访问Hbase
[zhangzk@zhangzk01 hbase-0.90.2]$ hbase shell HBase Shell; enter 'help<RETURN>' for list of supported commands. Type "exit<RETURN>" to leave the HBase Shell Version 0.90.2, r1085860, Sun Mar 27 13:52:43 PDT 2011 hbase(main):001:0> list TABLE 0 row(s) in 2.1660 seconds hbase(main):002:0> create 'student','data','ext' 0 row(s) in 4.0500 seconds hbase(main):003:0> list TABLE student 1 row(s) in 0.3450 seconds hbase(main):004:0> put 'student','1','data:name','zhangzk01' 0 row(s) in 0.3150 seconds hbase(main):005:0> put 'student','2','data:name','zhangzk02' 0 row(s) in 0.1090 seconds hbase(main):006:0> put 'student','3','data:name','zhangzk03' 0 row(s) in 0.0620 seconds hbase(main):007:0> get 'student','1' COLUMN CELL data:name timestamp=1306066277632, value=zhangzk01 1 row(s) in 0.3620 seconds hbase(main):008:0> get 'student','2' COLUMN CELL data:name timestamp=1306066291410, value=zhangzk02 1 row(s) in 0.0620 seconds hbase(main):009:0> get 'student','3' COLUMN CELL data:name timestamp=1306066301659, value=zhangzk03 1 row(s) in 0.0410 seconds hbase(main):010:0>
(5)使用Java client来访问Hbase
Configuration config = new Configuration(); //与hbase-0.90.2/conf/hbase-site.xml中hbase.zookeeper.quorum配置的值相同 config.set("hbase.zookeeper.quorum", "zhangzk01,zhangzk02,zhangzk03"); //与hbase-0.90.2/conf/hbase-site.xml中hbase.zookeeper.property.clientPort配置的值相同 config.set("hbase.zookeeper.property.clientPort", "2222"); hbaseConfig = HBaseConfiguration.create(config); //创建表 HBaseAdmin admin = new HBaseAdmin(hbaseConfig); if (admin.tableExists(tablename)) { System.out.println("table Exists!!!"); } else { HTableDescriptor tableDesc = new HTableDescriptor(tablename); tableDesc.addFamily(new HColumnDescriptor("commondata")); tableDesc.addFamily(new HColumnDescriptor("persondata")); admin.createTable(tableDesc); System.out.println("create table ok."); } //插入数据 long last = System.currentTimeMillis(); HTable table = new HTable(hbaseConfig, tablename); for (int i = 500000; i < 5000000; i++) { Put put = new Put(Bytes.toBytes("LB00000000000000000000" + i)); put.add(Bytes.toBytes("commondata"), Bytes.toBytes("id"), Bytes .toBytes("LB00000000000000000000" + i)); put.add(Bytes.toBytes("commondata"), Bytes.toBytes("order_code"), Bytes.toBytes("LB00000000000000000000" + i)); put.add(Bytes.toBytes("commondata"), Bytes.toBytes("source_type"), Bytes.toBytes(i % 10)); put.add(Bytes.toBytes("commondata"), Bytes.toBytes("order_type"), Bytes.toBytes(i % 5)); put.add(Bytes.toBytes("commondata"), Bytes .toBytes("order_sub_type"), Bytes.toBytes(i % 5)); put.add(Bytes.toBytes("persondata"), Bytes .toBytes("receive_name"), Bytes.toBytes("zhangzk-"+i)); put.add(Bytes.toBytes("persondata"), Bytes .toBytes("receive_address"), Bytes.toBytes("浙江省杭州市西湖区文九西路好好新村南N区"+i+"号5楼23号")); put.add(Bytes.toBytes("persondata"), Bytes .toBytes("receive_name"), Bytes.toBytes("zhangzk-"+i)); put.add(Bytes.toBytes("persondata"), Bytes .toBytes("receive_mobile"), Bytes.toBytes("13868117135")); put.add(Bytes.toBytes("persondata"), Bytes .toBytes("receive_zip"), Bytes.toBytes("518039")); put.add(Bytes.toBytes("persondata"), Bytes .toBytes("receive_telephone"), Bytes.toBytes("0571-88155188-11029")); table.put(put); if( i % 50000 == 0 ){ System.out.println( "i=" + i +";time=" + (last - System.currentTimeMillis())); last = System.currentTimeMillis(); } } System.out.println("add data ok.");
在单机1虚2的情况下,单线程插入性能如下:
i=500000;time=187
i=550000;time=112704
i=600000;time=125031
i=650000;time=120500
i=700000;time=115750
i=750000;time=95516
i=800000;time=110859
i=850000;time=119610
i=900000;time=99172
i=950000;time=105828
i=1000000;time=108453
i=1050000;time=124141
i=1100000;time=124703
i=1150000;time=104125
i=1200000;time=117812
i=1250000;time=94594
i=1300000;time=107703
i=1350000;time=98563
i=1400000;time=93640
i=1450000;time=124594
i=1500000;time=125000
i=1550000;time=108906
i=1600000;time=126906
i=1650000;time=128032
i=1700000;time=113781
i=1750000;time=103562
i=1800000;time=105469
i=1850000;time=126875
i=1900000;time=178141
i=1950000;time=76953
i=2000000;time=69078
i=2050000;time=71953
i=2100000;time=89625
i=2150000;time=60016
i=2200000;time=67719
i=2250000;time=67171
i=2300000;time=70454
i=2350000;time=66406
i=2400000;time=67015
i=2450000;time=70125
i=2500000;time=63110
i=2550000;time=65078
i=2600000;time=62656
i=2650000;time=61766
i=2700000;time=65062
i=2750000;time=63657
i=2800000;time=67765
i=2850000;time=67031
i=2900000;time=69657
i=2950000;time=67000
i=3000000;time=60672
i=3050000;time=72343
i=3100000;time=66266
HBASE那些你应该知道的事:
Hbase 如何更新 HDFS 文件
HBase技术介绍
HFile存储格式
HBase存储架构
paxos 实现
Zookeeper全解析——Paxos作为灵魂
Zookeeper研究和应用