Hbase-之Client-scan请求过滤器(request filter)_hbase client scan-程序员宅基地

技术标签: filter  过滤器  java  Hbase  hbase  大数据  

Hbase之Client-scan请求过滤器Filter

0 前言

在Hbase的Client对Hbase的数据进行请求的时候,实际上是可以通过过滤器进行数据的筛选的,Hbase的客户端请求过滤器大致分为5种类,具体详情请参考官方

  • FilterList 【传入过滤器列表,按照MUST_PASS_ONE \MUST_PASS_ALL的规则进行使用】

  • Column Value Filter【为列值维度的过滤,通过特定的value与具体column的值进行匹配】

  • MetaData Filter【为元数据的过滤,可以在扫描之前限定需要扫描的列族、列,避免扫描不需要的数据】

  • RowFilter 【为行过滤器,可以按照rowkey进行匹配】

  • Utility Filter 【为工具型的过滤器,一般用于进行hbase table rowcount操作】

1 FilterList(结构型过滤器)

常用的结构型的过滤器有FilterList,该类的血缘关系如下:

java.lang.Object
	org.apache.hadoop.hbase.filter.Filter
		org.apache.hadoop.hbase.filter.FilterBase
			org.apache.hadoop.hbase.filter.FilterList

FilterList简单使用代码如下:

Connection connection = ConnectionFactory.createConnection();

//创建过滤器列表的实例,可以装在多个实例
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);


//预先准备需要扫描的cf和column-qualifier
byte[] cf = Bytes.toBytes("");
byte[] cq = Bytes.toBytes("");
byte[] value1 = Bytes.toBytes("SuperMan");
byte[] value2 = Bytes.toBytes("BiteMan");


Filter filter1 = TestColumnValueFilter.getSingleColumnValueFilter(cf, cq, value1);
Filter filter2 = TestColumnValueFilter.getSingleColumnValueFilter(cf, cq, value1);

//添加过滤器
filterList.addFilter(filter1);
filterList.addFilter(filter2);

//获取table的实例
Table table = connection.getTable(TableName.valueOf(""));

Scan scan = new Scan();
scan.setFilter(filterList);
scan.setBatch(10000);
ResultScanner scanner = table.getScanner(scan);


//获取scanner中的数据,并进行操作

2 Column Value Filter(列值过滤器)

常用的列值过滤器有ColumnValueFilter,SingleColumnValueFilter,一般列值过滤器还可以配置不同的比较器配合使用;后者作为Hbase2.0.0之后对前者的完善,将row级别的匹配精确到了Cell,2者拥有相同的构造函数,简单的使用单吗如下。

package com.shufang.filter;

import org.apache.hadoop.hbase.CompareOperator;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;


/**
 * 常用的Column-Value相关的过滤器有:
 * @FilterList: 可以用来装在多个过滤器,同时可选择对所有的Filter的配置MUST_PASS_ONE 与 MUST_PASS_ALL之间的过滤规则;
 * @ColumnValueFilter: 返回匹配的Cell,是Hbase在2.0.0的时候对之前版本SingleColumnValueFilter的补充;
 * @SingleColumnValueFilter: 返回匹配到的所有value的所在row的所有数据内容;
 * @ValueFilter: 这个需要在scan的时候预先.addFamily().addColumn(),一般用于简单的查询类似于where$name=name;
 *
 * 一般的列值过滤器都是配合不同的列值比较器进行使用,常用的列值比较器如下。
 * @RegexStringComparator: 正则字符串比较器
 * @SubStringComparator: 子字符串比较器
 * @BinaryPrefixComparator: 二进制前缀比较器
 * @BinaryComparator: 二进制比较器
 * @BinaryComponentComparator: 二进制组建比较器,用特定位置的特定值与Cell进行比较,可以对比ascii和binary数据
 *
 */
public class TestColumnValueFilter {
    


    public static void main(String[] args) throws IOException {
    


        Connection connection = ConnectionFactory.createConnection();

        //创建过滤器列表的实例,可以装在多个实例
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);


        //预先准备需要扫描的cf和column-qualifier
        byte[] cf = Bytes.toBytes("");
        byte[] cq = Bytes.toBytes("");
        byte[] value1 = Bytes.toBytes("SuperMan");
        byte[] value2 = Bytes.toBytes("BiteMan");


