第8课Hbase的java调用方法

本文详细介绍如何使用Java API与HBase进行交互,包括创建表、插入数据、搜索及删除表的操作步骤。通过具体示例代码展示如何在Eclipse中构建Maven项目,并配置HBase环境。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明

  • 本文基于Centos 6.x + CDH 5.x
  • 本例中 Hbase 是安装成集群模式的
  • 本文基于Maven3.5+ 和 Eclipse 4.3
  • 教程后的参考资料建议大家一定要看下

我们搭建hbase并不是要用shell来查数据的,我们是要写基于hbase的应用的,所以学习如何使用java来调用hbase是必修课。

环境搭建

建立项目

打开Eclipse 建立一个Maven项目,archetype选quickstart,项目的artifactId 和 groupId 随便起

修改一下pom.xml 修改jdk为1.6+ ,并且引入hadoop相关jar包
[html]  view plain  copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.   
  5.     <groupId>org.crazycake</groupId>  
  6.     <artifactId>playhbase</artifactId>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <packaging>jar</packaging>  
  9.   
  10.     <name>playhbase</name>  
  11.     <url>http://maven.apache.org</url>  
  12.   
  13.     <properties>  
  14.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  15.     </properties>  
  16.     <resources>  
  17.         <resource>  
  18.             <directory>${basedir}/conf</directory>  
  19.             <filtering>false</filtering>  
  20.             <includes>  
  21.                 <include>hbase-site.xml</include>  
  22.             </includes>  
  23.         </resource>  
  24.     </resources>  
  25.     <dependencies>  
  26.         <dependency>  
  27.             <groupId>junit</groupId>  
  28.             <artifactId>junit</artifactId>  
  29.             <version>3.8.1</version>  
  30.             <scope>test</scope>  
  31.         </dependency>  
  32.         <dependency>  
  33.             <groupId>org.apache.hbase</groupId>  
  34.             <artifactId>hbase-client</artifactId>  
  35.             <version>0.98.4-hadoop2</version>  
  36.         </dependency>  
  37.     </dependencies>  
  38.   
  39.     <build>  
  40.         <plugins>  
  41.             <plugin>  
  42.                 <artifactId>maven-compiler-plugin</artifactId>  
  43.                 <version>2.0.2</version>  
  44.                 <configuration>  
  45.                     <source>1.6</source>  
  46.                     <target>1.6</target>  
  47.                     <encoding>UTF-8</encoding>  
  48.                     <optimise>true</optimise>  
  49.                     <compilerArgument>-nowarn</compilerArgument>  
  50.                 </configuration>  
  51.             </plugin>  
  52.             <plugin>  
  53.                 <groupId>org.apache.maven.plugins</groupId>  
  54.                 <artifactId>maven-shade-plugin</artifactId>  
  55.                 <version>2.3</version>  
  56.                 <configuration>  
  57.                     <transformers>  
  58.                         <transformer  
  59.                             implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">  
  60.                         </transformer>  
  61.                     </transformers>  
  62.                 </configuration>  
  63.                 <executions>  
  64.                     <execution>  
  65.                         <phase>package</phase>  
  66.                         <goals>  
  67.                             <goal>shade</goal>  
  68.                         </goals>  
  69.                     </execution>  
  70.                 </executions>  
  71.             </plugin>  
  72.         </plugins>  
  73.     </build>  
  74. </project>  

  • 除了引入Hbase 的Jar包以外,还引入了一个maven插件叫 maven-shade-plugin ,这个插件可以防止出现“证书重复问题”,重复的证书文件会造成HDInsight集群在运行报错。
  • 配置中还增加了一个resource,这个resource引用了一个配置文件hbase-site.xml,在这里写上hbase的连接信息

建立配置文件

