201707121000复习-hbase篇-api使用篇
一、api分为admin api ,可以创建库,创建表等。还有client api,只可以增删改查表里面的数据,只有在client api里才会用到过滤器
package com.practice.practice2_hbase; import java.io.IOException; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.HTable; 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.client.Table; import org.apache.hadoop.hbase.filter.BinaryComparator; import org.apache.hadoop.hbase.filter.CompareFilter; import org.apache.hadoop.hbase.filter.FilterList; import org.apache.hadoop.hbase.filter.RowFilter; import org.apache.hadoop.hbase.util.Bytes; import org.junit.Before; import org.junit.Test; /** * hbase测试 */ public class AppTest { Connection conn; // 获取一张表,对表中记录进行增删改查 Admin admin; // 对表本身进行增删改查 /** * 获取连接和管理员 * 通过连接可以获取一张表,然后对表中记录进行增删改查 * 通过管理员可以对表或者库进行增删改查 */ @Before public void getConn() { try { // 通过连接获取table对象,可以进行相应查询 conn = ConnectionFactory.createConnection(HBaseConfiguration.create()); // 通过连接获取admin对象,可以进行相应增加或修改等 admin = conn.getAdmin(); } catch (IOException e) { e.printStackTrace(); } } /** * 表的增删改查--增 * * @throws Exception */ @Test public void createTable() throws Exception { // 用管理员来创建表:指定表名 HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf("ns1:test1")); // 创建两个列族 HColumnDescriptor cf1 = new HColumnDescriptor("cf1"); HColumnDescriptor cf2 = new HColumnDescriptor("cf2"); // 添加两个列族 hTableDescriptor.addFamily(cf1); hTableDescriptor.addFamily(cf2); // 效果: crate 'ns1:test1',{NAME=>'cf1'},{NAME=>'cf2'} 或者 // create 'ns1:test1','cf1','cf2' admin.createTable(hTableDescriptor); admin.close(); } /** * 表的增删改查--删 * * @throws Exception */ @Test public void dropTable() throws Exception { admin.disableTable(TableName.valueOf("nst1:test1")); admin.deleteTable(TableName.valueOf("ns1:test1")); admin.close(); } /** * 表的增删改查--改 * * @throws Exception */ @Test public void alterTable() throws Exception { // 要想修改表就必须先禁用表,禁用表之后,就不能使用conn.getTable()方法来得到表了,因为已经得不到了。表的相关信息都是用admin然后指定表名得到的。 admin.disableTable(TableName.valueOf("ns1:test1")); // 改1:增加一个新的列族cf3 HTableDescriptor nowTableDesc = admin.getTableDescriptor(TableName.valueOf("ns1:test1")); nowTableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes("cf3"))); admin.modifyTable(TableName.valueOf("ns1:test1"), nowTableDesc); // 改2:修改列族cf3下列的保存版本数量 HColumnDescriptor cf3 = admin.getTableDescriptor(TableName.valueOf("ns1:test1")) .getFamily(Bytes.toBytes("cf3")); cf3.setVersions(1, 5); admin.modifyColumn(TableName.valueOf("ns1:test1"), cf3); admin.enableTable(TableName.valueOf("ns1:test1")); // 改3:删除一个列族cf3 nowTableDesc = admin.getTableDescriptor(TableName.valueOf("ns1:test1")); cf3 = nowTableDesc.getFamily(Bytes.toBytes("cf3")); System.out.println("最小版本:" + cf3.getMinVersions() + "\t最大版本:" + cf3.getMaxVersions()); nowTableDesc.removeFamily(Bytes.toBytes("cf3")); admin.modifyTable(TableName.valueOf("ns1:test1"), nowTableDesc); admin.enableTable(TableName.valueOf("ns1:test1")); } /** * 表的增删改查--查 * * @throws Exception */ @Test public void listTable() throws Exception { TableName[] listTableNames = admin.listTableNames(); for (TableName table : listTableNames) { System.out.println(Bytes.toString(table.getName())); } } /** * 数据的增删盖改查 -- 增和改 * * @throws Exception */ @Test public void insertData() throws Exception { HTable table = (HTable) (conn.getTable(TableName.valueOf("ns1:test1"))); // 开启缓存插入 table.setAutoFlush(false, true); // 循环生成put Put put = null; for (int i = 10000; i < 20000; i++) { put = new Put(Bytes.toBytes(i + "")); put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("age"), Bytes.toBytes(i + "")); put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("name"), Bytes.toBytes("tom" + i)); put.addColumn(Bytes.toBytes("cf2"), Bytes.toBytes("age"), Bytes.toBytes(i + "")); put.addColumn(Bytes.toBytes("cf2"), Bytes.toBytes("name"), Bytes.toBytes("tomas" + i)); table.put(put); } // 有一些会保留在缓存中,程序结束前,先刷新缓存 table.flushCommits(); table.close(); } /** * 数据的增删改查 -- 查 -- 用scan查,且查指定startkey到endkey的数据内容,且带缓冲地查,且指定过滤器 * * @throws Exception * */ @Test public void getDataWithScan() throws Exception { Table table = conn.getTable(TableName.valueOf("ns1:test1")); // 定制扫描器 Scan scan = new Scan(Bytes.toBytes("12345"), Bytes.toBytes("13456")); // 定制过滤器:需要传入比较的操作符,和比较器 RowFilter rowFilter1 = new RowFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL, new BinaryComparator(Bytes.toBytes("13000"))); RowFilter rowFilter2 = new RowFilter(CompareFilter.CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes("13400"))); // 把过滤器传递给扫描器:在扫描过程中过滤 scan.setFilter(new FilterList(rowFilter1, rowFilter2)); // 开启缓存查询,如果不设置这个值,那么默认值就是-1,即不缓存,等到遍历的时候,每次next()都会出发rpc,都会去regionserver上请求数据 // 设置为非-1的值即开启缓存,并每次缓存指定值的行数。较少了网络传输,但是会增加内存压力。需要平衡考虑。 scan.setCaching(100); // 开始扫描 String row = null; Cell cell = null; ResultScanner scanner = table.getScanner(scan); for (Result res : scanner) { row = Bytes.toString(res.getRow()); cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("age")); System.out.print(row + "\t" + "cf1:age=" + Bytes.toInt(cell.getValueArray()) + "\t"); cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("name")); System.out.print(row + "\t" + "cf1:name=" + Bytes.toString(cell.getValueArray()) + "\t"); cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("age")); System.out.print(row + "\t" + "cf2:age=" + Bytes.toInt(cell.getValueArray()) + "\t"); cell = res.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("name")); System.out.println(row + "\t" + "cf2:name=" + Bytes.toString(cell.getValueArray()) + "\t"); } table.close(); } /** * 数据的增删盖改查 -- 查 -- 用get查指定的一行 * * @throws Exception * */ @Test public void getDataWithGet() throws Exception { Table table = conn.getTable(TableName.valueOf("ns1:test1")); // 定制扫描器 Get get = new Get(Bytes.toBytes("13002")); Result result = table.get(get); Cell cell = result.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("age")); System.out.print(Bytes.toString(CellUtil.cloneValue(cell)) + "\t"); cell = result.getColumnLatestCell(Bytes.toBytes("cf1"), Bytes.toBytes("name")); System.out.print(Bytes.toString(CellUtil.cloneValue(cell)) + "\t"); cell = result.getColumnLatestCell(Bytes.toBytes("cf2"), Bytes.toBytes("age")); System.out.print(Bytes.toString(CellUtil.cloneValue(cell)) + "\t"); cell = result.getColumnLatestCell(Bytes.toBytes("cf2"), Bytes.toBytes("name")); System.out.println(Bytes.toString(CellUtil.cloneValue(cell)) + "\t"); table.close(); } /** * 数据的增删盖改查 -- 删 * * @throws Exception * */ @Test public void deletaData() throws Exception { Table table = conn.getTable(TableName.valueOf("ns1:test1")); Delete del = new Delete(Bytes.toBytes("13000")); del.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("age")); del.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("name")); table.delete(del); table.close(); } /** * 测试复杂过滤器 where ((name like 't%') and (age > 20)) or ((name like '%t') and * (age < 20)) * * @throws Exception */ @Test public void complexFilter() throws Exception { HTable table = (HTable) conn.getTable(TableName.valueOf("ns1:test1")); // 生成多个过滤器,然后拼装, Q:能不能再hbase shell中使用过滤器? Scan scan = new Scan(); ResultScanner scanner = table.getScanner(scan); for (Result res : scanner) { System.out.println(res); } } }
二、过滤器
1、接口及一些常用过滤器类,
2、自定义过滤器
package com.practice.practice2_hbase; import java.io.IOException; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.filter.FilterBase; public class MyFilter extends FilterBase { @Override public ReturnCode filterKeyValue(Cell v) throws IOException { /** * 输入一个Cell,从cell中得到它的value,然后判断是否过滤掉,然后返回值有一下几种 * return ReturnCode.INCLUDE; * return ReturnCode.INCLUDE_AND_NEXT_COL; * return ReturnCode.NEXT_COL; * return ReturnCode.NEXT_ROW; * return ReturnCode.SEEK_NEXT_USING_HINT; * return ReturnCode.SKIP; */ byte[] valueArray = v.getValueArray(); String value = new String(valueArray); if(value.equals("hello")){ return ReturnCode.INCLUDE; }else { return ReturnCode.SKIP; } } }
我也不知道这里写些什么东西好