spring-hadoop之操作hbase

Srping对于属于java web技术的程序员都不会陌生,jdbcTemplate更是用的熟之又熟,下面我们来认识一下Spring大家庭的新成员:Spring-data-hadoop项目。Spring-hadoop这个项目应该是在 Spring Data 项目的一部分(Srping data其余还包括把Spring和JDBC,REST,主流的NoSQL结合起来了)。其实再一想,Spring和Hadoop结合会发生什么呢,其实就是把Hadoop组件的配置,任务部署之类的东西都统一到Spring的bean管理里去了。

1.    pom.xml中引入maven依赖

<dependency>

         <groupId>org.springframework.data</groupId>

         <artifactId>spring-data-Hadoop</artifactId>

         <version>1.0.1.RELEASE</version>

</dependency>

<dependency>

         <groupId>org.apache.Hbase</groupId>

         <artifactId>hbase</artifactId>

         <version>0.94.12</version>

扫描二维码关注公众号,回复: 11926453 查看本文章

</dependency>

2.    Spring-hbase.xml配置文件配置:

<?xml version="1.0" encoding="UTF-8"?> 

<beans

xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:hdp="http://www.springframework.org/schema/hadoop"

xsi:schemaLocation="

http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/hadoophttp://www.springframework.org/schema/hadoop/spring-hadoop.xsd">

 <!-- 配置zookeeper的信息,远程连接hbase时使用 -->  
    <hdp:configuration resources="classpath:/hbase-site.xml" />  
    <hdp:hbase-configuration configuration-ref="hadoopConfiguration" />  
    <!-- 配置HbaseTemplate -->  
    <bean id="htemplate" class="org.springframework.data.hadoop.hbase.HbaseTemplate">  
        <property name="configuration" ref="hbaseConfiguration">  
        </property>  
    <property name="encoding" value="UTF-8"></property>  
    </bean>  
 </beans> 

hbaseConfiguration其实就是指的<hdp:hbase-configuration/>配置的信息

4、将hbase-site.xml配置文件拷贝到src目录下,参考内容如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <configuration>
 3   <property>
 4     <name>hbase.rootdir</name>
 5     <value>hdfs://nameservice1/hbase</value>
 6   </property>
 7   <property>
 8     <name>hbase.client.write.buffer</name>
 9     <value>62914560</value>
10   </property>
11   <property>
12     <name>hbase.client.pause</name>
13     <value>1000</value>
14   </property>
15   <property>
16     <name>hbase.client.retries.number</name>
17     <value>10</value>
18   </property>
19   <property>
20     <name>hbase.client.scanner.caching</name>
21     <value>1</value>
22   </property>
23   <property>
24     <name>hbase.client.keyvalue.maxsize</name>
25     <value>62914560</value>
26   </property>
27   <property>
28     <name>hbase.rpc.timeout</name>
29     <value>60000</value>
30   </property>
31   <property>
32     <name>hbase.security.authentication</name>
33     <value>simple</value>
34   </property>
35   <property>
36     <name>zookeeper.session.timeout</name>
37     <value>60000</value>
38   </property>
39   <property>
40     <name>zookeeper.znode.parent</name>
41     <value>/hbase</value>
42   </property>
43   <property>
44     <name>zookeeper.znode.rootserver</name>
45     <value>root-region-server</value>
46   </property>
47   <property>
48     <name>hbase.zookeeper.quorum</name>
49     <value>xinhong-hadoop-56,xinhong-hadoop-52,xinhong-hadoop-53</value>
50   </property>
51   <property>
52     <name>hbase.zookeeper.property.clientPort</name>
53     <value>2181</value>
54   </property>
55 </configuration>

5.     实例演示

public static void main(String[] args) {

       ApplicationContext context = new ClassPathXmlApplicationContext(newString[] { "spring-beans-hbase.xml" });

       BeanFactory factory = (BeanFactory) context;

       HbaseTemplate htemplate = (HbaseTemplate) factory.getBean("htemplate");

       String custom = "custom";

       htemplate.get("wcm", "10461", newRowMapper<String>(){

           @Override

           public String mapRow(Result result, int rowNum) throws Exception {

                // TODO Auto-generated methodstub

                for(KeyValue kv :result.raw()){

                    String key = newString(kv.getQualifier());

                    String value = newString(kv.getValue());

                    System.out.println(key +"= "+Bytes.toString(value.getBytes()));

                }

                return null;

           }

       });

}

