精华内容
下载资源
问答
  • Shiro中常见过滤器
    千次阅读
    2020-07-30 16:44:41

    Shiro提供多个默认的过滤器,我们可以用这些过滤器来配置控制指定URL的权限,Shiro常见的过滤器如下:

    配置缩写对应的过滤器功能
    身份验证相关的
    anonAnonymousFilter指定url可以匿名访问
    authcFormAuthenticationFilter基于表单的拦截器;如“/**=authc”,如果没有登录会跳到相应的登录页面登录;主要属性:usernameParam:表单提交的用户名参数名( username); passwordParam:表单提交的密码参数名(password); rememberMeParam:表单提交的密码参数名(rememberMe); loginUrl:登录页面地址(/login.jsp);successUrl:登录成功后的默认重定向地址; failureKeyAttribute:登录失败后错误信息存储key(shiroLoginFailure)
    authcBasicBasicHttpAuthenticationFilterBasic HTTP身份验证拦截器,主要属性: applicationName:弹出登录框显示的信息(application)
    logoutauthc.LogoutFilter退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址(/)
    userUserFilter用户拦截器,用户已经身份验证/记住我登录的都可
    授权相关的
    rolesRolesAuthorizationFilter角色授权拦截器,验证用户是否拥有所有角色;主要属性: loginUrl:登录页面地址(/login.jsp);unauthorizedUrl:未授权后重定向的地址;示例“/admin/**=roles[admin]”
    permsPermissionsAuthorizationFilter权限授权拦截器,验证用户是否拥有所有权限;属性和roles一样;示例“/user/**=perms[“user:create”]”
    portPortFilter端口拦截器,主要属性:port(80):可以通过的端口;示例“/test= port[80]”,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样
    restHttpMethodPermissionFilterrest风格拦截器,自动根据请求方法构建权限字符串(GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)构建权限字符串;示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll)
    sslSslFilterSSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口(443);其他和port拦截器一样
    noSessionCreationNoSessionCreationAuthorizationFilter需要指定权限才能访问
    更多相关内容
  • Hbase中常见几种过滤器的使用方法

    千次阅读 2019-05-12 19:58:33
    过滤器种类: 列植过滤器—SingleColumnValueFilter 过滤列植的相等、不等、范围等 列名前缀过滤器—ColumnPrefixFilter 过滤指定前缀的列名 多个列名前缀过滤器—MultipleColumnPrefixFilter 过滤多个指定...

    过滤器的种类:

    列植过滤器—SingleColumnValueFilter

          过滤列植的相等、不等、范围等

    列名前缀过滤器—ColumnPrefixFilter

          过滤指定前缀的列名

    多个列名前缀过滤器—MultipleColumnPrefixFilter

           过滤多个指定前缀的列名

    rowKey过滤器—RowFilter

          通过正则,过滤rowKey值。

    package com.ycit.hbase.test;
    
    import java.io.IOException;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.TableName;
    import org.apache.hadoop.hbase.client.Connection;
    import org.apache.hadoop.hbase.client.ConnectionFactory;
    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.ColumnPrefixFilter;
    import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
    import org.apache.hadoop.hbase.filter.FilterList;
    import org.apache.hadoop.hbase.filter.FilterList.Operator;
    import org.apache.hadoop.hbase.filter.RegexStringComparator;
    import org.apache.hadoop.hbase.filter.RowFilter;
    import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
    import org.apache.hadoop.hbase.util.Bytes;
    import org.jruby.compiler.ir.operands.Operand;
    import org.junit.Before;
    import org.junit.Test;
    
    /**
     * @author 江鹏飞 Hbase的几种过滤器
     */
    public class HbaseFilter {
    	/**
    	 * 全表扫描的过滤器 列值过滤器
    	 */
    	static Configuration config = null;
    	private Connection connection = null;
    	private Table table = null;
    
    	// 配置连接信息
    	@Before
    	public void init() throws Exception {
    		// 创建连接
    		config = HBaseConfiguration.create();
    		config.set("hbase.zookeeper.quorum", "mini1,mini2,mini3");// zookeeper地址
    		config.set("hbase.zookeeper.property.clientPort", "2181");// zookeeper端口
    		connection = ConnectionFactory.createConnection(config);
    		table = connection.getTable(TableName.valueOf("user"));
    	}
    
    	/**
    	 * 列值过滤器
    	 * 
    	 * @throws IOException
    	 */
    	@Test
    	public void scanDataByFilterClo() throws IOException {
    		// 创建全表扫描
    		Scan scan = new Scan();
    		// 过滤器:列值过滤器
    		SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("info1"), Bytes.toBytes("age"),
    				CompareOp.EQUAL, Bytes.toBytes("21"));
    		scan.setFilter(filter);
    		ResultScanner scanner = table.getScanner(scan);
    		for (Result result : scanner) {
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("age"))));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("airen"))));
    		}
    	}
    
    	/**
    	 * RowKey过滤器
    	 * 
    	 * @throws IOException
    	 */
    	@Test
    	public void scanDataByFilterRowKey() throws IOException {
    		// 创建全表扫描
    		Scan scan = new Scan();
    		// 过滤器:RowKey 过滤器
    		RowFilter filter = new RowFilter(CompareOp.EQUAL, new RegexStringComparator("^w"));
    
    		scan.setFilter(filter);
    		ResultScanner scanner = table.getScanner(scan);
    		for (Result result : scanner) {
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("age"))));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("airen"))));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("Address"))));
    
    		}
    	}
    
    	/**
    	 * 匹配列名前缀过滤器
    	 * 
    	 * @throws IOException
    	 */
    	@Test
    	public void scanDataByFilterPrefix() throws IOException {
    		// 创建全表扫描
    		Scan scan = new Scan();
    		// 过滤器:PrefixFilter 过滤器
    		ColumnPrefixFilter PrefixFilter = new ColumnPrefixFilter(Bytes.toBytes("a"));
    		scan.setFilter(PrefixFilter);
    		ResultScanner scanner = table.getScanner(scan);
    		for (Result result : scanner) {
    			System.out.println(Bytes.toString(result.getRow()));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("age"))));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("airen"))));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("Address"))));
    			System.out.println("============================");
    		}
    	}
    
    	/**
    	 * 过滤器集合
    	 * 
    	 * @throws IOException
    	 */
    	@Test
    	public void scanDataByFilterList() throws IOException {
    		Scan scan = new Scan();
    		// 定义过滤器集合
    		FilterList filterList = new FilterList(Operator.MUST_PASS_ALL);// Operator.MUST_PASS_ALL
    																		// 相当于逻辑关系中的
    																		// 且
    		// 过滤器:RowKey 过滤器 //Operator.MUST_PASS_ONE 相当于逻辑关系中的 或
    		RowFilter filterRow = new RowFilter(CompareOp.EQUAL, new RegexStringComparator("^jiang"));
    		// 过滤器:列值过滤器
    		SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("info1"), Bytes.toBytes("age"),
    				CompareOp.EQUAL, Bytes.toBytes("21"));
    		filterList.addFilter(filter);
    		filterList.addFilter(filterRow);
    		// 为scan添加过滤器
    		scan.setFilter(filterList);
    		ResultScanner scanner = table.getScanner(scan);
    		for (Result result : scanner) {
    			System.out.println(Bytes.toString(result.getRow()));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("age"))));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("airen"))));
    			System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("info1"), Bytes.toBytes("Address"))));
    			System.out.println("============================");
    		}
    
    	}
    }
    

     

    展开全文
  • Wireshark捕获过滤器和显示过滤器

    千次阅读 2019-12-17 21:19:26
    wireshark中非常实用的捕获过滤器以及显示过滤器的使用技巧

    wireshark过滤器分为两种,显示过滤器和捕获过滤器。显示过滤器指的是针对已经捕获的报文,使用过滤器语法过滤出符合规则的报文。捕获过滤器指的是提前设置好过滤规则,只捕获符合过滤规则的报文。显示过滤器和捕获过滤器在报文分析的过程中经常使用到,因此非常的实用。往往初次接触wireshark,可能会分不清这两种过滤规则,本文就先简单介绍一下这两种过滤器。

    为什么wireshark使用两套过滤器规则呢?原因在于wireshark使用winpcap或者libpcap第三方的报文捕获库来对网卡的报文进行捕获,事实上其他很多软件都有使用libpcap进行报文捕获。因此捕获过滤器就沿用了这些第三方库提供的捕获过滤规则。但是对于已经捕获报文的解析和处理,wireshark本身构建了一套新的过滤规则,即显示过滤器,要更加的复杂和强大。

    为什么要使用捕获过滤器呢?因为在有些场景下,网卡上的流量可能很大,每秒几个G很甚至更多。而很多的流量并不是我们关心的数据,这个时候就需要使用捕获过滤器捕获指定的数据。无用的数据一方面会干扰分析,另一方面浪费存储空间以及拷贝时间。

    图1就是wireshark捕获->选项中设置捕获过滤器的地方:
    在这里插入图片描述
    图1
    我在图中设置了主机的IP地址以及端口两个过滤规则,表示捕获地址为192.168.0.115同时端口为53的报文,从直观上来说是很容易理解的,我在此

    展开全文
  • Redis 布隆过滤器总结

    千次阅读 2022-01-24 19:51:06
    前言:开发中,经常让我们判断一个集合中是否存在某个数的case;大多数情况下,只需要用map或是list这样简单的数据结构。但是在高并发环境下,所有的case都会极端化,如果这是一个十分庞大的集合(给这个庞大一个...

    前言: 开发中,经常有让我们判断一个集合中是否存在某个数的case;大多数情况下,只需要用map或是list这样简单的数据结构。但是在高并发环境下,所有的case都会极端化,如果这是一个十分庞大的集合(给这个庞大一个具体的值吧,一个亿),简单的一个HashMap,不考虑链表所需的指针内存空间,一亿个int类型的整数,就需要380多M(4byte × 10 ^8),十亿的话就是4个G,不考虑性能,光算算这内存开销,即使现在满地都是128G的服务器,也不好吃下这一壶。

    在海量数据面前,需要高效的去重数据结构布隆过滤器。布隆过滤器有着很棒的性能,也有着很广泛的应用场景,比如垃圾邮件的过滤,缓存击穿等。


    一、为什么会出现布隆过滤器?

    1.1、抖音推送去重

    (1)问题描述

    抖音你有刷到过重复的推荐内容吗?这么多的推荐内容要推荐给这么多的用户,它是怎么保证每个 用户在看推荐内容时,保证不会出现之前已经看过的推荐视频呢?也就是说,抖音是如何实现 推送去重 的呢?

    (2)解决方案

    你会想到服务器记录了用户看过的所有历史记录,当推荐系统推荐短视频时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。问题是当用户量很大,每个用户看过的短视频又很多的情况下,这种方式,推荐系统的去重工作在性能上跟的上么

    实际上,如果历史记录存储在关系数据库里,去重就需要频繁地对数据库进行 exists 查询,当系统并发量很高时,数据库是很难抗住压力的。你可能又想到了Redis缓存,但是这么多用户这么多的历史记录,如果全部缓存起来,那得需要浪费多大的内存空间啊,并且这个存储空间会随着时间呈线性增长,服务器撑不住啊?不缓存性能又跟不上,咋办呢?

     布隆过滤器(Bloom Filter) 就是这样一种专门用来判断是否存在解决去重问题的高级数据结构。它能在解决去重的同时,在空间上能节省 90% 以上。

    1.2、用户登录和签到

    在移动应用的业务场景中,我们需要保存这样的信息:一个 key 关联了一个数据集合。

    常见的场景如下:

    • 给一个 userId ,判断用户登陆状态;

    • 显示用户某个月的签到次数和首次签到时间;

    • 两亿用户最近 7 天的签到情况,统计 7 天内连续签到的用户总数;

    通常情况下,我们面临的用户数量以及访问量都是巨大的,比如百万、千万级别的用户数量,或者千万级别、甚至亿级别的访问信息。所以,我们必须要选择能够非常高效地统计大量数据(例如亿级)的集合类型。

    如何选择合适的数据集合,我们首先要了解常用的统计模式,并运用合理的数据类型来解决实际问题。

    四种统计类型:

    1. 二值状态统计;

    2. 聚合统计;

    3. 排序统计;

    4. 基数统计。

    本文将介绍二值状态统计类型,会用到 String、Set、Zset、List、hash 以外的拓展数据类型 Bitmap 和布隆过滤器来实现。

    也就是集合中的元素的值只有 0 和 1 两种,在签到打卡和用户是否登陆的场景中,只需记录签到(1)或 未签到(0)已登录(1)未登陆(0)

    假如我们在判断用户是否登陆的场景中使用 Redis 的 String 类型实现(key -> userId,value -> 0 表示下线,1 - 登陆),假如存储 100 万个用户的登陆状态,如果以字符串的形式存储,就需要存储 100 万个字符串了,内存开销太大。可以使用高级数据结构bitmap或者布隆过滤器实现。


    二、布隆过滤器简介

    2.1、布隆过滤器是什么?

    布隆过滤器(Boolm Filter)是1970年由布隆提出的一种算法。实际上是一个很长的二进制向量和一系列随机映射哈希函数。其实就是一种数据结构,类似于Hash、Set,主要用于检索一个元素是否在一个集合中。当布隆过滤器说某个值存在时,这个值 可能不存在;当它说不存在时,那么一定不存在。你也可以把它简单理解为一个不怎么精确的 set 结构,当你使用它的 contains 方法判断某个对象是否存在时,它可能会误判。但是布隆过滤器也不是特别不精确,只要参数设置的合理,它的精确度可以控制的相对足够精确,只会有小小的误判概率。

    在编程中,我们想要判断一个元素是不是在一个集合中,一般会想到将所有元素保存起来,然后比较确定。链表、树等数据结构都是这种思路。但是,随着集合中元素的增加,需要的存储空间越来越大,检索的速度也就越来越慢了。

    布隆过滤器相对于Hash、Set等数据结构不同的时,它无需存储key,对于每个key,只需要k个比特位,每个存储一个标志,用来判断key是否在集合中。所以,它可以实现高效的插入和查询,并且在时间和空间方面都具有巨大的优势,都是常数。

    2.2、布隆过滤器的使用场景

    基于上述的功能,我们大致可以把布隆过滤器用于以下的场景之中:

    • 大数据判断是否存在来实现去重:这就可以实现出上述的去重功能,如果你的服务器内存足够大的话,那么使用 HashMap 可能是一个不错的解决方案,理论上时间复杂度可以达到 O(1) 的级别,但是当数据量起来之后,还是只能考虑布隆过滤器。

    • 判断用户是否访问过:判断用户是否阅读过某视频或文章,比如抖音或头条,当然会导致一定的误判,但不会让用户看到重复的内容。

    • 解决缓存穿透:我们经常会把一些热点数据放在 Redis 中当作缓存,例如产品详情。通常一个请求过来之后我们会先查询缓存,而不用直接读取数据库,这是提升性能最简单也是最普遍的做法,但是 如果一直请求一个不存在的缓存,那么此时一定不存在缓存,那就会有大量请求直接打到数据库上,造成 缓存穿透,布隆过滤器也可以用来解决此类问题。

    • 爬虫/ 邮箱等系统的过滤:平时不知道你有没有注意到有一些正常的邮件也会被放进垃圾邮件目录中,这就是使用布隆过滤器误判导致的。

    2.3、布隆过滤器的原理

    当一个元素被加入集合时,通过N个Hash函数将这个元素进行Hash,算出一个整数索引值,然后对数组长度进行取模运算,从而得到一个位置,每个Hash函数都会得到一个不同的位置,然后再把位数组中的几个位置点都置为1。

    检索时,也会把哈希的几个位置算出来,然后看看位数组中对应的几个位置是否都为1,只要有一个位为0,那么就说明布隆过滤器里不存在这个元素。

    但是,这几个位置都为1,并不能完全说明这个元素就一定存在其中,有可能这些位置为1是因为其他元素的存在,这就是布隆过滤器会出现误判的原因。

    简而言之就是,布隆过滤器可以判断某个元素一定不存在,但是无法判断一定存在。

    所以,我们可以得出布隆过滤器的优缺点如下:

    优点

    1)占用空间极小,插入和查询速度极快;

    2)布隆过滤器可以表示全集,其它任何数据结构都不能;

    缺点

    1)误算率随着元素的增加而增加;

    2)一般情况下无法删除元素;


     三、bitmap和布隆过滤器关系

    在Redis4.0之前,只能通过bitmap来实现,在Redis4.0之后,官方提供了module能力,这时候,官方提供的RedisBloom才算正式出道。

    3.1、海量整数中是否存在某个值:bitmap

    bitmap使用位数代表数的大小,bit中存储的0或者1来标识该整数是否存在。计算一下bitmap的内存开销,如果是1亿以内的数据查找,我们只需要1亿个bit = 12MB左右的内存空间,就可以完成海量数据查找了,这是极其诱人的一个内存缩减。

    (1)bitmap概述

    我们知道,计算机是以二进制为底层的存储单位,一个字节等于8位。比如“big”字符串是由三个字符组成,这三个字符对应的ASCII码分别为98,105,103,对应的二进制存储如下:

    基本命令如下:

    # 设置字节值
    setbit key offset value
    # 获取字节值
    gitbit key offset
    # 获取指定范围内为1的元素个数
    bitcount key [start end]

    (2)bitmap原理

    这是一个能标识0-9的“bitmap”,其中4321这四个数存在,具体模型如下:

    例如说往bitmap里面存储一个数字11,那么首先需要通过向右移位(因为一个byte相当于8个bit),计算出所存储的byte[]数组的索引定位,这里计算出index是1。由于一个byte里面存储了八个bit位,所以通过求余的运算来计算postion,算出来为3。

    这里假设原有的bitmap里面存储了4和12这2个数字,那么它的结构如下所示:

     这个时候,我们需要存储11进来,那么就需要进行或运算了:

    同理,当我们判断数字是否存在的时候,也需要进行相应的判断,代码如下:

      public boolean contain(int number) {
            int index = number >> 3;
            int position = number & 0x07; 
            return (bytes[index] & (1<<position)) !=0;
        }

    (3)整合一下简单版的bitmap代码如下:

    public class MyBitMap {
     
        private byte[] bytes;
        private int initSize;
     
        public MyBitMap(int size) {
            if (size <= 0) {
                return;
            }
            initSize = size / (8) + 1;
            bytes = new byte[initSize];
        }
     
        public void set(int number) {
            //相当于对一个数字进行右移动3位,相当于除以8
            int index = number >> 3;
            //相当于 number % 8 获取到byte[index]的位置
            int position = number & 0x07;
            //进行|或运算  参加运算的两个对象只要有一个为1,其值为1。
            bytes[index] |= 1 << position;
        }
     
     
        public boolean contain(int number) {
            int index = number >> 3;
            int position = number & 0x07;
            return (bytes[index] & (1 << position)) != 0;
        }
     
        public static void main(String[] args) {
            MyBitMap myBitMap = new MyBitMap(32);
            myBitMap.set(30);
            myBitMap.set(13);
            myBitMap.set(24);
            System.out.println(myBitMap.contain(2));
        }
     
    }

    (4)bitmap缺陷

    使用简单的byte数组和位运算,就能做到时间与空间的完美均衡,但是bitmap还存在问题!

    试想一下,如果我们明确这是一个一亿以内,但是数量级只有10的集合,我们使用bitmap,同样需要开销12M的数据,如果是10亿以内的数据,开销就会涨到120M,bitmap的空间开销永远是和他的数据取值范围挂钩的,只有在海量数据下,他才能够大显身手。

    再说说刚刚提到的那个极端case,假设这个数据量在一千万,但是取值范围好死不死就在十个亿以内,那我们不可避免还是要面对120M的开销,有方法应对么?

    3.2、布隆过滤器 

    (1)布隆过滤器简介

    如果面对笔者说的以上问题,我们结合一下常规的解决方案,譬如说hash一下,我将十亿以内的某个数据,hash成一亿内的某个值,再去bitmap中查怎么样,如下图,布隆过滤器就是这么干的:

    利用多个hash算法得到的值,减小hash碰撞的概率,但只要存在碰撞,就一定会有错误判断,我们无法百分百确定一个值是否真的存在,但是hash算法的魅力在于,我不能确定你是否存在,但是我可以确定你是否真的不存在,这也就是以上的实现为什么称之“过滤器”的原因了。

    在Redis4.0之后。我们可以将RedisBloom作为一个模块加载到Redis Server中,从而获取强大的布隆过滤器能力。

    在RedisBloom中,布隆过滤器有两个基本命令,分别是:

    1)bf.add添加元素到布隆过滤器中,类似于集合的sadd命令,不过bf.add命令只能一次添加一个元素,如果想一次添加多个元素,可以使用bf.madd命令。

    2)bf.exists:判断某个元素是否在过滤器中,类似于集合的sismember命令,不过bf.exists命令只能一次查询一个元素,如果想一次查询多个元素,可以使用bf.mexists命令。

    布隆过滤器提供默认参数的布隆过滤器,它在我们第一次使用bf.add命令时自动创建的。

    (2)Redis自定义参数的布隆过滤器

    Redis还提供了自定义参数的布隆过滤器,想要尽量减少布隆过滤器的误判,就要设置合理的参数。

    在使用bf.add命令添加元素之前,使用bf.reserve命令创建一个自定义的布隆过滤器。

    bf.reserve命令有三个参数,分别是:

    key:

    error_rate:期望错误率,期望错误率越低,需要的空间就越大。

    capacity:初始容量,当实际元素的数量超过这个初始化容量时,误判率上升。

    示例如下:

    127.0.0.1:6379> BF.RESERVE customFilter 0.0001 600000
    OK

    如果对应的key已经存在时,在执行bf.reserve命令就会报错。如果不使用bf.reserve命令创建,而是使用Redis自动创建的布隆过滤器,默认的error_rate是 0.0001,capacity是 60。

    布隆过滤器的error_rate越小,需要的存储空间就越大,对于不需要过于精确的场景,error_rate设置稍大一点也可以。

    布隆过滤器的capacity设置的过大,会浪费存储空间,设置的过小,就会影响准确率,所以在使用之前一定要尽可能地精确估计好元素数量,还需要加上一定的冗余空间以避免实际元素可能会意外高出设置值很多。

    总之,error_rate和 capacity都需要设置一个合适的数值。


    四、Redis布隆过滤器的使用

    Redis 官方提供的布隆过滤器到了 Redis 4.0 提供了插件功能之后才正式登场。布隆过滤器作为一个插件加载到 Redis Server 中,给 Redis 提供了强大的布隆去重功能。而在Java开发中,可以使用各种现成的布隆过滤器客户端,包括Google出品的Guava BloomFilter类和Redisson的RBloomFilter接口访问布隆过滤器。

    4.1、使用 Google 开源的 Guava 中自带的布隆过滤器

    Guava 中布隆过滤器的实现算是比较权威的,所以实际项目中我们不需要手动实现一个布隆过滤器。

    首先我们需要在项目中引入 Guava 的依赖:

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>28.0-jre</version>
    </dependency>
    

    实际使用如下:

    我们创建了一个最多存放 最多 1500 个整数的布隆过滤器,并且我们可以容忍误判的概率为百分之一(0.01)

    // 创建布隆过滤器对象
    BloomFilter<Integer> filter = BloomFilter.create(
            Funnels.integerFunnel(),
            1500,
            0.01);
    // 判断指定元素是否存在
    System.out.println(filter.mightContain(1));
    System.out.println(filter.mightContain(2));
    // 将元素添加进布隆过滤器
    filter.put(1);
    filter.put(2);
    System.out.println(filter.mightContain(1));
    System.out.println(filter.mightContain(2));
    

    在我们的示例中,当 mightContain() 方法返回 true 时,我们可以 99% 确定该元素在过滤器中,当过滤器返回 false 时,我们可以 100% 确定该元素不存在于过滤器中。

    Guava 提供的布隆过滤器的实现还是很不错的 ,但是它有一个重大的缺陷就是只能单机使用 (另外,容量扩展也不容易),而现在互联网一般都是分布式的场景。为了解决这个问题,我们就需要用到 Redis 中的布隆过滤器了。

    4.2、通过Redisson使用布隆过滤器

    Redisson是一款超快速轻量级Redis Java客户端,提供了许多常用的Java对象和功能,包括布隆过滤器。

    public interface RBloomFilter<T> extends RExpirable {
     
        boolean tryInit(long var1, double var3);  //初始化布隆过滤器,var1表示大小,var3表示容错率
     
        boolean add(T var1);                      //添加对象
        boolean contains(T var1);                 //判断对象是否存在
     
        long getExpectedInsertions();             //返回预计插入数量
        double getFalseProbability();             //返回容错率
        int getHashIterations();                  //返回hash函数个数
     
        long count();                             //对象插入后,估计插入数量
        long getSize();                           //布隆过滤器位数组的大小
     
    }

    下面的示例代码演示了如何用Redisson的RBloomFilter接口使用布隆过滤器:

    RBloomFilter<SomeObject> bloomFilter = redisson.getBloomFilter("sample");
    // 初始化布隆过滤器
    // expectedInsertions = 55000000
    // falseProbability = 0.03
    bloomFilter.tryInit(55000000L, 0.03);
    
    bloomFilter.add(new SomeObject("field1Value", "field2Value"));
    
    bloomFilter.add(new SomeObject("field5Value", "field8Value"));
    
    
    bloomFilter.contains(new SomeObject("field1Value", "field8Value"));
    
    bloomFilter.count();

    布隆过滤器是一种概率数据结构:能确认元素不存在于集合中,但只能提供元素出现在集合中的概率。

    • falseProbability参数定义了使用给定RBloomFilter发生误报的概率。

    • expectedInsertions参数定义了每个元素的预期插入次数。RBloomFilter对象最多支持2 ^32 bit。

    Redisson还能通过RClusteredBloomFilter接口在Redis中支持分布式布隆过滤器。RClusteredBloomFilter的内存效率更高,可以缩小所有Redis节点使用的内存。RClusteredBloomFilter对象最多支持2^64 bit。请注意,RClusteredBloomFilter只支持Redisson集群模式使用。

    以下示例代码演示了如何使用RClusteredBloomFilter接口:

    RClusteredBloomFilter<SomeObject> bloomFilter = redisson.getClusteredBloomFilter("sample");
    // 初始化布隆过滤器
    // expectedInsertions = 255000000
    // falseProbability = 0.03
    bloomFilter.tryInit(255000000L, 0.03);
    bloomFilter.add(new SomeObject("field1Value", "field2Value"));
    bloomFilter.add(new SomeObject("field5Value", "field8Value"));
    bloomFilter.contains(new SomeObject("field1Value", "field8Value"));

    Redis布隆过滤器总结:

    Redis中大名鼎鼎的布隆过滤器,在一些大数据场景下,判断是否存在来实现去重,布隆过滤器有着极为出色的性能,在大厂中应用范围是极其广的,只要你想在大厂搬砖,一定会在面试敲门的时候被问到的。


    参考链接:

    Redis 实战篇:巧用 Bitmap 实现亿级海量数据统计

    美团面试题:BloomFilter(布隆过滤器)原理与使用,深入浅出BloomFilter原理

    一千万个整数里面快速查找某个整数,你会怎么去做?

    展开全文
  • 网站忽然打不开了? 也许是服务器遭受到攻击了 我们访问网站的时候 的时候会碰到网站无法打开 服务器瘫痪 那么(D)Dos攻击让服务器瘫痪原理是什么呢? 黑客又如何实现DDos攻击的呢
  • 【Servlet】过滤器技术

    千次阅读 2021-02-16 21:19:37
    Filter过滤器技术简介
  • 一、基本选择 基本选择是jQuery中最常用也是最简单的选择,它通过元素的id、class和标签名等来查找DOM元素。 1、ID选择 #id 描述:根据给定的id匹配一个元素, 返回单个元素(注:在网页中,id名称不能...
  • 布隆过滤器究竟是什么,这一篇给讲的明明白白的

    万次阅读 多人点赞 2020-06-12 14:23:27
    不知道从什么时候开始,本来默默无闻的布隆过滤器一下子名声大燥,在面试中面试官问到怎么避免缓存穿透,你的第一反应可能就是布隆过滤器,缓存穿透=布隆过滤器成了标配,但具体什么是布隆过滤器,怎么使用布隆过滤...
  • 详解布隆过滤器

    千次阅读 2019-07-01 00:45:40
    假设我们想要开发一个邮件系统,那么如何实现垃圾邮件的过滤呢。 最简单的办法就是把确定为是垃圾邮件的地址都保存起来,存入黑名单中。当用户接收到黑名单地址的邮件时,直接将邮件归类到垃圾箱中。 垃圾邮件的...
  • Wireshark介绍 与 过滤器表达式语法

    千次阅读 2019-10-28 03:47:56
    二、捕捉过滤器: 1、捕捉过滤器表达式: 2、捕捉过滤器语法: 三、显示过滤器: 1、基本过滤表达式: 2、复合过滤表达示: 3、常见用显示过滤需求及其对应表达式: WireShark安装,安装非常简单,处理安装...
  • spring cloud gateway-filter过滤器

    千次阅读 2020-10-29 16:01:57
    spring cloud gateway-filter过滤器篇filter介绍filter作用filter生命周期内置的单路由过滤器自定义单个路由过滤器自定义全局路由过滤器 filter介绍 前篇对predicate断言进行了介绍,对于前端发送的请求,先通过网关...
  • 【ParaView教程】2.6 过滤器

    千次阅读 2020-06-20 20:01:04
    我们现在已经成功地读入了一些数据并收集了一些有关它的信息。我们可以看到网格的基本结构,并将一些数据映射到网格的表面。...过滤器可以附加到读取器、源或其它过滤器,以某种方式修改其数据。这些过滤器连接在一起,
  • Filter 过滤器一、Filter 什么是过滤器二、Filter 过滤器的使用步骤:三、Filter 的生命周期四、FilterConfig 类五、FilterChain 过滤器链六、Filter 的拦截路径的三配置方式 一、Filter 什么是过滤器 1、Filter ...
  • 分布式布隆过滤器 基于redis

    千次阅读 2019-09-30 11:10:09
    bitMap中用一位代表一个值 常见应用在数据去重 bitMap空间复杂度不会随着数据量的增大而增大 bitMap空间复杂度会随要存储的数据元素的最大值线性增大 比如存 ‘4’ 会直接存在第4位 那么64bit类型的数据 最大值为2^...
  • SpringCloud简介 Spring Cloud是Spring旗下的项目之一 Spring Cloud并不是一个组件 而是许多组件的集合 其将当下非常流行的一些技术整合到了一起 实现了多个...Hystrix或Resilience4j:熔断 【在本篇中 将介绍Spri
  • 几种ELK常见的架构模式

    千次阅读 2019-07-11 18:19:51
    后文的四基本架构中将逐一介绍应用到的其它套件。 ♦ Elasticsearch是实时全文搜索和分析引擎,提供搜集、分析、存储数据三大功能;是一套开放REST和JAVA API等结构提供高效搜索功能,可扩展的分布式系统。它构建...
  • angularjs中的常见过滤器

    千次阅读 2016-11-24 09:19:10
    项目中使用了angularjs框架,使用到了里面自带过滤器,随便就总结了一下angularjs中常见过滤器。 一、什么是过滤器过滤器用来格式化需要展示给用户的数据。 AngularJS很多实用的内置过滤器,同时也提供了...
  • 前言 一、Spring Cloud Gateway 简介 二、Gateway加入后的架构 三、初步建立网关 3.1创建工程添加启动器依赖 ...6.3过滤器类型 6.4自定义局部过滤器 6.4.1配置过滤器 6.4.2编写过滤器 6.4.3测试 6.
  • dubbo系列五、dubbo过滤器

    千次阅读 2022-04-05 21:45:15
    dubbo过滤器 1.前言 dubbo filter的作用和web filter的作用是一样的,在真正调用前做一些公共的处理。这也就是在重要的过程上设置拦截接口,提供扩展供业务实现。 dubbo过滤器是整个dubbo框架中非常重要的组成部分,...
  • 1、什么是布隆过滤器
  • 几种常见网络抓包方式介绍

    万次阅读 2019-05-24 18:17:21
    几种常见网络抓包方式介绍一、网络分流(TAP)二、网管功能的小交换机三、用两块网卡的Linux方案四、总结 无论作为网络运维人员,还是安全渗透工程师,在工作中都会无可避免地碰到网络抓包的需求。 对网络运维...
  • 常见几种网络设备的用途和功能

    千次阅读 2018-12-12 23:21:55
    中继器 一网络信号传输过程中放大信号的设备,它是网络物理层的一介质连接设备,由于信号在网络传输介质中...它可以把信号分散到多条线路上,集线器几口的数量确定下连的计算机数目,同时HUB也可进行堆叠扩展。...
  • (10)常见几种数据库连接池的配置和使用

    万次阅读 多人点赞 2020-03-17 15:59:04
    今天主要介绍常见的数据库连接池 并且对它们的使用做一个总结,本篇文章是以SpringBoot 项目为例,一起随着小编看一下吧! 在文章的开始,提出一个问题: 一.为什么要使用数据库连接池? 影响一个系统使用...
  • 该示例还显示了如何使用Hampel过滤器来移除大异常值。 动机 平滑是我们如何发现数据中的重要模式,同时忽略不重要的事物(即噪音)。我们使用过滤来执行此平滑。平滑的目标是产生缓慢的价值变化,以便更容易看...
  • 模型的几种常见融合方法

    千次阅读 2019-12-03 10:46:38
    每个推荐算法被视为一个过滤器,通过将不同粒度的过滤器前后衔接的方法来进行:   在瀑布型混合技术中, 前一个推荐方法过滤的结果,将作为后一个推荐方法的候选集合输入 ,层层递进,候选结果在此过程中会被...
  • 分库分表的几种常见形式以及可能遇到的难题 转自:http://www.open-open.com/lib/view/open1473820694158.html 摘要 在谈论数据库架构和数据库优化的时候,我们经常会听到“分库分表”、“分片”、...
  • } } 布隆过滤器—应用 常见个应用场景: (1)网页爬虫对URL的去重,避免爬取相同URL地址 (2)反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱(同理,垃圾短信) (3)缓存击穿,将已存在的...
  • 并且图像预处理算法的好坏又直接关系到后续图像处理的效果,如图像分割、目标识别、边缘处理等,所以为了获得高质量数字图像,必要对图像进行降噪处理,尽可能的保持原始信息完整性的同时,又能够去除信号中无用的...
  • 朴素贝叶斯算法是监督的学习算法,解决的是分类问题,如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优点在于简单易懂、学习效率高、在某些领域的分类问题中能够与决策树、神经网络相媲美。但...
  • Zuul主要种类型过滤器,我们可以为特定的url模式添加任意数量的过滤器。 “pre” 预过滤器 - 在路由分发一个请求之前调用。 “post” 后过滤器 - 在路由分发一个请求后调用。 “route” 路由过滤器 - ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 99,560
精华内容 39,824
关键字:

常见过滤器有几种类型