当前位置: 首页 > news >正文

如何在大规模服务中迁移缓存

当您启动初始服务时,通常会过度设计以考虑大量流量。但是,当您的服务达到爆炸式增长阶段,或者如果您的服务请求和处理大量流量时,您将需要重新考虑您的架构以适应它。糟糕的系统设计导致难以扩展或无法满足处理大量流量的需求,可能会导致糟糕的用户体验甚至服务失败。

缓存在处理大量流量的服务中起着重要作用,因为它可以快速将数据传递给用户。然而,缺乏可扩展性,这在早期服务中很容易被忽略,如果缓存需要增加容量或进行物理移动,可能会导致重大服务失败。

图片描述

系统架构中的缓存

我在一家拥有大量流量的全球信使公司担任核心团队成员六年,有很多机会思考这样的可扩展性。在本文中,我将分享在我需要物理移动缓存并增加其容量的类似情况下如何可靠地迁移和改进缓存而不影响服务。

大规模消息服务中的缓存

图片描述

消息服务中的常见流程

由于 Messenger 的全球性,数据从许多国家/地区以各种形式传输,包括文本、图像、视频、音频和二进制文件。如果你想分解这个过程,它是这样的。

  1. 上游数据
  2. 下游数据
  3. 交货数据

图片描述

在大规模服务中缓存请求/响应流

如果缓存每次在数据下游都检查数据源所在的存储,那么数据的传递速度会很慢,用户体验会很差。因此,缓存检查并在数据下游传递用户数据,因为为了用户体验必须快速传递数据。

系统架构可能会因各项服务的特殊因素而有所不同,例如数据的性质和用户的服务模式。因此,即使对于相同的服务,设计也会根据流量的大小而有所不同,因此灵活的设计很重要。我运行的平台是一个高流量服务,所以我根据用户的服务使用模式不同地应用了缓存。

图片描述

根据用户对服务的使用情况访问不同的数据

从数据利用的角度来看,用户如何使用您的服务存在三种一般模式。

  1. 用户在上传数据后立即访问他们的数据。
  2. 用户上传数据后,他们不会立即访问数据,但会频繁访问。
  3. 用户上传数据后,他们立即访问数据的频率就会降低。

如果一个缓存同样适用于所有这些情况,它将会是低效和昂贵的,这不是一个好的系统设计。根据用户的模式,缓存应该足够灵活以应用于相同的服务。

图片描述

在大规模服务中缓存请求/响应流

认识到上述情况,可以按如下方式应用缓存。

  1. 对于可立即访问的数据,在上游时将其推送到缓存中,并使其在之后立即被命中。
  2. 对于不能立即访问的数据,如果尚未命中,则在下载时将其从缓存中拉出。

当然,在第二种情况下,您可能会发现自己在第一次下载时访问存储,这是按需的,不会立即访问缓存。但是,如果此后数据被频繁访问,它会不断地命中缓存,这将减少存储 I/O,从而显着降低成本。

技术总是与Trade-off一起应用,因此从架构师的角度来看,它们是为成本、可靠性和用户体验而设计的。

缓存迁移

在实时产生大量流量的消息服务中,缓存起着非常重要的作用。在这种情况下,缓存服务器老化,需要增加容量。为此,我们首先需要整理现有设计中存在的问题,并定义需要改进的功能。

软件设计问题

图片描述

旧设计的问题是双重的。

具有难以缩放结构的哈希算法

首先,现有哈希服务器的哈希算法是一种基于特定标识符以服务器数量为分母进行划分和哈希的结构,如果哈希服务器数量发生变化,则现有缓存的访问方式也会发生变化,并且所有数据的命中率大幅下降。

因此,需要重新定义缓存服务器的哈希算法来扩展缓存服务器的容量。

图片描述

在役期间难以管理哈希服务器

第二个问题是缓存服务器不能实时自主控制,即在服务中途,如果缓存服务器发生变化或故障,无需重启后端应用程序。

这两个问题的关键共同问题是缺乏可扩展性,因此我们着手通过将可扩展性作为我们的首要任务以及实现它的操作来改进它们。

一致性哈希

为什么要使用一致性哈希

哈希算法有很多算法方法,视情况而定。但是,为了解决上述问题,我们需要优先考虑可扩展性,因此我们决定引入一种一致性哈希算法,即使在扩展时也可以被同一节点访问。