        /**
         * 对于简单的过滤条件,如:$value = cf:col:value,这种,官方强烈推荐使用ValueFilter,
         * 而不是
         * @ColumnValueFilter and
         * @SingleColumnValueFilter
         * 实例代码如下
         */
        scan.addColumn(cf,cq); //限定扫描额ColumnFamily和Column,避免扫描无关的列
        scan.setFilter(new ValueFilter(CompareOperator.EQUAL,new BinaryComparator(value1)));



        /**
         * 除了对特定value值的过滤支持,ColumnValueFilter还支持另外一种构造参数的过滤方式。
         * @ColumnValueFilter(
         *                  final byte[] family,
         *                  final byte[] qualifier,
         *                  final CompareOperator op,
         *                  final ByteArrayComparable comparator
         *                  TODO 这个参数是一种value的拓展比较方式,可以使用正则、字符串截取进行匹配
         *                  )
         * @regexStringComparator  正则匹配字符串
         * @substringComparator
         */

        RegexStringComparator regexStringComparator = new RegexStringComparator("my."); //所有以my开头的row
        new SingleColumnValueFilter(cf,cq,CompareOperator.EQUAL,regexStringComparator);

        SubstringComparator substringComparator = new SubstringComparator("y val"); //所有包含y val的row,my value会匹配出来
        new SingleColumnValueFilter(cf,cq,CompareOperator.EQUAL,substringComparator);


    }

    /**
     * @SingleColumnValueFilter :对特定value值的所有row进行等值,不等值,或者范围range的筛选
     * CompareOperator.EQUAL
     * CompareOperator.NOT_EQUAL
     * CompareOperator.GREATER
     * @param cf
     * @param cq
     * @param value
     * @return SingleColumnValueFilter
     */
    public static  Filter getSingleColumnValueFilter(byte[] cf,byte[] cq,byte[] value){
    
        return new SingleColumnValueFilter(cf,cq,CompareOperator.EQUAL,value);
    }


    /**
     * @ColumnValueFilter :在Hbase2.0.0之后,引入了ColumnValueFilter对SingleColumnValueFilter作补充,
     * 仅获取匹配到的value所在的Column的Cell,SingleColumnValueFilter会获取到匹配到的value的所在ROW的所
     * 有数据,包括其它列
     * TODO ColumnValueFilter的构造器参数与SingleColumnValueFilter是保持一致的
     * @param cf
     * @param cq
     * @param value
     * @return ColumnValueFilter
     */
    public static  Filter getColumnValueFilter(byte[] cf,byte[] cq,byte[] value){
    
        return new ColumnValueFilter(cf,cq,CompareOperator.EQUAL,value);

    }

}

3 MetaData Filter(元数据级别过滤器)

Hbase支持在扫描之从原数据层面进行过滤,避免不必要的扫描资源性能消耗,常用的此类过滤器有FamilyFilter,QualifierFilter,ColumnPrefixFilter,MutipleColumnPrefixFilter,ColumnRangeFilter关于这些过滤器的简单使用代码如下。

package com.shufang.filter;


import com.shufang.charactor01.TestHbaseConnection;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

/**
 * Hbase的过滤器除了列值过滤器之外还有MetaData相关的过滤器
 *
 * @FamilyFilter:列族过滤器,但是官方建议还是使用scan.addFamily()的方式比较好;
 * @QualifierFilter:列过滤器,但是官方还是建议使用scan.addColumn()的方式会比较好;
 * @ColumnPrefixFilter:列前缀过滤器,将指定前缀的columnQualifier的所有列进行选定匹配;
 * @MutipleColumnPrefixFilter:可以同时匹配多个前缀对应的所有Column的数据,是对上者的一种补充; 具体可以参考以下实例代码
 * @ColumnRangeFilter:用来从大量列中筛选出所需的列;
 */
public class TestHbaseMetaFilter {
    


