1.Configuration

在使用Java API时,Client端需要知道HBase的配置环境,如存储地址,zookeeper等信息。这些信息通过Configuration对象来封装,可通过如下代码构建该对象

        Configuration config=HBaseConfiguration.create();

在调用HBaseConfiguration.create()方法时,HBase首先会在classpath下查找hbase-site.xml文件,将里面的信息解析出来封装到Configuration对象中,如果hbase-site.xml文件不存在,则使用默认的hbase-core.xml文件。

除了将hbase-site.xml放到classpath下,开发人员还可通过config.set(name, value)方法来手工构建Configuration对象。

       

Configuration.set(String name, String value)

2.HBaseAdmin

HBaseAdmin用于创建数据库表格,并管理表格的元数据信息,通过如下方法构建

        HBaseAdmin admin=new HBaseAdmin(config);

常用方法:

        addColumn(tableName,column):为表格添加栏位

        deleteColumn(tableName,column):删除指定栏位

        balanceSwitch(boolean):是否启用负载均衡

        createTable(HTableDescriptor desc):创建表格

        deleteTable(tableName):删除表格

       

tableExists(tableName):判断表格是否存在

示例:创建test表格,并为其指定columnFamily为cf

1. HBaseAdmin admin=new
2. If(!admin.tableExists(“test”)){  
3. new
4. new
5.     tableDesc.addFamily(cf);  
6.     admin.createTable(tableDesc);  
7. }


3.HTable

在HBase中,HTable封装表格对象,对表格的增删改查操作主要通过它来完成,构造方法如下:

        HTable table=new HTable(config,tableName);

在构建多个HTable对象时,HBase推荐所有的HTable使用同一个Configuration。这样,HTable之间便可共享HConnection对象、zookeeper信息以及Region地址的缓存信息。

示例1:Get操作

1. Get get=new
2. Result res=table.get(get);


示例2:Put操作

1. Put put=new
2. put.add(columnFamily,column,value);  
3. table.put(put);

注:在HBase中,实体的新增和更新都是通过Put操作来实现。


示例3:Delete操作

1. Delete delete=new
2. table.delete(delete);


示例4:Scan操作

1. Scan scan=new
2. scan.addColumn(columnFamily,column);//指定查询要返回的column
3. SingleColumnValueFilter filter=new
4. //指定要过滤的column
5. //指定过滤条件
6. );  
7. //更多的过滤器信息请查看org.apache.hadoop.hbase.filter包
8. scan.setFilter(filter);//为查询指定过滤器
9. ResultScanner scanner=table.getScanner(scan);//执行扫描查找
10. Iterator<Result> res=scanner.iterator( );//返回查询遍历器

HBase提供了java api来对HBase进行一系列的管理涉及到对表的管理、数据的操作等。常用的API操作有:
  1、  对表的创建、删除、显示以及修改等,可以用HBaseAdmin,一旦创建了表,那么可以通过HTable的实例来访问表,每次可以往表里增加数据。
  2、  插入数据
    创建一个Put对象,在这个Put对象里可以指定要给哪个列增加数据,以及当前的时间戳等值,然后通过调用HTable.put(Put)来提交操作,子猴在这里提请注意的是:在创建Put对象的时候,你必须指定一个行(Row)值,在构造Put对象的时候作为参数传入。
  3、  获取数据
    要获取数据,使用Get对象,Get对象同Put对象一样有好几个构造函数,通常在构造的时候传入行值,表示取第几行的数据,通过HTable.get(Get)来调用。
  4、  浏览每一行
    通过Scan可以对表中的行进行浏览,得到每一行的信息,比如列名,时间戳等,Scan相当于一个游标,通过next()来浏览下一个,通过调用HTable.getScanner(Scan)来返回一个ResultScanner对象。HTable.get(Get)和HTable.getScanner(Scan)都是返回一个Result。Result是一个
KeyValue的链表。
  5、  删除
    使用Delete来删除记录,通过调用HTable.delete(Delete)来执行删除操作。(注:删除这里有些特别,也就是删除并不是马上将数据从表中删除。)
  6、  锁
    新增、获取、删除在操作过程中会对所操作的行加一个锁,而浏览却不会。
  7、  簇的访问
    客户端代码通过ZooKeeper来访问找到簇,也就是说ZooKeeper quorum将被使用,那么相关的类(包)应该在客户端的类(classes)目录下,即客户端一定要找到文件hbase-site.xml。

以下是一个完整的代码示例,基于hbase-0.90.3编写

