这几天突然有个组内的小伙伴为我,原有系统里边添加布隆过滤器的操作怎么搞?为什么百度了半天,相关的文章和代码很少?
结合他的问题,我看了下原有的代码结构,整理了一下.net core系统中如何简单高效的接入Redis的布隆过滤器。
1.首先,需要给Redis安装布隆过滤器的组件,这个百度一下,结果比较多,我自己试了几个基本靠谱。
2.原有代码中已经接入了StackExchange.Redis,也封装了一些基本操作。这样的话,我们只需要添加一个对布隆过滤器相关操作的基础方法拓展就行。
using StackExchange.Redis; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace BloomFilterpProject { public static class RedisBloomExtensions { public static async Task BloomReserveAsync(this IDatabaseAsync db, RedisKey key, double errorRate, int initialCapacity) => await db.ExecuteAsync("BF.RESERVE", key, errorRate, initialCapacity); public static async Task<bool> BloomAddAsync(this IDatabaseAsync db, RedisKey key, RedisValue value) => (bool)await db.ExecuteAsync("BF.ADD", key, value); public static async Task<bool[]> BloomAddAsync(this IDatabaseAsync db, RedisKey key, IEnumerable<RedisValue> values) => (bool[])await db.ExecuteAsync("BF.MADD", values.Cast<object>().Prepend(key).ToArray()); public static async Task<bool> BloomExistsAsync(this IDatabaseAsync db, RedisKey key, RedisValue value) => (bool)await db.ExecuteAsync("BF.EXISTS", key, value); public static async Task<bool[]> BloomExistsAsync(this IDatabaseAsync db, RedisKey key, IEnumerable<RedisValue> values) => (bool[])await db.ExecuteAsync("BF.MEXISTS", values.Cast<object>().Prepend(key).ToArray()); } }
3.在原有封装的Redis基础操作的类中,添加对布隆过滤器操作的方法就行。
using BloomFilterpProject; using StackExchange.Redis; using System.Threading.Tasks; namespace BloomFilterpProjects { public class RedisHelper { private int defaultDB; private string defaultFolder; private static string defaultConn; private static ConnectionMultiplexer connectionMultiplexer; private static ConnectionMultiplexer ConnectionMultiplexer { get { if (connectionMultiplexer == null || !connectionMultiplexer.IsConnected) { var config = ConfigurationOptions.Parse(defaultConn); config.AbortOnConnectFail = false; config.AllowAdmin = true; config.AsyncTimeout = 5000; config.ConnectTimeout = 15000; config.KeepAlive = 180; connectionMultiplexer = ConnectionMultiplexer.Connect(config); //Log.Information("创建Redis连接..."); } return connectionMultiplexer; } } public RedisHelper(string conn, string folder, int dbID = 0) { defaultDB = dbID; defaultFolder = folder; defaultConn = conn; } private IDatabase GetDatabase() { connectionMultiplexer = ConnectionMultiplexer; return connectionMultiplexer.GetDatabase(defaultDB); } #region Bloom /// <summary> /// 布隆过滤器添加值 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public async Task<bool> BloomAdd(string key,string value) { return await RedisBloomExtensions.BloomAddAsync(GetDatabase(), key, value); } /// <summary> /// 布隆过滤器验证值是否存在 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public async Task<bool> BloomExist(string key, string value) { return await RedisBloomExtensions.BloomExistsAsync(GetDatabase(), key, value); } /// <summary> /// 设置布隆过滤器key的错误率和初始容量 /// </summary> /// <param name="key"></param> /// <param name="errorRate"></param> /// <param name="initialCapacity"></param> /// <returns></returns> public async Task BloomReserve(RedisKey key, double errorRate, int initialCapacity) { await RedisBloomExtensions.BloomReserveAsync(GetDatabase(),key,errorRate,initialCapacity); } #endregion } }
4.这样就可以优雅的使用Redis的布隆过滤器了,无需引用任何新的插件和依赖。
private readonly RedisHelper redis; public Service(RedisHelper redisHelper) { this.redis=redisHelper; } public void Run() { redis.BloomAdd("lander","9111"); var result = redis.BloomExist("lander", "9112"); }
这里我再夹带一些私货,赘述一些自己对布隆过滤器的理解:
1.布隆过滤器创建的时候,就已经确定了能够存储的数据量和该key对应的布隆过滤器的占用的空间大小。
2.为什么会造成可能不存在但是验证的时候却返回存在?如果是单个标记为,哈希碰撞的概率比较大;如果是多个,那么每个标记为被其他的值标记的时候哈希的碰撞率也是不低的。所以我理解的,如果存储的数据越多,其实验证的时候,误报率理论上是要更高的,那么就是要在创建该过滤器之前考虑好数组位数。这里redis或者其他布隆过滤器的实现,已经考虑了这种情况,所以创建时,按照参数去设置自己想要的容错率和需要存储的数量大小就可以了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南