Sermant在异地多活场景下的实践

Sermant社区在1.3.0和1.4.0版本相继推出了消息队列禁止消费插件和数据库禁写插件,分别用于解决异地多活场景下的故障切流和保护数据一致性问题。本文将对Sermant在异地多活场景下的实践进行剖析。

一、异地多活

1.1 什么是异地多活

对于一个软件系统,我们希望当系统出现故障时仍然可以正常对外提供服务,软件系统的这种特性称之为高可用, 异地多活架构便是用来解决高可用问题的。

最早的系统架构一般为单机架构,当数据库出现故障时,可能会导致业务长时间中断。为了解决这一问题,数据库发展为由主库和从库组成,主库负责读和写操作,从库只提供读操作,主数据库的数据会实时同步至从数据库保持数据的一致性和完整性。当主库出现问题时,从库切换为主库继续工作。不过,这些服务都部署在同一机房甚至是同一个机柜,当机房出现故障后,系统仍然不能正常对外提供服务。

此时,同城双活成为很好的解决方案,在一个城市部署两个机房,两个机房部署相同的软件环境,并且均提供服务。当其中一个机房出现故障时,可以将流量切换至另一个机房继续执行,以保证系统的高可用。如图一所示,机房1数据库为主数据库,两个机房所有的写操作均操作机房1的主数据库,读操作则可以读取本机房的数据库。两个机房部署的物理距离较近,同时两个机房可以使用专线进行网络连接,因此不同机房服务调用的网络延迟较低,机房2的服务写入机房1的数据库时延在可接受范围内。

图一:同城双活架构图

同城双活架构很好地解决了软件系统的高可用问题,但是城市如果出现了自然灾害,比如地震、水灾等,这些部署在同一城市的所有机房仍然会受到损害从而停止提供服务。并且因为这些灾害的破坏性较强,系统修复的周期也会相对漫长,会严重影响公司业务的正常运行。在这种情况下,很明显需要这些机房部署在不同的地域,同时这些地域的地理距离需要足够遥远,这样就能抵抗自然灾害的风险,这就是异地多活架构的由来和价值所在。

针对上图,机房1和机房2如果部署在两个城市,就变成了异地双活,为了更好的抵御风险,可以在多个地域部署机房,这样异地双活就升级为了异地多活。

异地多活的架构图如图二所示,客户端的流量通过路由层分发至不同的地域机房执行。和同城双活架构不同的一点在于不同地域的机房物理距离遥远,部署网络专线的成本巨大且不现实,不同机房之间访问的网络时延是不可忽视的,因此需要操作本机房内的数据库,不能跨机房操作。在异地多活架构下,每个机房的数据库均为主库,不同机房的数据会同步至中心机房,并由中心机房再同步至其他机房。因为所有机房的数据库都可以写入,当不同机房修改同一条数据时,就不可避免的引入了数据冲突的问题。为了解决数据冲突,可以在路由层根据分片策略使一些流量固定转发到某一机房,流量分片的策略可以基于业务类型或地理位置。通过流量分片,保证同一用户的相关请求,会路由至同一个机房内完成所有业务操作,并且机房内的流量保证只在本机房内流转,降低网络延迟。

图二:异地多活架构图

1.2 异地多活典型场景

异地多活架构通过在不同地域部署机房对外提供服务来抵御自然灾害带来的风险,是实现系统高可用的有效手段。但是,异地多活架构也使系统变得更加复杂,在故障切流、数据一致性等方面引入了新的需求:

  1. 云服务场景下,当某可用区发生故障时,需要故障区的消费者停止拉取消息进行消费,同时将已分配的消息队列重平衡给正常可用区的消费者处理,从而避免引发业务异常。
  2. 异地多活通过对流量分片处理,可以很好地解决数据一致性问题。但是对于全局数据,比如商品数量,在写入数据时,只允许操作中心机房的全局数据库。一般需要将操作全局数据的流量路由至中心机房,其他机房只允许读该数据库。当流量路由错误时,仍可能会写入非中心机房的数据库,导致数据冲突问题。此时需要对全局数据库添加防护,在非中心机房禁止写操作的执行。

针对以上两个典型问题,Sermant分别开发了消息队列禁止消费插件和数据库禁写插件来处理,下文将详细介绍。