那么,什么是一致性哈希以及它的好处是什么?

概念

图片描述

一致性哈希概念

在分布式系统中,Consistent Hashing 有助于解决以下场景。

  1. 为缓存服务器提供弹性伸缩。
  2. 扩展一组服务器节点,例如 NoSQL 数据库或缓存。

图片描述

一致性哈希算法

我们的目标是设计一个缓存系统。

  1. 能够在一组“n”个缓存服务器上均匀分布请求的散列键。
  2. 我们必须能够动态地添加或删除缓存服务器。
  3. 添加或删除缓存服务器时,需要在服务器之间进行最少的数据移动。

Consistent Hashing 可以解决水平可扩展性问题,无需在每次向上或向下扩展时重新排列所有键或操作所有缓存服务器。

怎么运行的

图片描述

一致性哈希的工作原理

  1. 创建散列键空间:假设您有一个散列函数,它生成范围 [0, ²³²-1] 内的整数散列值。
  2. 我们将哈希空间表示为哈希环,并假设在步骤 1 中生成的整数被放置在一个环中,以便封闭最后一个值。
  3. 我们会在密钥空间(Hash Ring)中放置一批缓存服务器,并使用哈希函数将每个缓存服务器映射到环中的特定位置。例如,如果您有四台服务器,您可以使用散列函数来使用它们的 IP 地址的散列将它们映射到不同的整数。
  4. 这决定了服务器的关键位置。
  5. 在哈希环中添加或删除服务器时,您无需操作缓存服务器。

它如何在生产环境中工作

图片描述

生产环境中的一致性哈希

假设您已经在特定哈希环中部署了哈希密钥和服务器。

当系统触发哈希键时,它将尝试在分配给它的最近服务器上查找数据。这种旋转或放置可以根据系统设计进行调整。这些缓存服务器中的每一个在系统设计中都被称为一个“节点”,这里分别表示为A、B、C、D。它们按顺时针方向排列,后面是密钥。

现在,当系统收到有关“Cairo, Eygpt”的数据请求时,它会首先在相应的节点(即“A”)中查找该信息。类似地,对于键“英国伦敦和日本东京”,最接近的相应位置或节点是顺时针方向的“D”,因此它将与该特定节点交互以检索数据。

与传统的哈希不同,当系统遇到服务器故障、添加或移除时,请求或数据密钥会自动连接或分配到最近的服务器或节点。

在服务器出现问题或问题的情况下,传统的散列方法不足以使用和处理网络上的请求。假设有固定数量的服务器,并且密钥到服务器的映射是同时发生的。

添加服务器需要为新服务器重新映射和散列对象以及大量计算。另一方面,一致性哈希中节点的非线性放置允许节点在系统发生变化时相互交互。

然而,有时 Hash Ring 中所有节点的分布或负载不相等或不成比例,从而导致分布不平衡。让我们仔细看看 Consistent Hashing 系统如何响应添加或删除服务器/节点的情况,以及它如何确保系统不会变得不平衡。

热点

承载分布不均的数据请求负载的节点成为热点。为了解决这个问题,系统工程师可以使用虚拟节点来启用哈希环,将请求平均分配给所有活动节点。

在一致性哈希中添加和删除服务器

图片描述

在一致性哈希中添加和删除服务器

当您将新节点添加到环中时,例如,在“Srushtoka & Freddie”键之间。最初,如上图所示处理两个键。现在,在新服务器之后,“Freddie”密钥的哈希或分配将被分配或映射到而不是。但是,“Srushtika”键分配仍将映射到 .

在从环中删除现有服务器的情况下遵循相同的原则。因此,哈希环可确保在添加或删除服务器或节点出现故障的情况下不影响整个过程。此外,如果出现重新分配的情况,与传统的散列机制相比,它不会花费太多时间。

注意事项和好处

您有一个缓存服务器集群,需要能够根据流量负载进行弹性扩展或缩减。例如,一个常见的情况是在圣诞节或新年期间添加更多服务器以处理额外的流量。因此,你需要有一套可以根据流量负载弹性伸缩的缓存服务器。

这就是一致性哈希在这种情况下大放异彩的地方,在这种情况下,您正在运行一个弹性缓存集群。让我们总结一下这样做的好处。

  • 数据库或缓存服务器集群的弹性扩展
  • 更容易在服务器之间复制或分区数据
  • 分区数据允许均匀分布以减少热点
  • 启用系统范围的高可用性