查看数据 get “wcm“, ”rowkey“ 得到一条数据

Hbase查询总结:

HBase只提供了行级索引,因此,要进行条件查询只有两种方式:

(1).设计合适的行键(通过行键直接定位到数据所在的位置);

(2).通过Scan方式进行查询,Scan可设置其实行和结束行,把这个搜索限定在一个区域中进行;

Scan可以设置一个或多个Filter,来对行键、列族和列进行过滤,从而达到条件查询的目的。

Get数据的获取与上节Put数据插入一样,分为多种使用方式。

1、单行获取:get(Get get)

单行获取每次RPC请求值发送一个Get对象中的数据,因为Get对象初始化时需要输入行键,因此可以理解为一个Get对象就代表一行。一行中可以包含多个列簇或者多个列等信息

[html]  view plain  copy
  1. public void get(String tableName,String rowKey,String family,String qualifier)  
  2.     {  
  3.         Configuration conf=init();  
  4.         try {  
  5.             //进行管理员获取  
  6.             HBaseAdmin admin=new HBaseAdmin(conf);  
  7.             if(!admin.tableExists(Bytes.toBytes(tableName)))  
  8.             {  
  9.                 System.err.println("the table "+tableName+" is not exist");  
  10.                 admin.close();  
  11.                 System.exit(1);  
  12.             }  
  13.             admin.close();  
  14.             //创建表连接  
  15.             HTable table=new HTable(conf,TableName.valueOf(tableName));  
  16.             //创建一个获取对象  
  17.             Get get=new Get(Bytes.toBytes(rowKey));  
  18.             //根据传入的值,进行获取判断  
  19.             if(family!=null && qualifier!=null)  
  20.             {  
  21.                 get.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));  
  22.             }  
  23.             else if(family != null && qualifier == null)  
  24.             {  
  25.                 get.addFamily(Bytes.toBytes(family));  
  26.             }  
  27.             //获取数据  
  28.             Result result=table.get(get);  
  29.             KeyValue[] kvs=result.raw();  
  30.             for(KeyValue kv:kvs)  
  31.             {  
  32.                 System.out.println(Bytes.toString(kv.getRow()));  
  33.                 System.out.println(Bytes.toString(kv.getFamily()));  
  34.                 System.out.println(Bytes.toString(kv.getQualifier()));  
  35.                 System.out.println(Bytes.toString(kv.getValue()));  
  36.             }  
  37.         } catch (Exception e) {  
  38.             // TODO: handle exception  
  39.             e.printStackTrace();  
  40.         }  
  41.     }  

从上述代码中我们可以看到,Get实例使用 addColumn / addFamily 着两个函数想Get中添加搜索范围。如果没有添加,则表示将整行数据进行返回。如果添加列簇,则将指定的列簇中的所有列进行返回,如果指定列,则将制定的列进行返回。

2、获取多行: get(List<Get> list)

多行获取获取实质就是在代码中对List<Get>实例进行迭代,从而发送多次数据请求(即多个RPC请求与数据操作,一次请求包含一次RPC请求和一次数据传输)。