1. import
2. import
3. import
4.    
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13. import
14. import
15. import
16. import
17. import
18. import
19. import
20. import
21.    
22. public class
23.       
24. private static Configuration conf = null;  
25.        
26. /**
27.      * 初始化配置
28.      */
29. static
30. new
31. //与hbase/conf/hbase-site.xml中hbase.zookeeper.quorum配置的值相同 
32. "hbase.zookeeper.quorum", "10.1.1.1");  
33. //与hbase/conf/hbase-site.xml中hbase.zookeeper.property.clientPort配置的值相同
34. "hbase.zookeeper.property.clientPort", "2181");  
35.         conf = HBaseConfiguration.create(HBASE_CONFIG);  
36.     }  
37.       
38. /**
39.      * 创建一张表
40.      */
41. public static void creatTable(String tableName, String[] familys) throws
42. new
43. if
44. "table already exists!");  
45. else
46. new
47. for(int i=0; i<familys.length; i++){  
48. new
49.             }  
50.             admin.createTable(tableDesc);  
51. "create table " + tableName + " ok.");  
52.         }   
53.     }  
54.       
55. /**
56.      * 删除表
57.      */
58. public static void deleteTable(String tableName) throws
59. try
60. new
61.            admin.disableTable(tableName);  
62.            admin.deleteTable(tableName);  
63. "delete table " + tableName + " ok.");  
64. catch
65.            e.printStackTrace();  
66. catch
67.            e.printStackTrace();  
68.        }  
69.     }  
70.        
71. /**
72.      * 插入一行记录
73.      */
74. public static void
75. throws
76. try
77. new
78. new
79.             put.add(Bytes.toBytes(family),Bytes.toBytes(qualifier),Bytes.toBytes(value));  
80.             table.put(put);  
81. "insert recored " + rowKey + " to table " + tableName +" ok.");  
82. catch
83.             e.printStackTrace();  
84.         }  
85.     }  
86.    
87. /**
88.      * 删除一行记录
89.      */
90. public static void delRecord (String tableName, String rowKey) throws
91. new
92. new
93. new
94.         list.add(del);  
95.         table.delete(list);  
96. "del recored " + rowKey + " ok.");  
97.     }  
98.        
99. /**
100.      * 查找一行记录
101.      */
102. public static void getOneRecord (String tableName, String rowKey) throws
103. new
104. new
105.         Result rs = table.get(get);  
106. for(KeyValue kv : rs.raw()){  
107. new String(kv.getRow()) + " "
108. new String(kv.getFamily()) + ":"
109. new String(kv.getQualifier()) + " "
110. " "
111. new
112.         }  
113.     }  
114.        
115. /**
116.      * 显示所有数据
117.      */
118. public static void
119. try{  
120. new
121. new
122.              ResultScanner ss = table.getScanner(s);  
123. for(Result r:ss){  
124. for(KeyValue kv : r.raw()){  
125. new String(kv.getRow()) + " ");  
126. new String(kv.getFamily()) + ":");  
127. new String(kv.getQualifier()) + " ");  
128. " ");  
129. new
130.                  }  
131.              }  
132. catch
133.             e.printStackTrace();  
134.         }  
135.     }  
136.       
137. public static void
138. try
139. "scores";  
140. "grade", "course"};  
141.             HBaseTest.creatTable(tablename, familys);  
142.                
143. //add record zkb
144. "zkb","grade","","5");  
145. "zkb","course","","90");  
146. "zkb","course","math","97");  
147. "zkb","course","art","87");  
148. //add record  baoniu
149. "baoniu","grade","","4");  
150. "baoniu","course","math","89");  
151.                
152. "===========get one record========");  
153. "zkb");  
154.                
155. "===========show all record========");  
156.             HBaseTest.getAllRecord(tablename);  
157.                
158. "===========del one record========");  
159. "baoniu");  
160.             HBaseTest.getAllRecord(tablename);  
161.                
162. "===========show all record========");  
163.             HBaseTest.getAllRecord(tablename);  
164. catch
165.             e.printStackTrace();  
166.         }  
167.     }  
168. }



1.程序编译为一个jar包hbtest.jar

2.写个shell 脚本:(hbtest.sh)

1. #!/bin/sh  
2.   
3. source ~/.bash_profile  
4. export HADOOP_CLASSPATH=/home/liliugen/hadoop-0.20.2/hadoop-core-0.20.2-cdh3u0.jar:/home/liliugen/hbase-0.90.1/hbase-0.90.1-cdh3u0.jar:/home/liliugen/zookeeper-3.3.3/zookeeper-3.3.3.jar  
5.   
6. /home/liliugen/hadoop-0.20.2/bin/hadoop jar hbtest.jar hbase.HBaseTest