建立src/main/resources 文件夹,并添加到源文件夹,并在文件夹内建立一个 hbase-site.xml 文件,内容是
[html]  view plain  copy
  1. <?xml version="1.0"?>  
  2. <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>  
  3. <!--  
  4. /**  
  5.  * Copyright 2010 The Apache Software Foundation  
  6.  *  
  7.  * Licensed to the Apache Software Foundation (ASF) under one  
  8.  * or more contributor license agreements.  See the NOTICE file  
  9.  * distributed with this work for additional information  
  10.  * regarding copyright ownership.  The ASF licenses this file  
  11.  * to you under the Apache License, Version 2.0 (the  
  12.  * "License"); you may not use this file except in compliance  
  13.  * with the License.  You may obtain a copy of the License at  
  14.  *  
  15.  *     http://www.apache.org/licenses/LICENSE-2.0  
  16.  *  
  17.  * Unless required by applicable law or agreed to in writing, software  
  18.  * distributed under the License is distributed on an "AS IS" BASIS,  
  19.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  20.  * See the License for the specific language governing permissions and  
  21.  * limitations under the License.  
  22.  */  
  23. -->  
  24. <configuration>  
  25.   <property>  
  26.     <name>hbase.cluster.distributed</name>  
  27.     <value>true</value>  
  28.   </property>  
  29.   <property>  
  30.     <name>hbase.zookeeper.quorum</name>  
  31.     <value>host1,host2</value>  
  32.   </property>  
  33.   <property>  
  34.     <name>hbase.zookeeper.property.clientPort</name>  
  35.     <value>2181</value>  
  36.   </property>  
  37. </configuration>  

这个host1 跟 host2 就是你安装zookeeper的机器,因为我只装了两台机器,所以只有host1 和 host2,正常情况下至少是要3个,并且是奇数个增长


操作

创建表并插入数据

创建一类叫 CreateTable.java 这个例子来自 : http://azure.microsoft.com/en-us/documentation/articles/hdinsight-hbase-build-java-maven/?rnd=1 我做了翻译

[java]  view plain  copy
  1. package org.crazycake.playhbase;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.hbase.HBaseConfiguration;  
  7. import org.apache.hadoop.hbase.HColumnDescriptor;  
  8. import org.apache.hadoop.hbase.HTableDescriptor;  
  9. import org.apache.hadoop.hbase.MasterNotRunningException;  
  10. import org.apache.hadoop.hbase.TableName;  
  11. import org.apache.hadoop.hbase.ZooKeeperConnectionException;  
  12. import org.apache.hadoop.hbase.client.HBaseAdmin;  
  13. import org.apache.hadoop.hbase.client.HTable;  
  14. import org.apache.hadoop.hbase.client.Put;  
  15. import org.apache.hadoop.hbase.util.Bytes;  
  16.   
  17. public class CreateTable {  
  18.     public static void main(String[] args) throws MasterNotRunningException, ZooKeeperConnectionException, IOException {  
  19.         Configuration config = HBaseConfiguration.create();  
  20.           
  21.         // 这边注释起来的是动态设定zookeeper参数的方法,如果你没有hbase-site.xml 或者想动态改变  
  22.         // 可以采用动态方式设定  
  23.         //  
  24.         // config.set("hbase.zookeeper.quorum",  
  25.         //            "zookeepernode0,zookeepernode1,zookeepernode2");  
  26.         //config.set("hbase.zookeeper.property.clientPort", "2181");  
  27.         //config.set("hbase.cluster.distributed", "true");  
  28.           
  29.         // 使用配置文件创建一个 admin 对象  
  30.         HBaseAdmin admin = new HBaseAdmin(config);  
  31.           
  32.         // 创建表  
  33.         HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf("people"));  
  34.           
  35.         // 创建2个列簇  
  36.         tableDescriptor.addFamily(new HColumnDescriptor("name"));  
  37.         tableDescriptor.addFamily(new HColumnDescriptor("contactinfo"));  
  38.           
  39.         admin.createTable(tableDescriptor);  
  40.           
  41.         // 接下来搞点数据进去呗  
  42.         String[][] people = {  
  43.             { "1""Marcel""Haddad""marcel@fabrikam.com"},  
  44.             { "2""Franklin""Holtz""franklin@contoso.com" },  
  45.             { "3""Dwayne""McKee""dwayne@fabrikam.com" },  
  46.             { "4""Rae""Schroeder""rae@contoso.com" },  
  47.             { "5""Rosalie""burton""rosalie@fabrikam.com"},  
  48.             { "6""Gabriela""Ingram""gabriela@contoso.com"} };  
  49.   
  50.         HTable table = new HTable(config, "people");  
  51.           
  52.         //  把这些数据插入到表里面  
  53.         for (int i = 0; i< people.length; i++) {  
  54.           //第一列做rowkey  
  55.           Put person = new Put(Bytes.toBytes(people[i][0]));  
  56.             
  57.           //把 Marcel 放到 name 这个列簇的 first 这个字段去  
  58.           person.add(Bytes.toBytes("name"), Bytes.toBytes("first"), Bytes.toBytes(people[i][1]));  
  59.           person.add(Bytes.toBytes("name"), Bytes.toBytes("last"), Bytes.toBytes(people[i][2]));  
  60.           person.add(Bytes.toBytes("contactinfo"), Bytes.toBytes("email"), Bytes.toBytes(people[i][3]));  
  61.           table.put(person);  
  62.         }  
  63.           
  64.         // 最后要记得提交和关闭表  
  65.         table.flushCommits();  
  66.         table.close();  
  67.     }  
  68. }  


