可能是和否:Redis、概率和布隆过滤器
我遇到了一个问题。我的在线游戏 World of EverCraft(不是真实的游戏。但如果是,它会……)中有数千万玩家。
数据去重,也称为去重,可提供改进的用户体验和参与度,以及更高效的数据处理。虽然大多数人认为去重是指在数据库中删除多个相同数据的副本,但实际上,去重的需求出现在许多常见情况下,导致以下问题:
向客户发送消息是任何企业不可或缺的一部分。在向特定用户发送电子邮件或短信之前,去重可以确定该用户是否之前已经看过该电子邮件或短信。如果是,系统可以向该用户发送不同的消息,或者决定在一段时间内(如果需要)不联系该用户。
提取、转换和加载 (ETL) 是处理大型数据集(如事件日志)的常用技术。ETL 通常用于从不同的系统中收集数据,以便对其进行分析。在该流程中添加去重意味着系统不会对同一数据的多个副本执行相同的分析。
当用户创建新帐户时,确保其 ID 唯一非常重要。使用去重,可以轻松确定给定 ID 是否已存在。
收到系统中发生重要事件的警报是件好事。完全没有收到任何警报很糟糕,但收到同一个事件的 300 个警报几乎同样糟糕。或者 30,000 个警报。去重可以抑制之前发生的警报,但该技术可以与计时器结合使用,以删除 最近 的重复项,允许系统在给定时间范围内最多只发出给定警报一次。
欺诈检测是 AI/ML 处理的绝佳用例。不幸的是,AI/ML 处理成本高昂。去重可以检查交易,并查看它是否与过去批准的交易相似。如果新交易足够相似,系统可以自动批准交易,而无需产生欺诈检测成本。(在此用例中,重复值是一件好事。)
Redis 集合只存储任何给定值一次。无论向集合中添加了多少次值,集合中都只包含该值的单个副本。Redis 集合还针对以下问题进行了优化:“此值是否在此集合中?”,并能以极快的速度回答。集合也是确定的,因为问题的答案是“肯定”或“绝对不是”。但是,请注意,随着集合中唯一值的增加,集合可能会占用大量内存。
概率模块提供了布隆过滤器,这是一种用于去重的概率算法。与集合不同,布隆过滤器只存储每个值的哈希值,而不是值本身。这意味着布隆过滤器可能只占用集合所需内存的 2%。而且它们通常比集合快一点,而集合本身已经非常快了。但这种速度和内存效率的权衡是:布隆过滤器不是确定的。对于“我们之前是否见过此值?”这个问题,答案是“绝对不是”和“可能是”。换句话说,布隆过滤器可能会出现误报。
客户成功案例
“一家大型游戏公司 在 Redis Enterprise 中使用布隆过滤器为实时数据流添加事件级去重层,使他们能够每天处理超过 20 亿个事件。与他们的原始实现相比,他们现在使用的内存大约减少了 90%,并且延迟从大约 2 毫秒降低到不到 0.25 毫秒。”
要拥有世界一流的用户参与度,您的解决方案必须能够预测用户的需求并了解其先前的体验。一个优秀的去重解决方案可以让您确保每个用户交互都是独特的、与用户的兴趣相关的,并且基于用户的历史记录。
高性能的去重解决方案应该能够扩展以处理大量数据集,并具有高性能和线性可扩展性。Redis 集合和概率模块正是这样做的。无论您选择哪种解决方案,它们都能在所有数据集中提供闪电般的速度,包括多云和地理分布式数据集。
高效的去重解决方案可以让您避免冗余处理,确保不会对任何数据进行多次处理。在某些情况下,去重可用于避免完全进行处理。使用去重来限制或消除警报,使操作员能够更容易地对系统事件做出适当响应,同时避免警报疲劳。
集合最多包含任何给定值的单个副本。换句话说,我们可以将同一个值添加到集合中一百万次(反复调用 SADD pets dog ),但该值在集合中只会出现一次。在定义了集合后,我们可以使用 SISMEMBER 命令来判断给定值是否在集合中。如果我们创建一个名为 pets 的集合,并将值 dog, cat 和 parrot 添加到其中,则值 dog 是集合的成员,而值 monkey 则不是
以下是如何轻松设置和使用布隆过滤器
我们要确保每个用户都有唯一的用户名。我们将 doug 和 lisa 添加到布隆过滤器中。(BF.ADD 会在必要时创建过滤器。)如果有人尝试创建另一个名为 doug 的帐户,布隆过滤器会说我们可能已经有一个具有该名称的用户。另一方面,如果有人尝试使用用户名 bob 创建新帐户,布隆过滤器会告诉我们它绝对不是我们之前见过的 ID,因此可以使用该名称安全地创建新帐户。