HBase client API Guide  

HBaseConfiguration是每一个hbase client都会使用到的对象,它代表的是HBase配置信息。它有两种构造方式:

public HBaseConfiguration()

public HBaseConfiguration(final Configuration c)

默认的构造方式会尝试从hbase-default.xml和hbase-site.xml中读取配置。如果classpath没有这两个文件,就需要你自己设置配置。

Configuration HBASE_CONFIG = new Configuration();

HBASE_CONFIG.set(“hbase.zookeeper.quorum”, “zkServer”);

HBASE_CONFIG.set(“hbase.zookeeper.property.clientPort”, “2181″);

HBaseConfiguration cfg = new HBaseConfiguration(HBASE_CONFIG);

创建表

创建表是通过HBaseAdmin对象来操作的。HBaseAdmin负责表的META信息处理。HBaseAdmin提供了createTable这个方法:

public void createTable(HTableDescriptor desc)

HTableDescriptor 代表的是表的schema, 提供的方法中比较有用的有

setMaxFileSize,指定最大的region size

setMemStoreFlushSize 指定memstore flush到HDFS上的文件大小

增加family通过 addFamily方法

public void addFamily(final HColumnDescriptor family)

HColumnDescriptor 代表的是column的schema,提供的方法比较常用的有

setTimeToLive:指定最大的TTL,单位是ms,过期数据会被自动删除。

setInMemory:指定是否放在内存中,对小表有用,可用于提高效率。默认关闭

setBloomFilter:指定是否使用BloomFilter,可提高随机查询效率。默认关闭

setCompressionType:设定数据压缩类型。默认无压缩。

setMaxVersions:指定数据最大保存的版本个数。默认为3。

一个简单的例子,创建了4个family的表:

HBaseAdmin hAdmin = new HBaseAdmin(hbaseConfig);

HTableDescriptor t = new HTableDescriptor(tableName);

t.addFamily(new HColumnDescriptor(“f1″));

t.addFamily(new HColumnDescriptor(“f2″));

t.addFamily(new HColumnDescriptor(“f3″));

t.addFamily(new HColumnDescriptor(“f4″));

hAdmin.createTable(t);

删除表

删除表也是通过HBaseAdmin来操作,删除表之前首先要disable表。这是一个非常耗时的操作,所以不建议频繁删除表。

disableTable和deleteTable分别用来disable和delete表。

Example:

HBaseAdmin hAdmin = new HBaseAdmin(hbaseConfig);
if (hAdmin.tableExists(tableName)) {
       hAdmin.disableTable(tableName);
       hAdmin.deleteTable(tableName);
}

查询数据

查询分为单条随机查询和批量查询。

单条查询是通过rowkey在table中查询某一行的数据。HTable提供了get方法来完成单条查询。

批量查询是通过制定一段rowkey的范围来查询。HTable提供了个getScanner方法来完成批量查询。

public Result get(final Get get)

public ResultScanner getScanner(final Scan scan)

Get对象包含了一个Get查询需要的信息。它的构造方法有两种:

  public Get(byte [] row)

  public Get(byte [] row, RowLock rowLock)

Rowlock是为了保证读写的原子性,你可以传递一个已经存在Rowlock,否则HBase会自动生成一个新的rowlock。

Scan对象提供了默认构造函数,一般使用默认构造函数。

Get/Scan的常用方法有:

addFamily/addColumn:指定需要的family或者column,如果没有调用任何addFamily或者Column,会返回所有的columns.

setMaxVersions:指定最大的版本个数。如果不带任何参数调用setMaxVersions,表示取所有的版本。如果不掉用setMaxVersions,只会取到最新的版本。

setTimeRange:指定最大的时间戳和最小的时间戳,只有在此范围内的cell才能被获取。

setTimeStamp:指定时间戳。

setFilter:指定Filter来过滤掉不需要的信息

Scan特有的方法:

setStartRow:指定开始的行。如果不调用,则从表头开始。

setStopRow:指定结束的行(不含此行)。

setBatch:指定最多返回的Cell数目。用于防止一行中有过多的数据,导致OutofMemory错误。

ResultScanner是Result的一个容器,每次调用ResultScanner的next方法,会返回Result.

public Result next() throws IOException;

public Result [] next(int nbRows) throws IOException;