注意:在运行前,先用hbase shell 连上去,然后运行list 命令,看看是否正常,如果不正常就用jps看看是否hbase和hadoop的那些服务都启动起来了,把该起的都给起了。不然java运行了出错了,都不知道错在哪里再代码上瞎找原因浪费时间

一切就绪后,运行代码!
如果你的代码长时间卡主,不要傻等,去hbase部署的机器上看日志 :
[plain]  view plain  copy
  1. tail -200f  /var/log/hbase/hbase-hbase-master-host1.localdomain.log  

运行结束后查看一下结果
[plain]  view plain  copy
  1. hbase(main):003:0> scan 'people'  
  2. ROW                              COLUMN+CELL                                                                                    
  3.  1                               column=contactinfo:email, timestamp=1421338694666, value=marcel@fabrikam.com                   
  4.  1                               column=name:first, timestamp=1421338694666, value=Marcel                                       
  5.  1                               column=name:last, timestamp=1421338694666, value=Haddad                                        
  6.  2                               column=contactinfo:email, timestamp=1421338694932, value=franklin@contoso.com                  
  7.  2                               column=name:first, timestamp=1421338694932, value=Franklin                                     
  8.  2                               column=name:last, timestamp=1421338694932, value=Holtz                                         
  9.  3                               column=contactinfo:email, timestamp=1421338694977, value=dwayne@fabrikam.com                   
  10.  3                               column=name:first, timestamp=1421338694977, value=Dwayne                                       
  11.  3                               column=name:last, timestamp=1421338694977, value=McKee                                         
  12.  4                               column=contactinfo:email, timestamp=1421338695034, value=rae@contoso.com                       
  13.  4                               column=name:first, timestamp=1421338695034, value=Rae                                          
  14.  4                               column=name:last, timestamp=1421338695034, value=Schroeder                                     
  15.  5                               column=contactinfo:email, timestamp=1421338695054, value=rosalie@fabrikam.com                  
  16.  5                               column=name:first, timestamp=1421338695054, value=Rosalie                                      
  17.  5                               column=name:last, timestamp=1421338695054, value=burton                                        
  18.  6                               column=contactinfo:email, timestamp=1421338695076, value=gabriela@contoso.com                  
  19.  6                               column=name:first, timestamp=1421338695076, value=Gabriela                                     
  20.  6                               column=name:last, timestamp=1421338695076, value=Ingram                                        
  21. 6 row(s) in 0.3910 seconds  

根据email来搜索