二、消息队列禁止消费插件

2.1 消息队列禁止消费插件介绍

消息队列禁止消费插件允许微服务在运行态根据实际需求动态调整消费者对消息队列中间件的消费行为,确保在非正常环境或状态下,业务处理流程中的消息得到妥善管理,避免不必要的业务影响。例如,在异地多活架构系统中,如果发生区域性故障需要对流量做切流处理时,可在发生故障的可用区开启消息队列禁止消费功能,让正常可用区的消费者来处理业务,避免故障区域消费流量从而导致业务异常,保障系统的高可用。待故障处理完成后,可重新开启消费。

消息队列禁止消费插件目前支持Kafka和RocketMQ两种消息中间件。在Kafka方面,该插件实现了Topic级别的禁止和恢复消费功能。对于RocketMQ, 控制消费的粒度为消费者实例级别。Sermant支持通过配置中心下发需要禁止消费的消息队列类型和具体Topic。

关于消费队列禁止消费插件更多的介绍、配置说明和场景演示等请参考官网文档消息队列禁止消费。

2.2 消息队列禁止消费插件故障切流场景应用

应用场景:某软件系统使用Kafka作为消息队列,生产者往topic-test主题生产消息,该topic消息包含四个partition。可用区A和可用区B各有两个消费者加入test消费者组并消费topic-test的消息,每个消费者各分配一个partition,其中可用区A和可用区B分布在不同地域,即异地多活的两个机房。如下图所示。

该场景下,消费者服务通过挂载Sermant的消息队列禁止消费插件运行后,可以实时控制消费者消费的主题,从而确保在非正常环境或状态下,业务处理流程中的消息得到妥善管理。

当可用区A发生故障后,可用区A的消费者应该停止消费。在可用区A下发全局配置禁止消费者A和消费者B消费topic-test主题,并释放已分配的消息队列。

消息队列禁止消费插件的配置如下所示,enableKafkaProhibition表示开启Kafka队列禁消费能力,kafkaTopics指明需要禁止消费的订阅主题Topic。下发配置的方式请参考官网文档消息队列禁止消费:

enableKafkaProhibition: true  
kafkaTopics:  
 - topic-test 

配置下发后,可用区A的消费者停止消费,可用区B消费者重新分配topic-test主题的partition,如下图所示。

待可用区A恢复正常后,可以重新通过动态配置中心下发配置,开启消费者A和B对topic-test主题的消费。开启消费配置下发后Kafka将触发重平衡,可用区A和B的消费者重新分配partition。

消息队列禁止消费插件实现了异地多活场景下消息队列的故障切流能力,保障了系统的可用性。

三、数据库禁写插件

3.1 消息队列禁止消费插件介绍

服务在挂载数据库禁写插件启动后,可以动态开启或关闭对指定数据库的禁止写入能力。在异地多活场景下,用户希望停止对个别或全部数据库的写入操作,仅允许读取数据,以保证数据库系统的数据完整性、一致性和安全性。比如,某业务数据库全局数据写入仅允许操作中心机房,通过开启数据库禁写插件,使路由异常流量写入非中心机房数据库失败;多地多写场景下,对流量手动切流前,被切流的机房先禁止写入数据库,等待其他机房数据同步完成后,再进行切流。以上场景中数据库禁写插件的使用保障了数据库数据的一致性。

数据库禁写插件目前支持MySQL、MongoDB、PostgreSQL和OpenGauss数据库。在微服务运行时,可以通过配置中心下发禁写的数据库类型和名称。支持禁写的具体写操作和插件使用方式请参考官网文档数据库禁写。

3.2 数据库禁写插件保护数据一致性应用

应用场景:异地多活架构下,某业务微服务用于修改商品库存等全局数据,同时全局数据保存在名为global的MySQL数据库中。对于该全局数据,写操作仅允许操作中心机房的global数据库,其他机房的global数据库只能读取数据。为了保证数据一致性,当修改全局数据时,该流量在路由层被路由至中心机房执行,其他读操作可路由至任意机房,如下图所示。

当路由层对写全局数据的流量发生路由错误从而在非中心机房执行时,如果中心机房和非中心机房同时修改同一商品的数量,就可能导致数据冲突问题,为了防止这种情况的发生,业务微服务可以挂载Sermant的数据库禁写插件,禁止在非中心机房写入global数据库。

