由于文章内容较多,常需要用到目录索引,友情提示:页面右侧有个快捷展开目录的功能,浏览过程中可以随时查看目录。
key:rowkey:列簇:列名:时间戳
hbase.rootdir
hdfs://oda.com/hbase
hbase.cluster.distributed
true
hbase.tmp.dir
/home/jlu/bd/hbase-0.98.6-cdh5.3.6/hbase/tmp
指定regionserver节点hostname,修改文件regionservers。
创建到hdfs-site.xml的软连接(即在$HADOOP_HOME/etc/hadoop下创建hbase-site.xml的软连接)或者配置连接hdfs的配置信息(推荐)。
启动hbase集群并验证。
**大写的ps.**为防止后期编程,hadoop缺少jar包,建议在hadoop-env.sh上添加如下配置
验证分为四种方式:
create 'users','f'
put 'users', 'row1', 'f:id', '1'
put 'users', 'row1', 'f:name', 'zhangsan'
put 'users', 'row1', 'f:age', 18
put 'users', 'row1', 'f:phone', '021-11111111'
put 'users', 'row1', 'f:email', '[email protected]'
put 'users', 'row2', 'f:id', '2'
put 'users', 'row2', 'f:name', 'lisi'
put 'users', 'row2', 'f:email', '[email protected]'
put 'users', 'row2', 'f:address', 'shanghai'
put 'users', 'row3', 'f:id', '3'
put 'users', 'row3', 'f:name', 'lili'
put 'users', 'row3', 'f:age', 25
put 'users', 'row3', 'f:country', 'china'
put 'users', 'row3', 'f:email', '[email protected]'
put 'users', 'row4', 'f:id', '4'
put 'users', 'row4', 'f:name', 'user4'
put 'users', 'row5', 'f:id', '5'
put 'users', 'row5', 'f:name', 'user5'
put 'users', 'row6', 'f:id', '6'
put 'users', 'row6', 'f:name', 'user6'
put 'users', 'row7', 'f:id', '7'
put 'users', 'row7', 'f:name', 'user7'
put 'users', 'row8', 'f:id', '8'
put 'users', 'row8', 'f:name', 'user8'
put 'users', 'row9', 'f:id', '9'
put 'users', 'row9', 'f:name', 'user9'
put 'users', 'row10', 'f:id', '10'
put 'users', 'row10', 'f:name', 'user10'
scan提供多种filter命令,常用filter命令如下:ColumnPrefixFilter,MultipleColumnPrefixFilter,RowFilter,SingleColumnValueFilter,SingleColumnValueExcludeFilter等。
需要注意的是:在指定的value之前需要加’binary:’,比如:scan ‘users’,{FILTER=>“SingleColumnValueFilter(‘f’,‘id’,=,'binary:1)”}
SingleColumnValueFilter最常用,需要的参数也比较多,图中,因为id存的是字符串类型,所以按字典序比较过滤
Java客户端其实就是shell客户端的一种实现,操作命令基本上就是shell客户端命令的一个映射。Java客户端使用的配置信息是被映射到一个HBaseConfiguration的实例对象中的,当使用该类的create方法创建实例对象的时候,会从classpath路径下获取hbase-site.xml文件并进行配置文件内容的读取,同时会读取hadoop的配置文件信息。也可以通过java代码指定命令信息,只需要给定zk的相关环境变量信息即可。代码如下:
Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "hh1,hh2.."); // 第二个参数是主机名
HBaseAdmin类是主要进行DDL操作相关的一个接口类,主要包括命名空间管理,用户表管理。通过该接口我们可以创建、删除、获取用户表,也可以进行用户表的分割、紧缩等操作。
HTable是hbase中的用户表的一个映射的java实例,我们可以通过该类进行表数据的操作,包括数据的增删查改,也就是在这里我们可以类似shell中put,get和scan进行数据的操作。
HTableDescriptor是hbase用户表的具体描述信息类,一般我们创建表获取获取(给定)表信息,就是通过该类进行的。
在web应用中,如果我们之间使用HTable来操作hbase,那么在创建连接和关闭连接的时候,一定会浪费资源。那么HBase提供了一个连接池的基础,主要涉及到的类和接口包括:HConnection,HConnectionManager,HTableInterface,ExecutorService四个。
package com.jluzh.oda.hbase.test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HConnectionManager;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.FilterList.Operator;
import org.apache.hadoop.hbase.filter.MultipleColumnPrefixFilter;
import org.apache.hadoop.hbase.util.Bytes;
import com.jluzh.oda.hbase.util.HBaseUtil;
public class TestHTable {
static byte[] family = Bytes.toBytes("f");
public static void main(String[] args) {
Configuration conf = HBaseUtil.getHBaseConfiguration();
try {
// testUseHTable(conf);
testUseHbaseConnectionPool(conf);
} catch (IOException e) {
e.printStackTrace();
}
}
// 集中调用测试方法
static void testUseHTable(Configuration conf) throws IOException {
HTable hTable = new HTable(conf, "users");
try {
// testPut(hTable);
// testGet(hTable);
// testDelete(hTable);
testScan(hTable); // 参数是实现了接口的类实例
} finally {
hTable.close();
}
}
// 最好还是使用线程池
static void testUseHbaseConnectionPool(Configuration conf) throws IOException {
ExecutorService threads = Executors.newFixedThreadPool(10); // 10个线程
HConnection pool = HConnectionManager.createConnection(conf, threads);
HTableInterface hTable = pool.getTable("users");
try {
// testPut(hTable); // 参数是实现了接口的类实例
// testGet(hTable);
// testDelete(hTable);
testScan(hTable);
} finally {
hTable.close(); // 每次htable操作完 关闭 其实是放到pool中
pool.close(); // 最终的时候关闭
}
}
/**
* 测试scan
*
* @param hTable;接口
* @throws IOException
*/
static void testScan(HTableInterface hTable) throws IOException{
Scan scan = new Scan();
// 增加起始row key
scan.setStartRow(Bytes.toBytes("row1"));
scan.setStopRow(Bytes.toBytes("row5"));
// 使用指定布尔运算符求值的筛选器的有序列表
FilterList list = new FilterList(Operator.MUST_PASS_ALL); // 相当于AND
byte[][] prefixes = new byte[2][]; // 过滤前缀
prefixes[0] = Bytes.toBytes("id");
prefixes[1] = Bytes.toBytes("name");
// 创建多重列前缀过滤器实例
MultipleColumnPrefixFilter mcpf = new MultipleColumnPrefixFilter(prefixes);
list.addFilter(mcpf); // 添加过滤器
scan.setFilter(list); // scan操作设置过滤器
// Returns a scanner on the current table as specified
// by the {@link Scan} object.
ResultScanner rs = hTable.getScanner(scan);
Iterator iter = rs.iterator();
while (iter.hasNext()) {
// Single row result of a {@link Get} or {@link Scan} query.
Result result = iter.next();
printResult(result);
}
}
/**
* 打印result对象
*
* @param result
*/
static void printResult(Result result) {
System.out.println("*********************" + Bytes.toString(result.getRow())); // 获取rowkey
//
// getMap(): 将族映射到其限定符和值的所有版本。
NavigableMap>> map = result.getMap();
// 遍历map
for (Map.Entry>> entry : map.entrySet()) {
String family = Bytes.toString(entry.getKey()); // 获取family
for (Map.Entry> columnEntry : entry.getValue().entrySet()) {
String column = Bytes.toString(columnEntry.getKey()); // 获取column
String value = "";
if ("age".equals(column)) {
value = "" + Bytes.toInt(columnEntry.getValue().firstEntry().getValue());
} else {
value = Bytes.toString(columnEntry.getValue().firstEntry().getValue());
}
System.out.println(family + ":" + column + ":" + value);
}
}
}
/**
* 测试put操作
*
* @param hTable
* @throws IOException
*/
static void testPut(HTableInterface hTable) throws IOException {
// 单个put
Put put = new Put(Bytes.toBytes("row1"));
put.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("11"));
put.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("zhangsan"));
put.add(Bytes.toBytes("f"), Bytes.toBytes("age"), Bytes.toBytes(27));
put.add(Bytes.toBytes("f"), Bytes.toBytes("phone"), Bytes.toBytes("021-11111111"));
put.add(Bytes.toBytes("f"), Bytes.toBytes("email"), Bytes.toBytes("[email protected]"));
hTable.put(put); // 执行put
// 同时put多个
Put put1 = new Put(Bytes.toBytes("row2"));
put1.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("2"));
put1.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("user2"));
Put put2 = new Put(Bytes.toBytes("row3"));
put2.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("3"));
put2.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("user3"));
Put put3 = new Put(Bytes.toBytes("row4"));
put3.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("4"));
put3.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("user4"));
List list = new ArrayList();
list.add(put1);
list.add(put2);
list.add(put3);
hTable.put(list); // 执行多个put
// 检测put,条件成功就插入,要求rowkey是一样的。
Put put4 = new Put(Bytes.toBytes("row5"));
put4.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("7"));
hTable.checkAndPut(Bytes.toBytes("row5"), Bytes.toBytes("f"), Bytes.toBytes("id"), null, put4);
System.out.println("插入成功");
}
/**
* 测试get命令
*
* @param hTable
* @throws IOException
*/
static void testGet(HTableInterface hTable) throws IOException {
// Create a Get operation for the specified row.
Get get = new Get(Bytes.toBytes("row1"));
// Single row result of a {@link Get} or {@link Scan} query.
Result result = hTable.get(get); // 执行get
// Get the latest version of the specified column.
byte[] buf = result.getValue(family, Bytes.toBytes("id")); // 获取id
System.out.println("id:" + Bytes.toString(buf));
buf = result.getValue(family, Bytes.toBytes("age")); // 获取age
System.out.println("age:" + Bytes.toInt(buf));
buf = result.getValue(family, Bytes.toBytes("name"));
System.out.println("name:" + Bytes.toString(buf));
buf = result.getRow();
System.out.println("row:" + Bytes.toString(buf));
}
/**
* 测试delete
*
* @param hTable
* @throws IOException
*/
static void testDelete(HTableInterface hTable) throws IOException {
// Create a Delete operation for the specified row.
Delete delete = new Delete(Bytes.toBytes("row3"));
// 删除列
delete = delete.deleteColumn(family, Bytes.toBytes("id"));
// 直接删除family
// delete.deleteFamily(family);
hTable.delete(delete); // 删除rowkey(Delete delete = new Delete(Bytes.toBytes("row3"));)
System.out.println("删除成功");
}
}