建立一个SearchByEmail类
[cpp]  view plain  copy
  1. package org.crazycake.playhbase;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.hbase.HBaseConfiguration;  
  7. import org.apache.hadoop.hbase.client.HTable;  
  8. import org.apache.hadoop.hbase.client.Result;  
  9. import org.apache.hadoop.hbase.client.ResultScanner;  
  10. import org.apache.hadoop.hbase.client.Scan;  
  11. import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;  
  12. import org.apache.hadoop.hbase.filter.RegexStringComparator;  
  13. import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;  
  14. import org.apache.hadoop.hbase.util.Bytes;  
  15.   
  16. /** 
  17.  * 根据email 来搜索用户 
  18.  * @author alexxiyang (https://github.com/alexxiyang) 
  19.  * 
  20.  */  
  21. public class SearchByEmail {  
  22.     public static void main(String[] args) throws IOException {  
  23.           
  24.         //创建配置  
  25.         Configuration config = HBaseConfiguration.create();  
  26.   
  27.         // 打开表  
  28.         HTable table = new HTable(config, "people");  
  29.           
  30.         //定义一系列要用到的列簇和列  
  31.         // 定义列簇  
  32.         byte[] contactFamily = Bytes.toBytes("contactinfo");  
  33.         // 列  
  34.         byte[] emailQualifier = Bytes.toBytes("email");  
  35.         //列簇  
  36.         byte[] nameFamily = Bytes.toBytes("name");  
  37.         //列  
  38.         byte[] firstNameQualifier = Bytes.toBytes("first");  
  39.         byte[] lastNameQualifier = Bytes.toBytes("last");  
  40.         // 创建一个正则表达式的比较器  
  41.         RegexStringComparator emailFilter = new RegexStringComparator("rosalie@fabrikam.com");  
  42.         // 创建一个filter,把这个正则比较器传进去  
  43.         SingleColumnValueFilter filter = new SingleColumnValueFilter(contactFamily, emailQualifier, CompareOp.EQUAL, emailFilter);  
  44.   
  45.         // 创建一个 scan对象  
  46.         Scan scan = new Scan();  
  47.           
  48.         //把filter 传进去  
  49.         scan.setFilter(filter);  
  50.   
  51.         // 开始查询,并获取结果  
  52.         ResultScanner results = table.getScanner(scan);  
  53.         // 遍历结果打印数据  
  54.         for (Result result : results) {  
  55.             String id = new String(result.getRow());  
  56.             byte[] firstNameObj = result.getValue(nameFamily, firstNameQualifier);  
  57.             String firstName = new String(firstNameObj);  
  58.             byte[] lastNameObj = result.getValue(nameFamily, lastNameQualifier);  
  59.             String lastName = new String(lastNameObj);  
  60.             System.out.println(firstName + " " + lastName + " - ID: " + id);  
  61.             byte[] emailObj = result.getValue(contactFamily, emailQualifier);  
  62.             String email = new String(emailObj);  
  63.             System.out.println(firstName + " " + lastName + " - " + email + " - ID: " + id);  
  64.         }  
  65.         //关闭结果  
  66.         results.close();  
  67.           
  68.         //关闭表  
  69.         table.close();  
  70.     }  
  71. }  
运行结果
[sql]  view plain  copy
  1. Rosalie burton - ID: 5  
  2. Rosalie burton - rosalie@fabrikam.com - ID: 5  

删除表

建立 DeleteTable 类
[java]  view plain  copy
  1. package org.crazycake.playhbase;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.hbase.HBaseConfiguration;  
  7. import org.apache.hadoop.hbase.client.HBaseAdmin;  
  8.   
  9. /** 
  10.  * 删除表 
  11.  * @author alexxiyang (https://github.com/alexxiyang) 
  12.  * 
  13.  */  
  14. public class DeleteTable {  
  15.     public static void main(String[] args) throws IOException {  
  16.           
  17.         //创建配置  
  18.         Configuration config = HBaseConfiguration.create();  
  19.   
  20.         // 建立 admin  
  21.         HBaseAdmin admin = new HBaseAdmin(config);  
  22.   
  23.         // 先 disable 表,再delete  
  24.         admin.disableTable("people");  
  25.         admin.deleteTable("people");  
  26.     }  
  27. }  