可扩展的软件设计

随着哈希算法更改为一致性哈希,您拥有易于扩展的现成缓存服务器形式,但您需要做一些额外的准备,以使用一组现成的缓存服务器替换或添加到现有的缓存集群。

要在不中断服务的情况下迁移缓存服务器并对现有集群进行更改,您需要确保后端应用程序支持热重载,这意味着它们可以在不重新启动服务的情况下读取和反映设置。如果您的服务基于大量流量,您需要格外小心以确保它已准备好并能够处理此任务。

准备迁移

首先,我们做了很多配置减法,以便在不中断服务的情况下从后端应用程序添加或删除更改的缓存服务器。这个过程应该只针对应该由配置控制的信息,并且这样做的原因应该是清楚和明确的。

迁移场景

图片描述

上述设置完成后,我们一路将场景分为成功的场景和失败的场景,准备相应的应对。

大规模服务的成功缓存迁移场景

成功案例

  1. 根据地域等因素,依次迁移各族缓存服务器。
  2. 数据迁移到新配置的缓存集群完成,新缓存集群的命中率接近100%。
  3. 减少对现有缓存集群的请求,命中率接近0%。
  4. 在不重启服务的情况下使用设置移除旧的缓存集群
  5. 所有数据请求现在都将由新配置的缓存集群传送。

图片描述

大规模服务缓存迁移失败场景

故障场景

  1. 每个缓存服务器集群根据特定因素(例如区域)依次迁移。
  2. 当数据迁移到新配置的缓存集群时,它会与现有数据哈希混合,导致数据中断。
  3. 删除所有新的缓存集群并将请求回滚到仅现有的缓存集群。
  4. 现有后端应用程序服务器或存储 I/O 由于使用率高而出现死锁。
  5. 监控系统资源,观察情况,并比以前多添加 20-50% 的后端应用程序服务器。
  6. 通过断路器临时限制一些请求以适应存储 I/O。
  7. 系统稳定后,执行分析以确定原因。

我们首先考虑了可行的方案和可能失败的方案,并与我们自己和我们的团队成员一起审查它们,以确保我们不会错过任何任务或案例。如果场景可行,我们会列出我们需要的功能并一一实现。

迭代测试

如果您直接跳入缓存迁移而不测试依赖大量流量的服务,那么它顺利进行的可能性非常低。即使你准备了很多场景和响应,工程师也无法预料到每一种情况,人总是会犯错误,所以即使是小问题也很可能发生。

图片描述

大规模服务中的迭代测试

因此,在我开始在生产环境中迁移缓存之前,我将测试分为两部分。

  1. 在开发环境中运行小型模拟以进行测试。
  2. 在生产中请求最少的服务器集群上运行多个 Canary 测试。

对于以上两个测试,我们设置了与生产环境相同的监控和告警系统。

开发环境中的仿真

我们在开发环境做小规模模拟的时候,会根据mock数据产生流量,让我们承受小规模的高流量,也就是压力测试。但是,这种模拟的缺点是无法测试与实际生产环境相同。

生产环境中的金丝雀测试

图片描述

金丝雀测试

开发环境测试没有覆盖的是mock数据流量,不是真实用户流量,所以没有考虑生产环境缓存迁移时用户的时间,events当时,天气和其他背景因素。我们认为这些测试很难在开发环境中覆盖,所以我们想通过在生产环境中运行多个金丝雀测试来弥补。

但是由于金丝雀测试是在生产环境中进行的,会影响到服务,所以我们选择了请求量最少的区域的一组服务器,在请求量最少的时候进行测试。

迁移

我们把缓存迁移成功和失败的所有场景都写了出来,为它们开发了特性,并在小范围内测试了几次,所以我们认为如果不出什么大事,迁移就会顺利进行。事实上,一旦我们在生产中这样做,从旧缓存集群迁移到新缓存集群大约需要一个月的时间。花费这么长时间的原因是因为有一些流量可能是从各种客户端或遗留客户端代码遗留下来的。