[java]  view plain  copy
  1. public void getList(String tableName,String[] rows,String[] families,String[] qualifiers)  
  2.     {  
  3.         Configuration conf=init();  
  4.         try {  
  5.             //判断表是否存在  
  6.             HBaseAdmin admin=new HBaseAdmin(conf);  
  7.             if(!admin.tableExists(Bytes.toBytes(tableName)))  
  8.             {  
  9.                 System.err.println("the table "+tableName+" is not exist");  
  10.                 admin.close();  
  11.                 System.exit(1);  
  12.             }  
  13.             //创建表连接  
  14.             HTable table=new HTable(conf, Bytes.toBytes(tableName));  
  15.             List<Get> gets=new ArrayList<>();  
  16.             int length=rows.length;  
  17.             for(int i=0;i<length;i++)  
  18.             {  
  19.                 Get get=new Get(Bytes.toBytes(rows[i]));  
  20.                 get.addColumn(Bytes.toBytes(families[i]), Bytes.toBytes(qualifiers[i]));  
  21.                 gets.add(get);  
  22.             }  
  23.             //对结果进行递归输出  
  24.             Result[] results=table.get(gets);  
  25.             for(Result result:results)  
  26.             {  
  27.                 KeyValue[] keyValues=result.raw();  
  28.                 for(KeyValue kv:keyValues)  
  29.                 {  
  30.                     System.out.println(Bytes.toString(kv.getRow()));  
  31.                     System.out.println(Bytes.toString(kv.getFamily()));  
  32.                     System.out.println(Bytes.toString(kv.getQualifier()));  
  33.                     System.out.println(Bytes.toString(kv.getValue()));  
  34.                 }  
  35.             }  
  36.         } catch (Exception e) {  
  37.             // TODO: handle exception  
  38.             e.printStackTrace();  
  39.         }  
  40.     }  

3、获取数据或者前一行:getRowOrBefore()

该函数是HTable类提供的一个借口。作为为:当参数中的行存在时,则将本行指定的列簇进行返回,如果不存在时,则返回表中存在的指定行的前一行的数据进行返回。

[java]  view plain  copy
  1. public void getRowOrBefore(String tableName,String row,String family,String qualifier)  
  2.     {  
  3.         Configuration conf=init();  
  4.         try {  
  5.             HBaseAdmin admin=new HBaseAdmin(conf);  
  6.             if(!admin.tableExists(tableName))  
  7.             {  
  8.                 System.out.println("the table "+tableName+" is not exist");  
  9.                 admin.close();  
  10.                 System.exit(1);  
  11.             }  
  12.             //创建表连接  
  13.             HTable table=new HTable(conf, tableName);  
  14.             //执行函数  
  15.             Result result=table.getRowOrBefore(Bytes.toBytes(row),Bytes.toBytes(family));  
  16.             //进行循环  
  17.             KeyValue[] keyValues=result.raw();  
  18.             for(KeyValue kv: keyValues)  
  19.             {  
  20.                 System.out.println(Bytes.toString(kv.getRow()));  
  21.                 System.out.println(Bytes.toString(kv.getFamily()));  
  22.                 System.out.println(Bytes.toString(kv.getQualifier()));  
  23.                 System.out.println(Bytes.toString(kv.getValue()));  
  24.                 System.out.println(Bytes.toString(kv.getKey()));  
  25.             }  
  26.             table.close();  
  27.         } catch (Exception e) {  
  28.             // TODO: handle exception  
  29.         }  
  30.     }  

注意:在函数中需要注意的是,所有行的row在HBase中的存储都是byte数组,其没有具体的类型,因此row-10 是小于 row-9。因此在进行比较是在第五位中1是小于9,HBase数据库则会认为row-10 是小于 row-9 的。如果指定顺序的话,则需要将数据的row的位数规定一致。则 row-9 应该更改为 row-09。通过这样的修改可以保证 row-09 是小于 row-10的。

4、结果显示:Result对象、KeyValue对象与Cell对象

(1)Result对象,在查询得到的结果,每一行数据会被作为一个Result对象,将数据存入到一个Result实例中。当我们需要获取一行数据时则需要获取该行数据所在的Result对象即可。该对象内部封装了一个KeyValue 对象数组。在0.98.4以前的本班。result类提供了 raw() 方法去获取整个result对象中的KeyValue数组。在0.98.4以后,则提供了一个新的节后: rowCells() 方法获取KeyValue对象,不过返回的是KeyValue 对象父类引用。

(2)KeyValue对象。该对象我们已经进行过介绍。因此这里我们只进行其使用的展示

