聚焦缓存防护方面,让我们一起深入探讨和掌握它
感谢您阅读这篇文章。更多面试问题:
https://programmerscareer.com/zh-cn/software-interview-set/
主题1.1:详细研究缓存穿透
缓存穿透(Cache Penetration),也称为缓存错误或缓存突破,是指请求直接命中数据库,而不是缓存。这通常发生在请求查询未存储在我们的缓存中的数据时。
想象一下,一个购物网站,用户可以搜索产品。缓存可能包含受欢迎搜索项目,以提高检索速度。然而,罕见的产品搜索者可能会导致系统必须从数据库中查询。这是缓存穿透的一个例子。
虽然这可能不会造成严重的问题,但考虑一下高量的流量查询未缓存的项目。这可能会导致数据库的大量加载,并最终导致数据库崩溃。
甚至更严重的缓存穿透是当攻击者可以精确地预测特定请求不会被缓存时发生的情况,并在我们的系统上发起这些请求,使数据库成为主要的命中点,并最终导致系统崩溃。
缓存穿透是应用程序的流畅性和有效性所必需的。幸运的是,Redis提供了强大的策略来避免缓存穿透,并在本主题中探讨它们。
主题 1.2: Redis 中防止缓存穿透的策略
Redis 提供了强大的策略来防止缓存穿透,确保系统在高负载下的高效性。这些策略主要集中在减少直接命中数据库的情况下。
一个常见的策略是默认缓存值。当请求未找到数据时,不要让请求直接命中数据库,而是在缓存层处理它,并返回默认值。这意味着数据库不会受到缓存穿透的影响,并且可以防止缓存穿透。
另一个强大的策略是Bloom 过滤器。Bloom 过滤器是一种概率数据结构,可以用来测试数据集中的元素是否是集合的一部分。这意味着它可以快速识别数据请求是否存在于我们的数据库或缓存中。如果 Bloom 过滤器说数据项不存在,我们可以立即返回默认值,而不必查询我们的缓存或数据库。
在设置这些策略时,需要考虑权衡。Bloom 过滤器可能会导致误报。然而,这通常会大大超越小错误概率的好处。
主题1.3:深入探讨缓存崩溃
缓存崩溃是一种系统故障,发生在大量缓存项目同时过期,并且多个请求为这些数据项命中数据库,可能导致数据库崩溃或变得不可用,因为高负载。
想象一下,当网站缓存每日特惠时,所有缓存项目都在午夜过期。当时钟显示 12:00 时,所有缓存项目都变得无效。第一组用户在午夜之后试图访问这些特惠时,系统必须从数据库中获取新的特惠并填充缓存。
然而,想象一下,当数百万用户同时试图访问这些特惠时,这可能会导致数据库被大量请求所淹,使其变得不可用或崩溃——这是缓存崩溃的效果。
虽然缓存崩溃可能会令人恐惧,但我们可以采用各种策略来防止它发生。了解这些技术可以使我们设计的系统更加坚固和可靠。
主题 1.4: 使用 Redis 防止缓存崩溃
防止缓存崩溃的效果是防止大量请求同时命中数据库。Redis 提供了许多实用的策略来实现这一点。
第一种技术是使用TTL (Time To Live) 延迟。不要为所有缓存项目设置相同的 TTL 值。我们可以轻微延迟或随机化它们的 TTL 值。这引入了差异,从而降低了多个项目同时过期的风险。
另一个主要策略是使用缓存预热。缓存预热是加载数据到缓存之前进行的实践。例如,如果我们知道某些缓存项目很可能很快过期,我们可以在低峰期预先刷新它们,以避免崩溃期间的峰值。
最后,可能值得考虑使用回退缓存。在这种方法中,即使缓存项目已过期,仍然返回过期的值,同时更新缓存的后台进程。这可以防止突然数据库加载,因为同时发生的缓存错误。
要记住的是,没有单一策略可以在每个场景中作为银弹。实际的实现可能需要根据使用案例的特定性组合这些策略。
中文翻译:
主题1.5:Redis事务与缓存预防
Redis不仅仅是内存数据库,还可以支持事务——一系列命令按顺序执行,除非遇到命令中的错误。
Redis事务使用两步过程:
- 命令排队:使用
MULTI
命令来排队命令。在这一步中,Redis仅仅记录所有在这个事务中的命令。 - 命令执行:当
EXEC
命令被发出时,Redis就执行所有在事务中排队的命令,按照排队的顺序执行。
Redis事务用于确保所有缓存操作(例如读取、写入或更新)是原子的——这意味着它们全部执行或不执行。这是维持缓存一致性的关键,并可以帮助缓解脏读的影响,也可以帮助缓解缓存渗透的影响。
让我们来看一个例子。假设你正在实现一个排行榜系统并想以原子方式更新玩家的分数。下面是如何使用事务来实现这一点的:
1 | MULTI |
通过将 GET 和 INCR 命令包装在一个事务中,我们可以确保如果其他客户端读取分数,他们总是会得到一致的值。
使用 Redis 事务与缓存预防技术,无论是防止渗透还是避免崩溃,都可以显著提高缓存层的一致性和可靠性。
主题1.6:Redis 缓存预防在实际应用中的应用
Redis 和其缓存预防技术在许多实际应用中被广泛使用,以处理大量负载而不崩溃后端数据库。下面是一些例子:
- 电子商务网站:网站像 Amazon 一样使用 Redis 来缓存产品详细信息和推荐。Redis 的缓存预防技术对处理大量并发用户的能力至关重要,特别是在节日期间。
- 社交媒体平台:平台像 Twitter 和 Instagram 一样使用 Redis 来缓存用户数据和信息流。Redis 的高并发处理能力使其成为这些平台的理想选择。
- 排行榜系统:在游戏平台上,用户分数和排名被实时更新并需要被多个客户端同时访问。Redis 的原子事务能力确保分数在所有客户端中的一致性,即使处理大量并发用户。
- 在线票务服务:在高需求事件期间,票务服务可能会遇到数据库故,如果不处理正确。Redis 的缓存管理能力可以有效地防止这些情况。
在所有这些例子中,缓存优化技术,例如缓存时间的分层、缓存预热和使用备用值,被广泛使用来防止缓存渗透和缓存崩溃。
主题1.7:回顾和评估
缓存渗透 发生在频繁请求未知数据时,每次请求都会到达后端数据库,因为缓存中不可用。这可能会导致过多的和不必要的数据库负载。Redis 提供了多种防止它的机制,例如 NULL 缓存和 Bloom 过滤器。
缓存崩溃 发生在多个缓存数据同时过期时,导致数据库的大量请求。Redis 提供了策略,例如 TTL 分层、缓存预热和备用缓存,来处理缓存崩溃。
Redis 事务 在多次读取或写入操作期间起着重要的作用,通过排队多个命令并以原子方式执行它们,Redis 事务可以防止脏读并提供更高的可靠性。
Redis 和防止缓存渗透和崩溃的技术在高流量、实际应用中被广泛使用,例如电子商务网站、社交媒体平台、实时排行榜系统和在线票务服务。
让我们开始评估。
问题1
以你自己的语言描述什么是缓存渗透。为什么它是一个问题,Redis 是如何帮助防止它的?
问题2
描述一场实际场景,在这场场景中,Redis 事务可能会有用。在这种场景中,如何通过使用事务来促进数据一致性?
问题3
考虑一场高流量的电子商务网站,并描述如何有效地处理缓存崩溃使用 Redis。
答案1
缓存渗透是指频繁请求未知数据时,每次请求都会到达后端数据库,因为缓存中不可用。这可能会导致过多的和不必要的数据库负载,并降低性能。Redis 帮助防止缓存渗透主要通过 NULL 缓存,在数据库返回 NULL 值时存储“NULL”关键字的情况下。
答案2
在 Twitter 上,当用户点赞一条推文时,推文的总喜欢数和用户的喜欢推文都需要更新。这场场景需要多次写操作,如果不处理原子方式,可能会导致数据不一致。Redis 事务可以将多个写命令排队并以原子方式执行,以维持数据的整性和一致性。
答案 3
在高流量的电子商务网站,例如 Amazon,缓存崩溃可能会发生,当多个缓存产品详细信息或用户推荐过期时。Redis 有效地处理这种情况,通过 TTL 分层,每个键值对在缓存中有不同的过期时间,或者通过缓存预热,在旧缓存过期之前刷新缓存中的最常访问数据。这可以防止数据库的突然增加。
English post: https://programmerscareer.com/redis-interview4/
作者:Wesley Wei – Twitter Wesley Wei – Medium
注意:本文为作者原创,转载请注明出处。
评论