在非中心机房禁止写入global数据库,需要通过动态配置中心下发如下配置:

enableMySqlWriteProhibition: true  
mySqlDatabases:  
 - global

其中,enableMySqlWriteProhibition表示开启对MySQL数据库的禁写能力,mySqlDatabases用于指明具体的禁写数据库名称,本示例为global数据库。

下发配置后,当路由异常的流量在非中心机房写入global数据库时,数据库禁写插件对业务微服务抛出java.sql.SQLException异常,并禁止写入该数据库。业务系统需要处理该异常,比如加入重试操作重新路由该流量至中心机房执行,以保证系统的正常运行,执行逻辑如下图所示。

数据库禁写插件在异地多活场景下禁止对指定数据库的写入能力可以防止异常流量的写操作,保证不同机房数据库的数据一致性。

四、总结

在异地多活场景下,Sermant的消息队列禁止消费插件可以实现可用区故障时消息队列的切流问题,让正常可用区的消费者消费数据;数据库禁写插件则用于禁止写入指定的数据库,并且不影响读数据库,防止发生数据冲突问题。

Sermant在异地多活场景实现了丰富的服务治理能力,未来,Sermant还将持续发力,逐步构建更加完善的服务治理能力体系。


Sermant作为专注于服务治理领域的字节码增强框架,致力于提供高性能、可扩展、易接入、功能丰富的服务治理体验,并会在每个版本中做好性能、功能、体验的看护,广泛欢迎大家的加入。

  • Sermant 官网:Sermant
  • GitHub 仓库地址:https://github.com/huaweicloud/Sermant
  • 扫码加入 Sermant 社区交流群

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于GEE遥感影像处理和长时序土地分类以及生物量估算分析

简介 Google Earth Engine云平台是目前全球范围内测绘领域内使用最为广泛的遥感云计算平台,其凭借强大的数据存储和云计算能力,极大了提高了全球科研工作者的科研产出,每年借助GEE平台发布的各类期刊论文超1000篇,在海量遥感数据的…

人脸美型SDK解决方案,适用于各类应用场景

视频内容已经成为企业宣传、产品展示、互动直播等多个领域的核心载体。而在这些场景中,高质量的人脸美型效果不仅能够提升用户体验,更能为品牌加分。美摄科技凭借深厚的技术积累和行业洞察,推出了全新的人脸美型SDK解决方案,为企业…

Spring IoCDI(3)—DI详解

目录 一、属性注入 二、构造方法注入 小结:构造函数的注入 三、Setter注入 四、三种注入的优缺点分析(面试题) 1、属性注入 优点: 缺点: 2、构造方法注入(Spring4.X推荐) 优点&#x…

JetBrains DataGrip v2024.1 激活版 (多引擎数据库管理开发)

