首页 > 其他分享 >异地多活架构进阶:如何解决写后立即读场景问题?【转】

异地多活架构进阶:如何解决写后立即读场景问题?【转】

时间:2025-01-10 15:45:18浏览次数:1  
标签:场景 进阶 写后 写入 立即 多活 数据 节点

《醍醐灌顶!异地多活架构设计看这篇就够了》一文中,基于容灾需要,讨论了数据写入的架构模型。数据读取方面,重点在于解决读取请求的负载分担、路由选择的问题,对于容灾架构的选择影响不大。不过,其中的“写后立即读”场景,是个一致性范畴的问题,即写入的数据和写入后读到的数据是否一致的问题,本文不展开讨论各种一致性模型,只关注“写后立即读”的要求是数据写入后短时间内到来的读请求能够读取到最新写入的值这一具体问题,这是互联网应用中数据读取中比较独特和典型的场景,值得深入探讨,本文尝试分析一下这个问题的细节并探讨相应的解决思路。



图片

问题细节剖析

图片
   1.1 解决思路方向

 


写后立即读的问题是指一份数据在写完之后,很短时间内来读这份数据,读不到最新写入的值。解决这个问题,就需要读操作能够从最新写入了数据的节点获取数据,有几个方向:

  1. 单写单读,将所有需要写后立即读的请求都路由到唯一的写入点读取,可以保证能够读到最新写入的值;
  2. 多写多读,保证写入点个数(W)和读取点个数(R)的和大于节点总数(N),即 N < R + W,也就是 NRW 方案;
  3. 读时复制,在读节点收到读请求的时候,检测本节点的被读数据是否是最新的,不是的话,就等把最新的数据复制到位再返回。


在接入层、逻辑层、数据层的基础架构中,数据库层面具有最全貌的数据复制细节,可以刻画最精确的数据状态,如果能从数据库层面来着手,将从根本上解决写后立即读问题且做到业务无关,业务侧也会更轻松,例如上面的读时复制在数据库层面就比较容易做。不过,很多业务并不是运行在这么理想的数据库系统之上,还是不得不从业务侧来考虑解决思路。
NRW 是各节点对等的议会制度,用多数派解决读到新值的问题,根据读写量级压力调节 R 和 W 的数值来使系统达到一个较好的状态。这种模型,有请求量放大的问题,不管怎么调节 R 和 W 的数值,都只是把 R 和 W 的负载情况相对均衡,整体的读写代价增加是不可避免的。在跨城容灾场景下,NRW 方案成本较高,不太能接受,因为:

  1. 如果每次都要读多个节点,那基本上就面临着读请求都要跨城;
  2. 如果每次都就近读1个节点,那就要求写入的时候要写入所有节点。


所以,很多业务都不采用对等机制来维护数据,而是采用主从模式,主写点写入之后,出于容灾的考虑,会等主写点数据复制到部分从节点后才算成功写入。为什么不复制到所有的从节点呢?因为重点在容灾,保证在主写点之外有冗余数据,并不追求各节点的数据完全一致。这样,就等同于 NRW 中的 W 是 1 < W < N,但是这一批写入点不是对等的,而是通过主从复制达到写 W 个节点的效果。读操作方面,基本都是读1次,这样就不能满足 N < R + W 了。在这种主从架构下,要想写后立即读到新值,基本就是去读主写点了,退化成了“单写单读”的情况,这就是本文要讨论的模型了。
   1.2 业务架构案例

 


为了避免过于宽泛,下面以作者工作中碰到的典型的三地五中心跨城容灾架构来展开讨论,希望针对该典型模型的探讨能把问题核心聊清楚,在结合实际情况设计方案的时候有所启发。关于下图架构的几点说明:

  • 主从复制模式是半同步模式,只要求主写点收到2份数据复制确认,保证在本城之外有一份冗余数据后即提交成功,但是2份数据复制确认具体是哪2个从节点来的,不确定;
  • 数据层为了屏蔽容灾、运营动作导致的读写节点变更对上层调用放透明,通过名字服务提供读写访问,提供了写名字、读名字,写名字指向主写点,读名字指向所有节点提供就近访问能力;
  • 如果要应对写后立即读,那么在做读操作路由的时候,得选择写名字获得主写点进行数据读取。