Result代表是一行的数据。常用方法有:

getRow:返回rowkey

raw:返回所有的key value数组。

getValue:按照column来获取cell的值

Example:

Scan s = new Scan();
s.setMaxVersions();
ResultScanner ss = table.getScanner(s);
for(Result r:ss){
    System.out.println(new String(r.getRow()));
    for(KeyValue kv:r.raw()){
       System.out.println(new String(kv.getColumn()));
    }
}

插入数据

HTable通过put方法来插入数据。

public void put(final Put put) throws IOException

public void put(final List<Put> puts) throws IOException

可以传递单个批Put对象或者List put对象来分别实现单条插入和批量插入。

Put提供了3种构造方式:

public Put(byte [] row)

public Put(byte [] row, RowLock rowLock)

public Put(Put putToCopy) 

Put常用的方法有:

add:增加一个Cell

setTimeStamp:指定所有cell默认的timestamp,如果一个Cell没有指定timestamp,就会用到这个值。如果没有调用,HBase会将当前时间作为未指定timestamp的cell的timestamp.

setWriteToWAL: WAL是Write Ahead Log的缩写,指的是HBase在插入操作前是否写Log。默认是打开,关掉会提高性能,但是如果系统出现故障(负责插入的Region Server挂掉),数据可能会丢失。

另外HTable也有两个方法也会影响插入的性能

setAutoFlash: AutoFlush指的是在每次调用HBase的Put操作,是否提交到HBase Server。默认是true,每次会提交。如果此时是单条插入,就会有更多的IO,从而降低性能.

setWriteBufferSize: Write Buffer Size在AutoFlush为false的时候起作用,默认是2MB,也就是当插入数据超过2MB,就会自动提交到Server

Example:
HTable table = new HTable(hbaseConfig, tableName);
table.setAutoFlush(autoFlush);
List<Put> lp = new ArrayList<Put>();
int count = 10000;
byte[] buffer = new byte[1024];
Random r = new Random();
for (int i = 1; i <= count; ++i) {
       Put p = new Put(String.format(“row%09d”,i).getBytes());
       r.nextBytes(buffer);
       p.add(“f1″.getBytes(), null, buffer);
       p.add(“f2″.getBytes(), null, buffer);
       p.add(“f3″.getBytes(), null, buffer);
       p.add(“f4″.getBytes(), null, buffer);
       p.setWriteToWAL(wal);
       lp.add(p);
       if(i%1000==0){
           table.put(lp);
           lp.clear();
       }
    }

删除数据

HTable 通过delete方法来删除数据。

  public void delete(final Delete delete)

 

Delete构造方法有:

public Delete(byte [] row)

public Delete(byte [] row, long timestamp, RowLock rowLock)

public Delete(final Delete d)

Delete常用方法有

deleteFamily/deleteColumns:指定要删除的family或者column的数据。如果不调用任何这样的方法,将会删除整行。

注意:如果某个Cell的timestamp高于当前时间,这个Cell将不会被删除,仍然可以查出来。

Example:

HTable table = new HTable(hbaseConfig, “mytest”);

Delete d = new Delete(“row1″.getBytes());

table.delete(d) 

切分表

HBaseAdmin提供split方法来将table 进行split.

public void split(final String tableNameOrRegionName)

如果提供的tableName,那么会将table所有region进行split ;如果提供的region Name,那么只会split这个region.

由于split是一个异步操作,我们并不能确切的控制region的个数。

Example:
public void split(String tableName,int number,int timeout) throws Exception {
    Configuration HBASE_CONFIG = new Configuration();
    HBASE_CONFIG.set(“hbase.zookeeper.quorum”, GlobalConf.ZOOKEEPER_QUORUM);
    HBASE_CONFIG.set(“hbase.zookeeper.property.clientPort”, GlobalConf.ZOOKEEPER_PORT);
    HBaseConfiguration cfg = new HBaseConfiguration(HBASE_CONFIG);
    HBaseAdmin hAdmin = new HBaseAdmin(cfg);
    HTable hTable = new HTable(cfg,tableName);
    int oldsize = 0;
    t =  System.currentTimeMillis();
    while(true){
       int size = hTable.getRegionsInfo().size();
       logger.info(“the region number=”+size);
       if(size>=number ) break;
       if(size!=oldsize){
           hAdmin.split(hTable.getTableName());
           oldsize = size;
       }
       else if(System.currentTimeMillis()-t>timeout){
           break;
       }
       Thread.sleep(1000*10);
    }
}