    public static void main(String[] args) throws IOException {
    

        //使用工具创建一个Connection对象
        Connection connection = TestHbaseConnection.getConnection(HBaseConfiguration.create());
        //获取Table的实例
        Table table = connection.getTable(TableName.valueOf("test1"));

        byte[] family = Bytes.toBytes("cf");
        byte[] qualifier = Bytes.toBytes("cq");


        //创建scan,配置family和column
        Scan scan = new Scan();
        //scan.addColumn(family, qualifier);
        scan.setFilter(new FamilyFilter(CompareOperator.EQUAL,new BinaryComparator(family))); //设置列族过滤器
        scan.setFilter(new QualifierFilter(CompareOperator.EQUAL,new BinaryComparator(qualifier))); //设置列过滤器


        /**
         * @ColumnPrefixFilter
         */
        ColumnPrefixFilter abc = new ColumnPrefixFilter(Bytes.toBytes("abc"));
        //scan.setFilter(abc);


        /**
         * @MultipleColumnPrefixFilter
         */
        byte[][] prefixs = {
    Bytes.toBytes("abc"),Bytes.toBytes("xyz")};
        MultipleColumnPrefixFilter multipleColumnPrefixFilter = new MultipleColumnPrefixFilter(prefixs);
        scan.setFilter(multipleColumnPrefixFilter);

        /**
         * @ColumnRangeFilter:假如Table有100W个列,我只需要[minColumn,macCloumn)区间的列的数据;
         */
        ColumnRangeFilter columnRangeFilter = new ColumnRangeFilter(Bytes.toBytes("minColumn"),
                true, Bytes.toBytes("maxColumn"), false);
        scan.setFilter(columnRangeFilter);


        /**
         * 然后开始扫描结果,并处理获取到的结果
         */
        ResultScanner rs = table.getScanner(scan);
        for (Result r = rs.next(); r != null; r = rs.next()) {
    
            for (Cell cell : r.rawCells()) {
    
                //每个Cell就代表Column与Row的交接处的一个单元,一个Cell可能有多个Version的value,默认返回最大时间戳的
                byte[] value = CellUtil.cloneValue(cell);
                //现在就可以处理获取到的结果value了
            }
        }

        rs.close(); //释放内存资源

    }

}

4 RowFilter(行级别的过滤)

在早期的Hbase版本,可以使用scan.setStartRow(),scan.setStopRow() 限定范围,但是这些方法在今后的版本都被标示成过期状态,所以目前有一种过滤器的方式来进行过滤。

对于Row级别的Filter,有2种简单的API可供使用scan.setRowPrefixFilter(Bytes.toBytes("prefix_of_rowkey")),还可以使用scan.setFilter(new RowFilter(comparator_oper.EQUAL,new ByteArrayComparator()))的方式进行筛选,简单使用代码如下。

package com.shufang.filter;

import com.shufang.charactor01.TestHbaseConnection;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

/**
 * 通常Hbase对行的过滤,可以通过startRow与stopRow进行过滤(但是在Hbase2.X后续版本中标示为过时),
 * 但是通过RowFilter也是可以进行过滤操作的!
 *
 * @RowFilter
 */
public class TestRowFilter {
    
    public static void main(String[] args) throws IOException {
    

        Connection conn = TestHbaseConnection.getConnection(HBaseConfiguration.create());
        Table table = conn.getTable(TableName.valueOf("test"));


        /**
         * 1、常规的通过scan的原生方法进行过滤
         */
        Scan scan = new Scan();
        //scan.setStartRow()
        //scan.setStopRow()

        /**
         * 2、通过RowFilter进行过滤
         * @RowFilter可以配合@BinaryComponentComparator等比较器进行配合使用,还能扩展过滤功能
         */
        scan.setRowPrefixFilter(Bytes.toBytes("prefix1"));//按照Row的前缀进行过滤匹配
        scan.setFilter(new RowFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("momoji"))));

        ResultScanner scanner = table.getScanner(scan);
        for (Result r = scanner.next(); r != null ; r= scanner.next()) {
    

            Cell[] cells = r.rawCells();

            for (Cell cell : cells) {
    
                //处理cell中的数据
                byte[] value = CellUtil.cloneValue(cell);
                cell.getTimestamp(); //查看Cell对应的版本时间戳。
                //.......
            }
        }

        scanner.close();//释放资源
    }
}

5 Utility Filter(工具型过滤器)