图片
   1.3 解决方案模型

 


从业务架构案例的架构图来看,好像和NRW的多R情况类似,每次读都在做跨城读取。其实不然,可以把“写后立即读”细拆如下几点来看:

  1. 写源:即写操作的发起来源,大抵可以分两类,一类来源是用户触发,另一类是后台触发。差别在于,用户触发一般是单个细粒度的写更新,后台触发往往是大批量的写更新,结合读需要,二者对于写点的压力是不同的;
  2. 架构:在一主N从的存储架构下,数据在主写节点写入之后,还没有同步到某从节点的情况下,读请求打到该从节点上,就产生了读不到新值的问题;
  3. 时效:一个是数据写入之后读请求到来之前的时间差,记写后读间隔,也就是“写后立即读”的立即是多立即;另一个是数据写入后和复制到从的时间差,记写复制时延。如果写复制时延大于写后读间隔,就会产生读不到新值的问题。基本上很难保证写复制时延一定小于写后读间隔;
  4. 读者:即写入数据的读取使用方,和写源类似,一类是真实用户,一类是后台程序。后台程序基本上都是可以采用异步的方式解决即可,大都不用考虑“立即”的问题,写后立即读重点在于解决用户的“立即读“需要;
  5. 场景:一份数据的使用场景基本上都是多样的,并不是所有的场景都有写后立即读的诉求,往往都是解决少量核心场景的需要即可;
  6. 范围:在数据全集中,一个时间段内有多少数据是需要面临写后立即读问题?从写源分析来看,用户触发的写显然是小范围的,后台触发的写是大范围的,但是这种大批量往往可以做时间段拆分,可以缩减范围,再考虑真实用户带来的读,也就是小范围的了。“小范围”结合“少场景”,这就是一个典型的“局部性”问题。


可以看到,解决写后立即读问题,并不需要所有请求都去主写节点,只要把“刺头”挑出来即可,也就是要寻找一种方案:该方案需要标识出哪些数据有写入操作,在特定时间段内特定场景的读请求到来时,数据不确定是否同步到从副本的情况下,引导这部分请求去读主写点。在异地多活场景下,读请求到来的接入点所在地和数据所在地可能是跨城的,如果读请求的时延要求比较敏感,还需要在写入后的短时间内新数据能够提供就近访问,避免跨城。总结一下要点如下:

  1. 区分业务场景;
  2. 标识写入数据;
  3. 判断时延要求;
  4. 提供就近访问。


这4点,是基于局部特征,层层下钻的过程,下面分别来看看。

图片

区分业务场景

图片
区分业务场景,指的是如何把有写后立即读的“刺头”场景标识出来。基本可以从服务调用方和服务提供方两端视角来看:

  1. 服务调用方视角,服务的不同调用方根据需要,在调用服务的时候申明请求是否有写后立即读的诉求,可以通过服务提供方在协议上定义协议字段让调用方申明诉求;
  2. 服务提供方视角,服务提供方为不同的调用方分配标识,在服务提供方内部管理调用方属性,将有写后立即读诉求的调用方标识出来;
  3. 一般来说,服务提供方视角的方式具有更好的可控可管特性,不太容易被调用方滥用,比较推荐。


明确了读写场景,每个用户读请求到来的时候,判断一下场景属性,如果是不需要写后立即读的场景,访问本地就近的数据副本即可,无需关心该副本是否有最新数据。对于有写后立即读需要的场景,则需要做进一步的判断处理。
图片

图片

标识写入数据

图片
如何标识某份数据有写入,有两个方向:

  1. 用户触发写入的场景,可以在给用户回包的时候,把写入的信息带上,立即读的时候回带,后台可以直接用来做判断;
  2. 不论哪种写操作发起来源,由后台统一记录最近写入的信息,请求到来的时候,先访问一下记录的写入信息,再行判断是否有最近写入。这里可以更进一步,不光记录数据是否有写入的标识,还可以考虑把完整的写入数据也记录下来;
  3. 后台统一记录的处理方式更有普适性,上面提到的两种典型场景,不论是用户写后立即读,还是后台写后用户立即读,都能很好应对。


