本地分布式缓存一致性系统设计方案
此前我们发布的文章缓存与主副本数据一致性系统设计方案。讲解了如何在系统设计中选择缓存与主副本数据一致性处理模式以及如何正确的实现相应模式。其中提到的问题与解决方案基本可以覆盖各规模研发团队 90% 的业务场景。 采用缓存提升系统性能,提升系统并发度,是我们在系统设计角度下通常会想到的应用场景。在普遍降本增效的大环境下,服务器成本也逐步成为了我们选择为系统添加缓存的参考因素。 # 缓存用的好,降本又增效 我们以云厂商两类产品的定价做为成本参考,如下面两张图是国内头部云厂商的产品基础版本的价格截图(截取自24年12月03日)。第一张图为关系型数据库 MySQL 版本价格,选择高可用系列标准版 4C8G 以及 50GB 存储容量,付费方式为包年包月制一年固定费用为 7358.40 元。第二张图为缓存产品 Redis 开源版本价格,选择标准版 4GB 主从双副本,付费方式依然为包年包月制一年固定费用为 2448.00 元。 以上配置对于系统设计来讲,属于提供基本高可用保障的规格,其中关系型数据库的固定成本约为缓存产品的 3 倍。你可能会觉得这个价格表对比不公平,缓存的容量与数据库差距过大,所以成本才如此显著。当然如果想达到与数据库一致的存储容量,使用缓存的成本也将会是数倍于数据库。但是在实际业务场景下,会被高频访问与使用的数据可能不足总数据量的 20% 。 如果你所负责的系统属于基础系统,也是存在绝大部分数据存在高频高并发的访问场景。通常为了防止缓存穿透等问题,我们在部署架构上也会增加数据库节点,来承载这些以外流量,防止节点负载过高引发的系统问题。如果仅仅依靠扩展 MySQL 节点来承载系统负载,那么成本开销无疑也是巨大的。 此前本人整理的 Shopee 百亿级商品数据如何平稳实现千万级服务器成本缩减一文,便介绍了 Shopee 研发团队如何通过提升缓存命中率进而提高缓存利用率,促使数据库节点数量下降进而降低成本的案例。所以,如果你所在的团队面临控制硬件成本资源的挑战时,不妨考虑一下采用缓存的来缩减数据库的方案。同时还会带来系统性能的提升,可谓降本增效的典范。 当然缓存所能够承载的系统负载也是有限的,随着流量的增加缓存服务器的成本也会随之增加。为了应对此类情况,我们又可以采取应用本地缓存的方案,来降低缓存服务的负载。因为应用服务的成本通常价格相对较低,所以也是进一步控制成本的选择。 如下图所示为国内头部云厂商的轻量应用服务器的产品价格(截取自24年12月03日),即便按照官方折扣价一台 2 核 4G 的应用服务器一年的固定成本也仅需 816 元,上图同等价位的缓存服务可以组一个 3 台应用服务的集群。同样在真实环境下,50% 以上的应用服务其内存利用率都是不高的。长期为数据分配几十,甚至上百 MB 的空间是可能的,这不仅可以降低缓存系统的负载,还可以进一步带来系统性能的提升。 # 本地缓存的数据一致性问题 为系统引入本地缓存,又会带来颇具挑战的数据一致性问题。而为了解决数据一致性问题所带来的工程复杂度,常常让我们忽视掉其经济价值。其实在真实场景下,绝大多数系统中短时数据一致性问题都是可以容忍的。 在 Shopee 百亿级商品数据如何平稳实现千万级服务器成本缩减#多级缓存压缩缓存成本中提到 Shopee 研发团队结合自身实际场景,采用了一个颇具性价比的方案来实现本地缓存。大致思路为通过指定时间窗口内数据访问阈值以及本地缓存短 TTL 的方式实现本地缓存的使用。 可参考下图辅助理解,应用服务针对每个缓存记录维护一个计数器,起初请求穿过应用服务查询缓存,当单位时间内请求数量达到阈值(如:100QPS),便从缓存中加载数据至本地缓存,此后单位时间内(如:1S,S - 秒)请求查询本地缓存,本地缓存失效后查询缓存系统并重启计数。当然也可以在查询本地缓存时重启计数,当本地缓存失效时,如果请求依然达到阈值,再次加载数据至本地缓存。 ...