首页 新闻 会员 周边 捐助

C#:内存中保存IP黑白单,用什么列表类型以及如何查找性能最好

0
悬赏园豆:30 [已解决问题] 解决于 2025-08-19 21:55

当前IP黑白单是保存在 redis 中的,为了进一步性能,准备改为在内存中保存并定时更新内存中的数据,请问用什么列表类型以及如何查找性能最好?

dudu的主页 dudu | 高人七级 | 园豆:25265
提问于:2025-08-19 15:40

需求是给定一个ip,判断其是否在黑名单中吗?

会长 1周前

@会长: 是的

dudu 1周前

@会长: 准备用 FrozenSet + AlternateLookup

dudu 1周前

@dudu: 哦,刚才去查了下,这个结构说是比HashSet<T>查找更快,但是实例化之后不能往里添加新的元素。那如果需要把新的ip添加到黑名单还需要重新实例化吗?

会长 1周前

@会长: 是的,通过定时任务从 redis 中读取黑名单创建新的实例

dudu 1周前
< >
分享
最佳答案
0

准备使用 .NET 8 引入的 Frozen Collections,查找速度比 HashSet 还要快,相关链接:

dudu | 高人七级 |园豆:25265 | 2025-08-19 17:16

再结合 AlternateLookup<ReadOnlySpan<char>> ,参考博文 Alternate Lookup for Dictionary and HashSet in .NET 9

dudu | 园豆:25265 (高人七级) | 2025-08-19 17:38

采用 FrozenSet + AlternateLookup 的方法实现并上线了

实现一个 HostedService,在应用启动时与定时周期内从 redis 读取 IP 黑名单数据,创建新的 FrozenSet 实例

public async Task<FrozenSet<string>> GetBlockedIpSetAsync(string appName)
{
    string key = CacheKeyManager.IpBlockList(appName);
    return [.. (await redisDatabase.Database.SortedSetRangeByRankAsync(key)).Select(x => x.ToString())];
}

并基于这个 FrozenSet 实例创建 AlternateLookup

internal static FrozenSet<string>.AlternateLookup<ReadOnlySpan<char>>? BlockedIpLookup { get; private set; }

public static void BuildBlacklists(FrozenSet<string> blockbedIpSet)
{
    BlockedIpLookup = blockbedIpSet.GetAlternateLookup<ReadOnlySpan<char>>();
}

然后通过 AlternateLookup 的 Contains 检查黑名单中是否存在对应的 IP

public static bool IsIpBlocked(string appName, string ip)
{
    return appName switch
    {
        BlogList.Name => BlogList.BlockedIpLookup?.Contains(ip) == true,
        BlogPostDetail.Name => BlogPostDetail.BlockedIpLookup?.Contains(ip) == true,
        _ => throw new Exception($"The app name '{appName}' is not supported ")
    };
}
dudu | 园豆:25265 (高人七级) | 2025-08-19 21:18
其他回答(2)
0

我觉得用字典存应该不错

收获园豆:15
摸鱼w | 园豆:287 (菜鸟二级) | 2025-08-19 16:31

ConcurrentDictionary

支持(1) 反对(0) dudu | 园豆:25265 (高人七级) | 2025-08-19 17:02
0

布隆过滤器可以吗

收获园豆:15
我才不是老家伙 | 园豆:354 (菜鸟二级) | 2025-08-19 16:46
支持(0) 反对(0) dudu | 园豆:25265 (高人七级) | 2025-08-19 17:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册