hbase中分页过滤器详细解析

来源:互联网 发布:caddy windows 编辑:程序博客网 时间:2024/05/17 22:46

分页过滤器:对habse中的数据,按照所设置的一页的行数,进行分页。

前提:

首先我们要先了解数据在hbase中的存储格式,数据是以十六进制的格式存储在hbase中的。还有个我们需要知道的就是在hbase中,各行是按照什么标准进行排序的?在hbase根据各行之间通过行键按照字典序进行排序的,字典序就是如果是字母则对应其在字母表中的顺序进行排序,比如a(在1号位)就大于在3号位的c;1<10<2<20<200<3,先比较第一位,再比较二号位依次类推;具有相同前缀,短的小(400>4)。最后我们要了解分页过滤的机制,通过分页过滤,它会保证每页会存在所设置的行数(我们假设为3),也就是说如果把首行设置为一个不存在的行键也没关系,这样就会将该行键后的3行放到页中,而如果首行存在,这时就会将首行和该行后面的两行放到一页中。

设计思路:

第一页比较好做,因为我们知道第一行的第一个行键(就是表的第一行的行键),然后我们根据设置的一页的行数,就可以做出第一页。
第二页和后面的页就没这么好做了,因为我们不知道这些页的首行行键是什么,因为在hbase中各行的行键并没有规律,这时我们就需要些小技巧,对上一页的最后一个行键后面加个’0’,这样hbase会自动将加’0’的行键当作上一页最后一行的下一行的行键,再加上上面前提中的最后一条,我们就可以完成,对非第一页的分页了,是不是很巧妙?

样例所用的表:

这里写图片描述

代码实现:

public class HighLevelApi {    Connection conn;    @Before    public void init() {        //配置参数信息        Configuration conf = new Configuration();        conf.set("hbase.zookeeper.quorum", "oracle");        conf.set("hbase.rootdir", "hdfs://oracle:9000/hbase");        //建立链接,这里需要注意的是我已经在电脑中的host文件添加了集群的主机名对应的IP        //若没有添加,"oralce"的位置还是应该写成IP地址        try {            conn = ConnectionFactory.createConnection(conf);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }     @After    public void close() {        try {            conn.close();//关闭链接        } catch (IOException e) {            e.printStackTrace();        }    }    @Test//分页过滤器,按行输出比如说有五行,pageSize=3,就会输出两页    public void testPageFilter(){        Table table;        try {            table = conn.getTable(TableName.valueOf("school"));            byte[] POSTFIX = new byte[] { 0x00 };//长度为零的字节数组            Filter filter = new PageFilter(3);//设置一页所含的行数            //我们要了解分页过滤的机制            //通过分页过滤,它会保证每页会存在所设置的行数(我们假设为3),也就是说如果把首行设置为一个不存在的行键也没关系            //这样就会将该行键后的3行放到页中,而如果首行存在,这时就会将首行和该行后面的两行放到一页中            int totalRows = 0;//总行数            byte[] lastRow = null;//该页的最后一行            while (true) {                Scan scan = new Scan();                scan.setFilter(filter);                //如果不是第一页                if (lastRow != null) {                    // 因为不是第一页,所以我们需要设置其实位置,我们在上一页最后一个行键后面加了一个零,来充当上一页最后一个行键的下一个                    byte[] startRow = Bytes.add(lastRow, POSTFIX);                    System.out.println("start row: "                            + Bytes.toStringBinary(startRow));                    scan.setStartRow(startRow);                }                   ResultScanner scanner = table.getScanner(scan);                int localRows = 0;                Result result;                while ((result = scanner.next()) != null) {                    System.out.println(localRows++ + ": " + result);                    totalRows++;                    lastRow = result.getRow();//获取最后一行的行键                }                scanner.close();                //最后一页,查询结束                if (localRows == 0)                    break;            }            System.out.println("total rows: " + totalRows);            table.close();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

输出结果:

这里写图片描述

原创粉丝点击