常用的工具型过滤器有FirstKeyOnlyFilter,该过滤器会返回扫描结果的所有row的第一个KV,一般可以用来进行Hbase的rowcount操作,简单代码如下:

package com.shufang.filter;


import com.shufang.charactor01.TestHbaseConnection;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;

import java.io.IOException;

/**
 * Hbase除了列值、row、元数据过滤器之外,还有工具型的过滤器
 *
 * @FirstKeyOnlyFilter:只会返回每行的第一个KV,这里的KV代表一个Cell,在hbase需要进行rowcount的时候很实用
 */
public class TestUtilityFilter {
    
    public static void main(String[] args) throws IOException {
    

        Connection conn = TestHbaseConnection.getConnection(HBaseConfiguration.create());


        Table table = conn.getTable(TableName.valueOf(""));
        ResultScanner rs = null;
        try {
    

            Scan scan = new Scan();
            scan.setFilter(new FirstKeyOnlyFilter());
            rs = table.getScanner(scan);

            //handle the rs with rs.next()
            Long sum = 0l;

            for (Result r = rs.next(); r != null ; r= rs.next()) {
    
                sum+=1;
                
                Cell[] cells = r.rawCells();
                for (Cell cell : cells) {
    
                    //处理cell中的数据
                    byte[] value = CellUtil.cloneValue(cell);
                    cell.getTimestamp(); //查看Cell对应的版本时间戳。
                    //.......
                }
            }

        } catch (IOException e) {
    
            e.printStackTrace();
        } finally {
    
            rs.close();
            table.close();
        }

    }
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shufangreal/article/details/109811702

智能推荐

python实现在 Mac 10.9 远程桌面截屏抓取_mac 监控截屏-程序员宅基地

文章浏览阅读2k次。照样画葫芦,用python编写了一段小程序,可以使用ipad的web浏览器远程监控远端iMac主机界面(每秒截屏,非流控),与大家分享。1. 首先介绍一下需要下载的第三方工具:Flask,PyscreenshotFlask用来做web服务器,Pyscreenshot是用来截屏的。用pip install 分别安装即可2. 介绍程序文件架构如下,需要simplesvr_mac 监控截屏

centos7安装后一直出现pcieport 0000:00:1c.5的解决_dpc:error containment capabilities-程序员宅基地

文章浏览阅读4.7k次,点赞3次,收藏7次。安装完centos7后进入时一直不停出现pcieport 0000:00:1c.5字样,这个的具体原因尚不完全清楚,解决方法查到的都是一种,就是在/etc/default/grub中的GRUB_CMDLINE_LINUX的内容最后添加pci=nomsi或者pci=noaer或者pcie_aspm=off,这样的确可以,但是更新的步骤需要grub2-mkconfig -o /boot/efi/EFI..._dpc:error containment capabilities

目前看到的最好的RNN、LSTM、GRU博客:Understanding LSTM Networks_humans don鈥檛 start their thinking from scratch eve-程序员宅基地

文章浏览阅读735次。原文:http://colah.github.io/posts/2015-08-Understanding-LSTMs/Recurrent Neural NetworksHumans don’t start their thinking from scratch every second. As you read this essay, yo_humans don鈥檛 start their thinking from scratch every second.

maven/conf/settings.xml完整配置(3处)_apache-maven-3.9.2\conf\settings.xml-程序员宅基地

文章浏览阅读1.4k次。<?xml version="1.0" encoding="UTF-8"?><!--Licensed to the Apache Software Foundation (ASF) under oneor more contributor license agreements. See the NOTICE filedistributed with this work for additional informationregarding copyright ownersh._apache-maven-3.9.2\conf\settings.xml

基于Python的逆向工程:ELF文件_逆向工程 python-程序员宅基地

文章浏览阅读6.4k次。当解决复杂的逆向问题时,我们常使用radare2或IDA等成熟工具进行反汇编和调试。但有时也需要深入挖掘并了解它们是如何运作的。编写一些反汇编脚本对于自动化某些流程非常有用,并且可以形成自己的逆向工具链。至少,这是我现在正在尝试的事情。配置环境如标题所说的那样,你需要先安装Python 3。如果你无法确定是否安装了Python 3,可以运行如下命令:其中capstone是..._逆向工程 python

四种方法实现:找出数组中两个只出现一次的数字_一个数组中找出出现一次的2个数字-程序员宅基地

文章浏览阅读2.6k次。//先排序然后查找void FindNumsAppearOnce1(vector&lt;int&gt; data, int* num1, int *num2) { if (data.size() &lt; 2) return; sort(data.begin(), data.end()); vector&lt;int&gt; res; for (int i = 0; i &lt;..._一个数组中找出出现一次的2个数字

随便推点

开箱即用的 WebRTC 开发环境_xujianzhu webrtc开箱即用-程序员宅基地

文章浏览阅读333次。本文是 Piasy 原创,发表于 https://blog.piasy.com,请阅读原文支持原创 https://blog.piasy.com/2017/06/17/out-of-the-box-webrtc-dev-env/在刚刚落幕的 WWDC17 上,苹果为我们带来了一个不小的惊喜 —— 其浏览器内核WebKit将正式支持 WebRTC,而未来基于 WebKit 内核的苹果浏览器,比如m..._xujianzhu webrtc开箱即用

从ResNet101到ResNet50_resnet50 使用什么代替-程序员宅基地

文章浏览阅读3.3w次,点赞5次,收藏21次。一直用VGG训练,几天前想看下ResNet的效果如何,因为SSD源码中有python实现的ResNet网络结构实现代码,包含ResNet101和ResNet152,直接拿ResNet101来训练,GTX1060配置,batchsize竟然只降到2才跑的起来,果然一直收敛不了。看了下model_libs.py里面的实现代码:def ResNet101Body(net, from_layer, u_resnet50 使用什么代替

vivado ILA在线逻辑仪使用_vivado ila 下一触发沿-程序员宅基地

文章浏览阅读1.1w次,点赞12次,收藏131次。目录:1、在线逻辑分析仪简介2、HDL 实例化调试探针流程(实验-闪烁灯)3、Hardware Manager中观察调试信号4、网表插入调试探针流程(实验-闪烁灯)1、在线逻辑分析仪简介在线逻辑分析仪借用了传统逻辑分析仪的理念以及大部分的功能,并利用 FPGA 中的逻辑资源,将这些功能植入到 FPGA 的设计当中。一般地,在线逻辑分析仪的应用原理框图如下图所示:​ 待测设计(Design Under Test,DUT)就是用户逻辑,它和片内的在线逻辑分析仪都位于 FPGA中。在线逻辑分_vivado ila 下一触发沿

数据库索引的使用_db2数据库索引的使用-程序员宅基地

文章浏览阅读3.5k次。今天发现一个问题,问题大概是这样的,查询interface的信息,在本地使用本地的数据库访问没有问题,但是发布到服务器上以后访问速度就特别的忙,需要5分钟左右才能返回数据,这肯定是无法让人接受的,刚开始以为是服务器性能的问题,为了验证就把服务器上的数据库备份到本地,发现本地的速度也马上慢了下来,到底是什么问题的。看了一下查询interface的sql语句不禁吓了一跳: _db2数据库索引的使用

win7下mysql的安装_[root@gaojiao ~]# mysql -uroot error 1045 (28000):-程序员宅基地

文章浏览阅读3.1k次。一 , 当前mysql的最新版本是5.5.25a。到http://dev.mysql.com/downloads/mysql/下载mysql安装文件 。我们这里下载mysql-5.5.25a-win32.msi就可以了,下载完,直接点击安装。mysql有好几个版本,稍微了解下各个版本之间的区别:  MySQL Community Server :社区版本 不提供官方技术支持,是免费的_[root@gaojiao ~]# mysql -uroot error 1045 (28000): access denied for user 'r

PHP微信公众平台开发高级篇--群发接口_微信公众号根据标签群发接口支持数组传参吗-程序员宅基地

文章浏览阅读2.3k次。群发消息接口订阅号:每天一条的群发权限服务号:每月(自然月)4条群发权限实例&lt;?php/** * 群发接口 * PS:群发之前调用“预览接口”进行测试 * PS:通过第三方后台调用微信上传图片素材接口,获取图片url,如:{"url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/BdxWN2kspVgJOFpRHJojlWmbl0pM..._微信公众号根据标签群发接口支持数组传参吗