由于新的缓存集群已经到位,我们能够在正确的时间移除旧的缓存集群,因为我们一直在监控和密切管理警报。另外,为了通过缓存迁移保持稳定的服务,我们着眼于降低失败率而不是以成功为目标,因此我们有灵活的应对失败场景的计划。最终,这个过程让我们在长达一个月的时间内顺利完成了缓存迁移,没有出现任何问题。

结论

在本文中,我们讨论了缓存对依赖大量流量的服务的影响,这些服务设计中的可扩展性差距会导致什么,以及我们在尝试扩展缓存时遇到的问题以及我们如何解决他们。

总的来说,这些变化对于依赖大量流量的服务来说可能是非常沉重的负担,所以你应该经常质疑自己的想法是否有错误。此外,我们并没有仅仅实现缓存迁移的短期目标,而是考虑了很多关于“我们可以用当前系统做出回应吗?”的问题。或“我们可以扩展吗?” 当将来出现类似的需求时。如果我们有缓存迁移的短期目标,我们会简单地根据现有的哈希算法增加服务器的数量。

当您考虑大型服务的架构时,您可能会遇到许多需要权衡取舍的情况。在这些情况下,提前计划并着眼于减少可能会失败以实现目标的场景的数量,而不是试图实现零碎的目标,这可能是解决问题的有效方法。

相关文章:

如何在大规模服务中迁移缓存

当您启动初始服务时,通常会过度设计以考虑大量流量。但是,当您的服务达到爆炸式增长阶段,或者如果您的服务请求和处理大量流量时,您将需要重新考虑您的架构以适应它。糟糕的系统设计导致难以扩展或无法满足处理大量流量的需求&…...

【GPT LLM】跟着论文学习gpt

GPT1开山之作:Improving language understanding by generative pre-training 本文提出了gpt1,即使用无标签的数据对模型先进行训练,让模型学习能够适应各个任务的通用表示;后使用小部分 task-aware的数据对模型进行微调&#xff…...

【玩转Docker小鲸鱼叭】Docker容器常用命令大全

在 Docker 核心概念理解 一文中,我们知道 Docker容器 其实就是一个轻量级的沙盒,应用运行在不同的容器中从而实现隔离效果。容器的创建和运行是以镜像为基础的,容器可以被创建、销毁、启动和停止等。本文将介绍下容器的这些常用操作命令。 1、…...

专项练习11

目录 一、选择题 1、执行下列选项的程序,输出结果不是Window对象的是() 2、以下哪些代码执行后 i 的值为10: 二、编程题 1、判断 val1 和 val2 是否完全等同 2、统计字符串中每个字符的出现频率,返回一个 Object&…...

ASP.NET+SQL通用作业批改系统设计(源代码+论文)

随着网络高速地融入当今现代人的生活,学校对网络技术的应用也在不断地提高。学校的教学任务十分复杂,工作也很繁琐,在教学任务中,作业的批改也是一个很重要的环节。为了提高老师工作效率,减轻教师的工作强度,提高作业批改的灵活性,《通用作业批改系统》的诞生可以说是事在…...

基于深度学习的高精度打电话检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度打电话检测识别系统可用于日常生活中或野外来检测与定位打电话目标,利用深度学习算法可实现图片、视频、摄像头等方式的打电话目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检…...

Vue搭建智能文本检索视频界面

前言 随着人工智能技术的发展,智能文本检索已经成为了一种非常流行的技术。在视频领域中,智能文本检索技术可以帮助用户快速找到自己需要的视频片段,提高用户的观看体验。本文将介绍如何使用Vue框架搭建一个智能文本检索视频界面&#xff0c…...

软考A计划-系统集成项目管理工程师-一般补充知识-中

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…...

springboot-内置Tomcat

一、springboot的特性之一 基于springboot的特性 自动装配Configuretion 注解 二、springboot内置Tomcat步骤 直接看SpringApplication方法的代码块 总纲: 1、在SpringApplication.run 初始化了一个上下文ConfigurableApplicationContext configurableApplica…...

Flink流批一体计算(2):Flink关键特性

目录 Flink关键特性 流式处理 丰富的状态管理 丰富的时间语义支持 Data pipeline 容错机制 Flink SQL CEP in SQL Flink 应用程序可以消费来自消息队列或分布式日志这类流式数据源(例如 Apache Kafka 或 Kinesis)的实时数据,也可以从各…...

2023软件工程中各种图在现代企业级开发中的使用频率

