从小白到架构师 | Meta 如何实现 99.99999999% 的缓存一致性

码农有道公众号

共 2870字,需浏览 6分钟

 ·

2024-07-29 08:36

推荐一个原创技术号-非科班大厂码农,号主是机械专业转行进入腾讯的后端程序员!


曾经的故事

Meta(Facebook) 曾经运行一个简单的技术栈——PHP 和 MySQL。

但随着更多用户的加入,他们面临着可扩展性问题。因此他们建立了一个分布式缓存。

虽然这暂时解决了可扩展性问题,但保持缓存数据的新鲜度变得困难。以下是一种常见的数据不一致场景:

  1. 客户端查询缓存中的x,但缓存中不存在该值。
  2. 因此缓存会向数据库查询:x = 0
  3. 与此同时,数据库中的x发生了变化:x = 1
  4. 但缓存失效事件先到达缓存,缓存中的x发生变更:x = 1
  5. 然后第2步中查询到的x=0再次更新x值:x = 0

现在数据库中的值:x = 1,而缓存中的值:x = 0。所以存在缓存和数据库中的数据不一致。

尽管缓存不一致出现的概率很小,但是Meta 的用户增长速度却是爆炸性的,很快成为全球访问量第三大的网站。

现在他们每天处理一千万亿(10^15)个请求。所以即使有1%的缓存未命中率其代价也是昂贵的——每天有10万亿次缓存填充。

这篇文章介绍了 Meta 如何利用可观测性来提高缓存一致性。

缓存一致性

从用户的角度来看,缓存不一致就像数据丢失一样。因此他们创建了一个可观察性解决方案。以下是他们的做法:

1. 监控

Meta的开发人员开发了一个单独的服务来监控缓存不一致问题,并将该服务命名为Polaris

Polaris 的工作原理如下:

  • 它像一个缓存服务器一样工作,并接收缓存失效事件,当数据库中的数据发生变化时,失效事件会发送到缓存服务器和 Polaris。
  • 然后Polaris 会向缓存服务器查询数据,检查缓存中的数据是否与数据库中的数据一致。
  • 如果发现数据不一致,Polaris 会将这些缓存服务器加入队列,稍后再次检查,在必要时会从数据库中获取最新的数据,并将其更新到缓存中。以确保数据的一致性。
  • 它在写入期间检查数据的正确性,因此可以更快地发现缓存不一致

这里还是举一个例子来帮助理解Polaris 的工作原理:假设有一个电商网站,它使用缓存来加速用户访问产品信息的速度。缓存中存储了产品的价格、库存等信息,而这些数据的原始来源是数据库。

  • 数据库更新:某个商品的库存从10件增加到20件,数据库发送了一个缓存失效事件。
  • Polaris 接收事件:Polaris 收到了这个失效事件,并开始工作。
  • 查询缓存服务器:Polaris 向缓存服务器查询该商品的信息,发现缓存中的库存还是10件,与数据库中的20件不一致。
  • 排队并再次检查:Polaris 将这个缓存服务器排队,稍后再次检查和刷新缓存,确保缓存中的数据更新为20件。
  • 在写入时检查:现在,假设有另一个用户在短时间内再次购买商品:库存从20件减少到19件。在这个写入操作发生时,Polaris 会再次检查缓存中的数据,确保缓存中的数据是最新的19。如果发现缓存中的数据不正确(例如,缓存中显示的是20件,而实际库存已经变为19件),Polaris 会立即更新缓存,确保缓存和数据库中的数据保持一致。

此外,分布式缓存与 Polaris 之间存在网络分区的风险。因此他们在客户端与 Polaris 之间使用单独的失效事件流。这个流专门用于传递缓存失效事件,即使在网络分区的情况下,也能确保失效事件被传递到位。

解决缓存不一致的一个简单方法是查询数据库。但大规模下数据库存在过载风险。因此 Polaris 以 1、5 或 10 分钟为时间间隔查询数据库。通过这种方式,Polaris 可以在确保数据一致性的同时,避免频繁查询数据库导致的过载问题。

2. 追踪

在没有日志的情况下调试分布式缓存中的问题非常困难。为了找到缓存不一致的原因,记录每个数据更改虽然是一个办法,但因为写入操作过于频繁,导致这种方法不可扩展。因此,他们创建了一个跟踪库并将其嵌入到每个缓存服务器上。

其工作原理如下:

  • 跟踪库仅记录在竞争条件时间窗口内发生的数据变化,从而减少了日志存储的需求。竞争条件时间窗口是指在发生数据竞争的时间段。例如,当多个操作同时尝试访问和修改同一数据时,会产生竞争条件。
  • 跟踪库会保存最近修改的数据的索引,以便在发生新的数据更改时,判断是否需要记录。如果新数据变更涉及到最近修改的数据,才会进行记录。这种方式减少了不必要的日志记录,
  • 如果Polaris发现缓存不一致,它会读取这些日志来查找问题的根源,然后发送通知。这样可以快速定位和解决问题。
系统设计

缓存失效是计算机科学中的难题之一,现在 Meta 支持 10 个 9 的缓存一致性 - 99.99999999%。简而言之,100 亿次缓存写入中,只有 1 次会出现不一致的情况。这种技术可以与任何规模的缓存服务器一起使用。

推荐阅读:

完全整理 | 365篇高质技术文章目录整理

一张图弄清楚缓存架构设计中的经典问题及解决方案

一张图总结系统设计中的33个黄金法则

主宰这个世界的10大算法

彻底理解cookie、session、token

专注服务器后台技术栈知识总结分享

欢迎关注交流共同进步
也可扫码添加个人微信交流技术,职场发展~
添加时请注明公司名(或学校名)+方向!!


码农有道 coding


码农有道,和您聊技术,和您聊职场,和您聊互联网那些事!

浏览 251
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报