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

news2024/10/6 14:25:02

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

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

图片描述

系统架构中的缓存

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

大规模消息服务中的缓存

图片描述

消息服务中的常见流程

由于 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当时,天气和其他背景因素。我们认为这些测试很难在开发环境中覆盖,所以我们想通过在生产环境中运行多个金丝雀测试来弥补。

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

迁移

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

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

结论

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/664037.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第三章 decimal模块

1. decimal 模块介绍 decimal 模块是 Python 提供的用于进行十进制定点和浮点运算的内置模块。使用它可以快速正确地进行十进制定点和浮点数的舍入运算,并且可以控制有效数字的个数。 使用 decimal 模块主要是因为它与 Python 自带的浮点数相比,有以下…

关于Stream流和Lambda表达式,这些技巧你都知道吗?

💧 关于 S t r e a m 流和 L a m b d a 表达式,这些技巧你都知道吗? \color{#FF1493}{关于Stream流和Lambda表达式,这些技巧你都知道吗?} 关于Stream流和Lambda表达式,这些技巧你都知道吗?&…

2014年全国硕士研究生入学统一考试管理类专业学位联考写作试题

2014年1月真题: 四、写作:第56~57小题,共65分。其中论证有效性分析30 分,论说文35分。 56.论证有效性分析: 分析下述论证中存在的缺陷和漏洞,选择若干要点,写一篇600字左右的文章,对该论证的有效性进行分析和评论。…

马克思第二章

1.实践和认识 实践决定认识,认识又反作用于实践 实践的特点: 1.直接现实性 2.自觉能动性 3.社会历史性 实践和认识的关系 1.实践是认识的来源 2.实践是认识的目的 3.实践是认识的发展动力 4.实践是检验认识真理的唯一标准 5.认识又反作用于实践&#xf…

gocv Windows10下编译和安装(opencv4.7)

opencv居然还没有官方的golang版,出乎意料。为了编译安装这玩意,折腾了一下午,记录下: 资源提前下载 1、 MinGW-w64 这里的坑是对于只懂一点点的人,容易选错版本: 没仔细看的人很可能会选win32的&#x…

【EDA软件互转】PADS转Allegro

1. 使用pads软件打开PCB文件,然后执行菜单命令:File->Export->弹出的对话框中点击“保存”。然后按下图设置后点击“OK”按钮,会在当前目录下生成一个前面保存的asc文件;如果点击OK后有弹出其它提示就点击“确定”就好…

在编写测试报告的时候,我们有哪些点需要注意的呢?

测试报告作为测试人员的核心输出项,是体现自己工作价值的重要承载工具,需要我们认真对待,所以我们要重视测试报告的输出,那么在编写测试报告的时候,我们有哪些点需要注意的呢? 1、不要乱用模板 很多测试新…

CTR预估之WideDeep系列(下):NFM/xDeepFM

在上一篇文章中CTR预估之Wide&Deep系列模型:DeepFM/DCN,学习了Wide & Deep这种通用框架:wide组件的线性模型的显性低阶特征交叉提供记忆能力,deep组件的深度网络模型的隐式高阶特征交叉提供泛化能力,还有DeepFM和Deep&…

蓝桥杯刷题篇①

前言:hello各位童学们好呀!许久不见!本文为本人的蓝桥杯OJ的刷题笔记!文章隶属于专栏蓝桥杯,该专栏的目的是为了记录自己的刷题记录和学习过程,激励自己不断前行,为明年的ACM、ICPC、蓝桥杯等比…

CVPR2023最佳论文提名(12篇)

CVPR2023公布了12篇最佳论文候选文章。(直接点击标题可以查看原文~) Ego-Body Pose Estimation via Ego-Head Pose Estimation 单位:Stanford-----------关键词:姿态估计 3D Registration With Maximal Cliques 单位&…

三层交换机与路由互联配置(华为设备)

#三层交换机与路由器配置配置 #三层交换机与路由器配置配置 路由器配置 #进入系统视图 <Huawei>system-view #关闭系统提示信息 [Huawei]undo info-center enable #配置一个环回口 [Huawei]int LoopBack 0 #配置IP地址 与 掩码 [Huawei-LoopBack0]ip address 1.1.…

基于matlab使用自定义辐射方向图进行天线阵列分析(附源码)

一、前言 此示例演示如何使用自定义天线辐射方向图创建天线阵列&#xff0c;然后如何分析阵列的响应方向图。这种模式可以通过测量或模拟获得。 二、导入辐射图 根据应用的不同&#xff0c;实用的相控天线阵列有时会使用专门设计的天线元件&#xff0c;其辐射方向图无法用闭式方…

Java018——Java方法

什么是方法&#xff1f; 方法的作用&#xff1f; 方法的定义 方法的使用 一、什么是方法&#xff1f; Java方法是语句的集合 二、方法的作用&#xff1f; 它们&#xff08;语句&#xff09;在一起执行一个功能。 三、方法的定义 格式&#xff1a; 修饰符 返回值类型 方法名…

PostgreSQL(九)内置系统视图

目录 一、系统视图二、 pg_stat_activity 视图1.简介2.核心字段3.全部字段 一、系统视图 PGSQL 中提供了一系列内置的视图&#xff0c;包括系统视图和其他视图。 系统视图提供了查询系统表的一些便利的访问方法。其他视图提供了访问内部服务器状态的方法。 官方文档&#xf…

Spring Boot是什么?详解它的优缺点以及四大核心

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、Spring Boot 是什么&#xff1f; 二、Spring Boot 的优缺点 1、优点 ①可快速构建独立的 Spring 应用 ②直接嵌入Tomcat、Jett…

【Python GUI编程系列 01】安装python pycharm 和 pyside6

Python GUI编程系列 01 安装python pycharm 和 pyside61、安装python2、安装pycharm3、安装 pyside6 安装python pycharm 和 pyside6 本系列使用python3 pycharmpyside6 来进行python gui设计&#xff0c;首先我们来配置编程环境 PS&#xff1a;为了减少复杂程度&#xff0c;本…

学习HCIP的day.15

目录 三层架构 一、网络拓扑冗余 1、线路冗余 2、设备冗余 3、网关冗余 4、电源冗余 二、三和一&#xff08;网关、根网桥、SVI&#xff09; 三、管理vlan 四、三层交换机 五、网关冗余 六、名词注解&#xff1a; 七、数据交换方法&#xff1a; 1、原始交…

STM32开发——ADC(烟雾传感器)

目录 1.ADC简介 2.项目简介 3.CubeMX设置 4.函数代码 1.ADC简介 作用&#xff1a;用于读取电压值&#xff0c;然后转换为数字量传给单片机&#xff0c;单片机再通过计算&#xff0c;可以得到电压值。 ADC的性能指标 量程&#xff1a;能测量的电压范围分辨率&#xff1a;A…

简聊关于Flutter的争议~

关于Flutter的争议 Flutter是谷歌的推出的跨平台UI框架&#xff0c;可以快速在iOS和Android上构建高质量的原生用户界面&#xff0c;可以与现有的代码一起工作。在全世界&#xff0c;Flutter正在被越来越多的开发者和组织使用&#xff0c;并且Flutter是完全免费、开源的。这是…

机器学习课程报告——基于机器学习的自动人脸识别研究

摘 要 生物特征识别技术使用了人体本身所固有的生物特征&#xff0c;与传统的身份识别方法完全不同&#xff0c;具有更高的安全性、可靠性、和有效性&#xff0c;越来越受到人们的重视。人脸识别技术作为生物特征识别技术的重要组成部分&#xff0c;在近三十年里得到了广泛的关…