JetBrains系列软件安装目录 一、JetBrains IntelliJ IDEA v2024.1 安装教程 (Java集成开发IDE) 二、JetBrains WebStorm v2024.1 激活版 (JavaScript集成开发IDE) 三、JetBrains PhpStorm v2024.1 安装教程 (PHP集成开发IDE) 四、JetBrains PyCharm Pro v2024.1 安装教程 (…

5W 1.5KVDC、3KVDC 宽电压输入 DC/DC 电源模块 ——TP05DA 系列

TP05DA系列电源模块额定输出功率为5W,外形尺寸为31.75*20.32*10.65,应用于2:1及4:1电压输入范围 9V-18V、18V-36V、36V-72V、9V-36V和18V-72VDC的输入电压环境,输出电压精度可达1%,具有输出短路保护等功能,可广泛应用于…

06-07 -变量的高级主题

---- 整理自狄泰软件唐佐林老师课程 文章目录 1. 变量值的替换2. 变量的模式替换3. 规则中的模式替换4. 变量值的嵌套使用5. 命令行变量6. 环境变量7. 目标变量(局部变量)8. 模式变量9. 工程 1. 变量值的替换 使用指定字符(串)替…

华人团队用大模型实现“读心术”:大脑活动直接变文字

NeurIPS收录的一项新研究,让大模型也学会“读心术”了! 通过学习脑电波数据,模型成功地把受试者的脑电图信号翻译成了文本。 而且整个过程不需要大型设备,只要一块特制的“头巾”就能实现。 这项成果名为DeWave,能在…

观测云 VS ELK:谁是日志监控的王者?

前言 作为 IT 信息系统运行状态感知和故障分析的重要手段,日志在行业兴起之初便为运维和开发环节所广泛应用。当应用和系统发生故障或出现问题时,日志数据成为了排查和诊断问题的重要依据。通过分析日志,开发人员和运维人员可以了解系统的运…

Redis是什么? 日常运维 Redis 需要注意什么 ? 怎么降低Redis 内存使用 节省内存?

你的项目或许已经使用 Redis 很长时间了,但在使用过程中,你可能还会或多或少地遇到以下问题: 我的 Redis 内存为什么增长这么快?为什么我的 Redis 操作延迟变大了?如何降低 Redis 故障发生的频率?日常运维…

LeetCode刷题记(五):121~150题

121. 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从…

59-ARM与FPGA间RGMII通信电路设计

视频链接 ARM与FPGA间RGMII通信电路设计01_哔哩哔哩_bilibili ARM与FPGA间RGMII通信电路设计 第2课:千兆以太网电路设计 第3课:万兆网电路设计 第49课:PCIE转网口电路设计 第50课:RGMII & SGMII & QGMII电路设计 1、…

在做题中学习(51): x的平方根

69. x 的平方根 - 力扣(LeetCode)​​​​​​ 解法:二分查找 思路:看示例2: 可以看到8的平方根是2.82,在2^2和3^2之间,所以可以把数组分为两部分,(具有二段性) 而2.82去掉小数部…

java线上问题排查之内存分析(三)

java线上问题排查之内存分析 使用top命令 top命令显示的结果列表中,会看到%MEM这一列,这里可以看到你的进程可能对内存的使用率特别高。以查看正在运行的进程和系统负载信息,包括cpu负载、内存使用、各个进程所占系统资源等。 2.用jstat命令…

CCE云原生混部场景下的测试案例

背景 企业的 IT 环境通常运行两大类进程,一类是在线服务,一类是离线作业。 在线任务:运行时间长,服务流量及资源利用率有潮汐特征,时延敏感,对服务SLA 要求高,如电商交易服务等。 离线任务&…

shell脚本脚本变量

shell脚本的概念: 1.讲要执行的命令按顺序保存到一个文本文件 2.给文件可执行权限 3.可以结合各种shell控制语句以完成更复杂的操作 linux中包含shell的文件有 [rootlocalhost ~]# cat /etc/shells /bin/sh #UNIX最初使用的 shell,已经被…

AI编码时代到来?实现编程梦想的利器—Baidu Comate测评

文章目录 Comate智能编码是什么?Comate支持的环境 Comate应用安装实际操作对话式生成代码生成代码注释智能单测项目测试调优功能 总结 Comate智能编码是什么? 在如今这个拥抱AI的时代,市面上已经产出了很多Ai代码助手,如果你还没…

Java clone

Java clone 原型模式用一个已经创建的实例作为原型,通过复制(clone)该原型对象来创建一个和原型对象相同的新对象。Java中对象克隆需要重写Object.clone()方法,并实现Cloneable接口。 浅克隆 浅克隆仅仅克隆本对象,…

关于Oracle 23ai 你要知道的几件事情

1.版本生命周期 23ai发布后的Oracle版本生命周期图,可以看到23ai是长期支持版本可以到2032年。 引申 Oracle版本分为两类 Innovation Release--创新版本,一般提供至少两年技术支持 Long Term Release --长期支持版本,一般提供5年premier和…

MacOS快速安装FFmpeg,并使用FFmpeg转换视频

前言:目前正在接入flv视频流,但是没有一个合适的flv视频流地址。网上提供的flv也都不是H264AAC(一种视频和音频编解码器组合),所以想通过fmpeg来将flv文件转换为H264AAC。 一、MacOS环境 博主的MacOS环境(…

DAPP开发:揭秘DAPP软件开发的秘密

随着区块链技术的飞速发展,DAPP(去中心化应用)的开发逐渐成为了一个热门话题。在本文中,我们将探讨如何从零开始开发DAPP软件,并深入思考DAPP开发中的关键问题。 一、了解DAPP开发的基础知识 在开始开发DAPP之前&…