布隆过滤器的应用 — 实现”活跃账号设备比异常“检测

本文介绍了在app登录场景中,如何利用布隆过滤器来检测时间窗口内的活跃账号和设备比是否异常。布隆过滤器结合内存存储和数据压缩,提供了一种兼顾性能和存储效率的解决方案,尽管存在误判率,但能满足许多业务场景的需求。文中提到了使用Guava在本地实现和利用Redis作为分布式缓存的两种方式,以及Redis的redisbloom插件和Redisson等实现选项。
摘要由CSDN通过智能技术生成

在一个app的登录场景中,有两个重要的信息:账号和设备号

设备号标识一个被安装的app,在app安装时生成,如果卸载了重新安装则会生成新的设备号。

假设有个需求,需要检测一个时间窗口内活跃账号和设备比是否在合理范围内,如果不在合理范围内则告警提醒。

一般的方案有下面两种:

方案 特点
内存set 优点:性能好,缺点:存储数据有限
数据库 优点:可以存储更多数据,缺点:性能相对差,需要维护数据的清除逻辑

这两种方案各有其优缺点。

那么,如果我既追求性能,又追求存储更多的数据,有办法吗

于是布隆过滤器就派上用场了。

布隆过滤器的使用也是将数据存储到内存,同时又可以对数据进行压缩,所以能够在保证性能的同时,存储更多的数据。

前提是能容忍一定程度的误判率,而刚好多数业务场景的却不需要那么精准的数据。

如果想在本地内存里维护布隆过滤器,可以使用Guava的实现。

BloomFilter<CharSequence> bloomFilter = BloomFilter.create(
                Funnels.stringFunnel(Charsets.UTF_8),
                // 期望的插入数据量
                100000,
                // 期望的容错率
                0.0001);

但是本地内存依然是有限的,并且实际场景下,一般是多个应用实例组成的集群需要维护共用的布隆过滤器,所以会考虑使用分布式缓存组件,如redis

若使用redis,也有几种实现方式

  1. 安装redis布隆过滤器插件 — redisbloom
    可自行百度。

  2. 基于redis的bitmap实现

public class RedisBloomFilter {
   

    // 布隆过滤器的 redis key 前缀 利用它可以统计过滤器对Redis的使用情况
    private static final String KEY_PREFIX = "bf:";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * bit数组长度
     */
    private final long numBits;

    // hash函数数量
    private final int numHashFunctions;

    /**
     *
     * @param expectedInsertions 预计插入量
     * @param fpp 可接受的错误率
     */
    public RedisBloomFilter(long expectedInsertions, double fpp) {
   
        this.numBits = optimalNumOfBits(expectedInsertions, fpp);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值