不管是用户端传递携带写入记录标识,还是后台存放写入记录标识,都在数据库之外引入了一套额外的依赖机制,会增加复杂度,引入的机制可靠性上相较于数据库来说,也是会有所折损的。不过,写后立即读主要解决的是用户体验层面的问题,应该说一般是能够接受的。当然,具体还是需要结合业务实际仔细评估。
有了写入数据的标识,用户读请求到来的时候,先读取一下最近写入的标识,判断一下,如果最近没有写入,说明本地副本已经有了最新的数据,访问本地就近的数据副本即可。如果最近有写入,那么需要进一步判断处理。
图片


图片

判断时延要求

图片
读场景往往有较高的性能要求,处理时延是一个很重要的指标,在异地多活的跨城架构中,都会提供本地的就近访问副本,以达到低延时的目标。不过,普通的读副本并不具备提供最新写入数据的访问能力。写后立即读的情况,其时延需要要考虑的主要因素包括:

  1. 跨城往返时延大约 30ms,这种时延是否可以接受?
  2. 读请求需要读取的数据,是否有多份?多份数据是否都有写后立即读的要求?
  3. 多份数据的读取,是有前后依赖需要串行读取?还是可以并发读取?
  4. 上面的几个问题,需要综合考虑整个业务多种场景,且适当考虑未来,当前可以满足需要,未来是否依然?


明确了业务的时延要求后,对于要读到最新值的读请求,如果时延要求没那么高的,引导读主写点即可,否则,就需要提供就近访问能力。下面是以比较通用的后台记录写入标识模式来说明时延的示意图。
图片

图片

提供就近访问

图片
写后立即读的就近访问,要求提供就近访问的副本保证有最新数据,而我们讨论的数据层架构是保证不了的,这就需要业务层在把数据成功写入数据层后,额外往各读请求接入所在地写一份数据,以达到就近访问的目的。这种情况下,可以扩展上文“标识写入数据”提到的写入记录,不光记录写入标识,同时记录写入的具体数据。下面是简化的处理示意图,就近副本的定位,是用来解决写后立即读的问题,结合读请求不会污染数据,以及业务侧来实现强一致比较麻烦,设计上可以轻量化,例如:

  1. 第2步写入数据之后,就可以并行回包,以及并行写多份就近副本了;
  2. 在写就近副本的时候,可以采用轻量的 CAS 写入保障,失败的情况下,可以适当增加重试次数;
  3. 增加短时的异步对账,检测就近副本和主写点之间的差异,让失败的影响控制在很小的时间范围之内;
  4. 对于异步写入就近副本的方式,可以提供封装好的 API,提供给有需要的服务,降低使用成本。


图片

图片

解决思路总结

图片
写后立即读是比较典型的局部性问题,如果能够在数据库层面根据主从数据复制细节,刻画局部特征,解决起来会事半功倍。本文根据该问题的局部性特征,从业务侧角度,总结了区分业务场景、标识写入数据、判断时延要求、提供就近访问四步的解决思路,层层递进下钻,细化局部特征。

转自

异地多活架构进阶:如何解决写后立即读场景问题?
https://mp.weixin.qq.com/s/lTBPto7vNsK1h1xlZ_qkKw

 

标签:场景,进阶,写后,写入,立即,多活,数据,节点
From: https://www.cnblogs.com/paul8339/p/18664083