去hbase检查下结果

[plain]  view plain  copy
  1. hbase(main):004:0> list  
  2. TABLE                                                                                                                           
  3. employee                                                                                                                        
  4. employee2                                                                                                                       
  5. student                                                                                                                         
  6. users                                                                                                                           
  7. 4 row(s) in 4.8460 seconds  
  8.   
  9. => ["employee", "employee2", "student", "users"]  

people表没有了

我遇到的问题

中间有一个小插曲,浪费了我一天的时间:
一开始我照这个教程 http://azure.microsoft.com/en-us/documentation/articles/hdinsight-hbase-build-java-maven/?rnd=1 做的时候发现我运行了代码发现长时间卡主,我就去hbase-master机器上看下日志,没有任何异常。
又到RegionServer 所在机器上看了下日志,没有任何异常。

然后我觉得可能hbase出了什么问题,我先停掉程序用hbase shell操作一下试试看,建了一个表,插入了一条数据,一切正常

[plain]  view plain  copy
  1. hbase(main):002:0> create 'users','info'   
  2. 0 row(s) in 36.5110 seconds  
  3.   
  4. => Hbase::Table - users  
  5. hbase(main):003:0> list  
  6. TABLE                                                                                                                           
  7. employee                                                                                                                        
  8. employee2                                                                                                                       
  9. student                                                                                                                         
  10. users                                                                                                                           
  11. 4 row(s) in 0.4520 seconds  
  12.   
  13. => ["employee", "employee2", "student", "users"]  
  14. hbase(main):004:0> put 'users',1,'info:name','ted'   
  15. 0 row(s) in 0.8350 seconds  
  16.   
  17. hbase(main):005:0> scan 'users'  
  18. ROW                              COLUMN+CELL                                                                                    
  19.  1                               column=info:name, timestamp=1421252020520, value=ted                                           
  20. 1 row(s) in 0.3140 seconds  

这样问题就有可能出在zookeeper上了,因为你的java API 不是直接跟hbase交互的,是先通过zookeeper交互,所以我就去看下zookeeper的日志,我用tail监听zookeeper日志
[plain]  view plain  copy
  1. tail -200f /var/log/zookeeper/zookeeper.log  

然后我运行java代码,看下zookeeper有没有报什么异常,不过很令我失望,zookeeper什么都没有报

用telnet来连接两台zookeeper机器也都ok,未发现问题。

我没办法只好用最土的方法,直接调试到源代码内部,发现了卡在了检测zookeeper是否可用的代码上

这里出现了一个localhost 
联想到我在hbase 管理界面 (host1:60010)上看到的

估计是这个localhost有问题吧,造成java程序检测本机的2181,这样肯定会卡住的。

然后我去检查我的 host1 上的hbase-site.xml  文件,发现果然没有配置 hbase.zookeeper.quorum 这个参数,于是我配置上这个参数,然后重启hbase-master,再访问 host1:60010

这下比较像样了,然后我再去运行java代码,发现还是卡主!断点到checkIfBaseNodeAvailable发现获取到的配置还是localhost:2181!看来问题在于配置文件的解析上了。
继续断点配置文件的解析。
然后我就发现程序读取的配置文件居然不是hbase-site.xml 而是 zoo.cfg,这是怎么回事?!我看了下官方文档 “HBase 会优先加载 zoo.cfg 里面的配置,把hbase-site.xml里面的覆盖掉.” ,卧槽!既然这样,我就把 zookeeper 的配置文件zoo.cfg 干脆拷贝到 conf 文件夹下,再试试看。还是不行。
然后我突然想到这个hbase-site.xml根本没有加入编译,咋会被java读取到呢?所以我果断不理教程,自己建立了 resources 文件夹,并把这个文件塞到这个目录下,再运行就成了!

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值