[java]  view plain  copy
  1. public void KVObject(String tableName,String row,String family,String qualifier)  
  2.     {  
  3.         Configuration conf=init();  
  4.         try {  
  5.             HBaseAdmin admin=new HBaseAdmin(conf);  
  6.             if(!admin.tableExists(Bytes.toBytes(tableName)))  
  7.             {  
  8.                 System.err.println("the table "+tableName+" is not exist");  
  9.                 admin.close();  
  10.                 System.exit(1);  
  11.             }  
  12.             admin.close();  
  13.             //创建表连接  
  14.             HTable table=new HTable(conf, tableName);  
  15.             //查询一行并返回result对象  
  16.             Get get=new Get(Bytes.toBytes(row));  
  17.             Result result=table.get(get);  
  18.             //进行循环  
  19.             KeyValue[] keyValues=result.raw();  
  20.             for(KeyValue kv: keyValues)  
  21.             {  
  22.                 System.out.println(Bytes.toString(kv.getRow()));  
  23.                 System.out.println(Bytes.toString(kv.getFamily()));  
  24.                 System.out.println(Bytes.toString(kv.getQualifier()));  
  25.                 System.out.println(Bytes.toString(kv.getValue()));  
  26.                 System.out.println(Bytes.toString(kv.getKey()));  
  27.             }  
  28.             table.close();  
  29.         } catch (Exception e) {  
  30.             // TODO: handle exception  
  31.             e.printStackTrace();  
  32.         }  
  33.     }  

(3)Cell对象:Cell对象是KeyValue对象的父类,Cell对象中的所有方法在KeyValue对象中全部被实现。因此根据继承的特征,我们可以使用Cell对象中的API操作KeyValue对象。

[java]  view plain  copy
  1. public void CellObject(String tableName,String row,String family,String qualifier)  
  2.     {  
  3.         Configuration conf=init();  
  4.         try {  
  5.             //查看表是否存在  
  6.             HBaseAdmin admin=new HBaseAdmin(conf);  
  7.             if(!admin.tableExists(tableName))  
  8.             {  
  9.                 System.out.println("the table "+tableName+" is not exist");  
  10.                 admin.close();  
  11.                 System.exit(1);  
  12.             }  
  13.             admin.close();  
  14.             //创建表连接  
  15.             HTable table=new HTable(conf, tableName);  
  16.             Get get=new Get(Bytes.toBytes(row));  
  17.             get.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));  
  18.             Result result=table.get(get);  
  19.             Cell[] cells=result.rawCells();  
  20.             for(Cell cell:cells)  
  21.             {  
  22.                 System.out.println(Bytes.toString(cell.getRow()));  
  23.                 System.out.println(Bytes.toString(cell.getFamily()));  
  24.                 System.out.println(Bytes.toString(cell.getQualifier()));  
  25.                 System.out.println(Bytes.toString(cell.getValue()));  
  26.             }  
  27.             table.close();  
  28.         } catch (Exception e) {  
  29.             // TODO: handle exception  
  30.         }  
  31.     }  






查询列族下的列的数据:

1 public List<String> find(String tableName,String family,String cloumn){
2         List<String> rows = hbaseTemplate.find(tableName, family,cloumn, new RowMapper<String>() {
3             public String mapRow(Result result, int rowNum) throws Exception {
4                 return Bytes.toString(result.getRow());
5             }
6         });
7         return rows;
8     }

查询指定行健的一列数据:

1 public String get(String tableName,String family,String cloumn,String rowKey){
2         String context = hbaseTemplate.get(tableName, "NCEP_p_wa_2014032212_tp_006.nc", family, cloumn, new RowMapper<String>() {
3             public String mapRow(Result result, int rowNum) throws Exception {
4                 return Bytes.toString(result.value());
5               }
6             });
7         return context;
8     }

5.    基本命令

查看有哪些表list

查看所有数据 scan “表名”

查看数据 get “wcm“,”lrowkey“ 得到一条数据

 删除一条数据delete “表名”,”主键”,”列族”,”列”

 删除整条数据deleteAll “表名”,”主键”

Hbase的特点:

>>在命令窗口只能一次更新一个单元格;

>>在程序中通过调用HTable.setAutoFlush(false)方法可以将HTable写客户端的自动flush关闭,这样可以批量写入数据到 HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存时,才实际向HBase服务端发起写请求。默认情况下auto flush是开启的。

猜你喜欢

转载自blog.csdn.net/happyAliceYu/article/details/62218257