相关文章

  • 异地多活架构如何设计:活好你也好【转】
    异地多活是分布式系统架构设计的一座高峰,当业务系统走到需要考虑异地多活这一步,其体量和复杂度都会达到很高的水准。接入层、逻辑层、数据层的三层架构,基本上是每个业务都会拥有的基础架构形态,而三层架构的关键在于数据层,本文将从数据层切入探讨异地多活对于基础架构设计的影响。......
  • 洛谷题单指南-线段树的进阶用法-P3157 [CQOI2011] 动态逆序对
    原题链接:https://www.luogu.com.cn/problem/P3157题意解读:长度为n的序列,序列是1~n的排列,一共m个删除操作,每一个删除之前输出逆序对。解题思路:要计算静态的逆序对,可以通过树状数组、权值线段树等方式,时间复杂度都是O(nlogn)要计算动态的逆序对,算上每一次删除,暴力做法需要O(mnlo......
  • Stable Diffusion超详细教程!从0-1入门到进阶
    一、本地部署StableDiffusion(全套教程文末领取哈)前言目前市面上比较权威,并能用于工作中的AI绘画软件其实就两款。一个叫Midjourney(简称MJ),另一个叫Stable-Diffusion(简称SD)。MJ需要付费使用,而SD开源免费,但是上手难度和学习成本略大,并且非常吃电脑配置(显卡、内存)。E和Mid......
  • Spring Bean生命周期管理:高手进阶的必修课
    SpringBean的生命周期就像一颗种子的成长过程,经历了从播种到发芽、成长、开花、结果,最终凋零的各个阶段。播种阶段(Bean定义与配置):就像农民将种子播撒在土壤中,为种子的生长做好准备。在Spring中,这是Bean定义的阶段,通过XML配置、注解或Java代码等方式,将Bean的定义信息注册到......
  • 学习笔记:C#高级进阶语法——委托(Delegate)
    四、委托4.1、什么是委托,委托的本质是什么呢?​ 1、形似一个方法,用delegate修饰符修饰。所谓委托,ILSpy反编译识别底层----生成一个一个的类。如果定义在class外部:独立生成一个类,如果定义在class内部,生成了一个类中类:包含一个2、所以委托的本质:就是一个类。4.2、委托的实例化,......
  • Flutter进阶(5):EventBus全局事件总线
    一、EventBus的基本概念FlutterEventBus是一种用于在Flutter应用程序中实现组件间通信的事件总线机制。可以用于在应用程序中实现各个组件之间的通信。它基于发布/订阅模式,允许组件订阅感兴趣的事件,并在事件发生时接收通知。二、FlutterEventBus的工作原理FlutterEventBu......
  • 【AIGC-ChatGPT进阶提示词指令】职场老油条的生存智慧:化解办公室困境的艺术
    引言在现代职场中,每个人都可能遇到各种挑战和困境。从项目管理的突发变更,到薪资谈判的微妙博弈,再到功劳归属的争议,这些都考验着职场人的智慧和情商。本文将通过实际案例,深入剖析职场常见困境的应对之道,助你在职场中游刃有余。最近比较忙,可能更新不及时,这两天忙完就恢复......
  • 【AIGC-ChatGPT进阶提示词指令】解析职场人群的心理密码
    今天逛某瓣,发现有人分享了一个【人生四季照片】,挺有意思的,然后就结合咱们的工作,想着能不能把【职业也进行四季的具象化】,所以就有了这篇文章。引言在当代职场中,每个专业领域都如同一个独特的小宇宙,塑造着从业者特定的思维方式、行为模式和情感体验。本文将深入剖析金融投......
  • 【AIGC-ChatGPT进阶提示词指令】AI美食助手的设计与实现:Lisp风格系统提示词分析
    引言在人工智能助手的应用领域中,美食烹饪是一个既专业又贴近生活的方向。本文将详细分析一个基于Lisp风格编写的美食助手系统提示词,探讨其结构设计、功能实现以及实际应用效果。提出你的菜系,为你分析,并生成图片卡片提示词在最下方效果图系统架构设计核心角色定......
  • 让 AI 更懂你:微调、RLHF、强化学习微调和偏好微调,大模型训练的“进阶秘籍”
    以ChatGPT为代表的大语言模型(LLM)展现出了惊人的能力,能写诗、作画、编代码,甚至和你聊天谈心。但你知道这些聪明的AI模型是如何炼成的吗?除了海量数据的“喂养”之外,还需要一些特殊的训练技巧,才能让它们更好地理解和执行我们的指令。(关注公众号“AI演进”,获取更多AI知识)1.微......