概览 系统流程图 ✔ 数据流图 不常用 ER图 ✔ 状态转换图 ✔ Warnier图 不常用 IPO图 不常用 Petri网 不常用 层次方框图 不常用 层次图 a.k.a. H图 ✔ 1,层次图描绘软件的层次结构.层层次方框图描绘的是数据结构。 2,层次图的方框表示模块或子模块。层次方框图的方框表示数据结…...

macOS Big Sur 11.7.8 (20G1351) 正式版 ISO、PKG、DMG、IPSW 下载

macOS Big Sur 11.7.8 (20G1351) 正式版 ISO、PKG、DMG、IPSW 下载 本站下载的 macOS 软件包,既可以拖拽到 Applications(应用程序)下直接安装,也可以制作启动 U 盘安装,或者在虚拟机中启动安装。另外也支持在 Window…...

【C++案例】一个项目掌握C++基础-通讯录管理系统

文章目录 1、系统需求2、菜单功能3、退出功能4、添加联系人4.1 设计联系人结构体4.2 设计通讯录结构体4.3 main函数中创建通讯录4.4 封装添加联系人函数4.5 测试添加联系人功能 5、显示联系人5.1 封装显示联系人函数5.2 测试显示联系人功能 6、删除联系人6.1 封装检测联系人是否…...

Triton教程 --- 动态批处理

Triton教程 — 动态批处理 Triton系列教程: 快速开始利用Triton部署你自己的模型Triton架构模型仓库存储代理模型设置优化动态批处理 Triton 提供了动态批处理功能,将多个请求组合在一起执行同一模型以提供更大的吞吐量。 默认情况下,只有当每个输入在…...

Python的并行(持续更新)

0. 参考: 《Python并行编程 中文版》https://python-parallel-programmning-cookbook.readthedocs.io/zh_CN/latest/index.html 1. 线程和进程: 进程可以包含多个并行运行的线程;通常,操作系统创建和管理线程比进程更省CPU资源&am…...

chatgpt赋能python:Python实现Fibonacci数列

Python实现Fibonacci数列 Fibonacci数列是一个非常经典的数列,定义如下: F ( 0 ) 0 , F ( 1 ) 1 F(0)0, F(1)1 F(0)0,F(1)1 F ( n ) F ( n − 1 ) F ( n − 2 ) F(n)F(n-1)F(n-2) F(n)F(n−1)F(n−2) 也就是说,第n个数等于前两个数之和…...

开环模块化多电平换流器仿真(MMC)N=6

模型简介: 运行环境MATLAB2021a 开环模块化多电平换流器仿真(MMC)N=6,连接负载,采用载波移相调制。 可以得到换流器输出N+1=7电平的相电压波形。可考虑线路阻抗。 子模块采用半桥结…...

java springboot整合MyBatis联合查询

前面文章 java springboot整合MyBatis做数据库查询操作写了springboot整合MyBatis的方法 并演示了基础查询的语法 根据id查 那么 我们这次来演示联合查询 我们staff 表 内容如下 每条数据 对应的都有一个departmentid 这是 department部门表的外键id department表内容如下 如…...

windows2022证书配置.docx

Windows证书的配置 要求两台主机,一台作为域,一台进入域 按要求来选择角色服务 确认之后安装 安装完以后配置证书服务 选择服务 按要求配置 注:此处不用域用户登陆无法使用企业CA 按要求来 创建新的私钥 这几处检查无误后默认即可 有效期…...

HCIP网络笔记分享——IA回顾及OSPF协议

第一部分 HCIA回顾1、网络基础2、动态路由协议3、路由认证4、路由控制(AD metric ) 一、知识巩固二、场景模拟1、获取IP地址1.1 DHCP --- 动态主机配置协议1.1.1 DHCP客户端1.1.2 DHCP服务器1.1.3 DHCP客户端1.1.4 DHCP服务器 2、打开浏览器3、路由器进行…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...

用递归算法解锁「子集」问题 —— LeetCode 78题解析

文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...

CSP信奥赛C++常用系统函数汇总

# CSP信奥赛C常用系统函数汇总## 一、输入输出函数### 1. cin / cout&#xff08;<iostream>&#xff09; cpp int x; cin >> x; // 输入 cout << x << endl;// 输出 优化&#xff1a;ios::sync_with_stdio(false); 可提升速度 2. scanf() /…...