文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

微服务架构中的数据一致性:解决方案与实践

2024-11-30 12:59

关注

2、如何实现服务之间的数据一致性

说到数据一致性这个话题,我们可以想到的最常用最熟悉的解决问题的方式就是事务处理了。它存在的意义是为了保证系统中所有的数据都是符合预期的,并且存在关联关系的数据之间不会产生矛盾,即数据状态一致性。事务的概念,起源于数据库,发展到今天,几乎在每一个业务系统中都会涉及到。尤其在一些大型复杂的分布式系统中,事务的概念已经不仅局限于数据库,还可以延伸为一切需要保证数据一致性的应用场景,包括但不限于数据库、事务内存、缓存、消息队列、分布式存储等等,这些都有可能会用到事务处理。

今天我们探讨的主题是服务之间数据一致性问题。当然,实际生产落地中,在不同业务背景下,具备可行性的方案也是非常多的,各有优劣和适用场景。我们从中选择一两个具体实现,聊一些相关的设计和实践。

3、几个核心名词

为了方便正在阅读本篇文章的同学对后续内容的阅读和理解,我们先对文章中使用到的几个名词的语义做一些解释和约定:

业务侧系统:指的是发起执行业务操作的一方系统服务,可以简单理解为消费方。

平台侧系统:指的是为发起执行业务操作而提供基础能力的一方系统服务,可以简单理解为服务方。

执行业务操作:指的是对数据的读写操作需要依赖多个系统服务的协同完成,业务侧系统发起,平台侧系统执行最终的数据读写操作。这样场景中就普遍存在着服务之间的数据一致性问题(备注 :业务侧系统和平台侧系统是一个逻辑概念,并非一定要存在具体的应用服务与之对应)。

业务操作标识:指的是业务操作应该归属的业务类型或者业务场景的标识,它是平台侧系统创建并且统一管理的,然后发放给业务侧系统,在业务侧系统的服务调用平台侧系统提供服务能力的身份信息。业务标识可以设计为单层结构,也可以设计为多层结构,符合当前系统和业务的需求即可。

业务操作唯一ID:指的是某个具体业务操作在某一次或者多次重复执行的唯一性标识。生产实践中,它一般是由业务侧系统的服务自定义实现和管理的,也可以是基于平台侧系统提供有约束性质和方便管理的规则限制下,再由业务侧系统的服务自定义实现,后者是比较推荐的方式。

业务操作记录表:指的是记录业务操作的日志流水表。生产实践中,一般是由业务侧系统的服务创建并且管理。

4、方案一:业务侧系统保证最终一致性

4.1 核心思想

通过业务侧系统的服务保证数据的最终一致性,其核心思想就是业务侧系统记录下来每一次具体业务操作的执行流水日志信息,并且对没有全部成功的变更结果,触发执行数据一致性的校验核对工作。

4.2 设计原则

4.3 流程图

4.3.1 数据一致性的校验核对同步执行流程

4.3.2 数据一致性的校验核对异步核对链路

5、方案二:平台侧系统保证最终一致性

5.2 设计的基本原则:

平台侧系统,提供支持业务操作执行的基础服务能力的接口,需要根据业务操作标识和唯一ID做幂等设计。它和方案一的一致性原则类似,省略不再赘述。

平台侧系统,提供业务操作的执行结果确认的回调SPI,可以方便业务侧系统来实现,根据业务操作标识和业务操作的唯一ID。

业务侧系统,提供根据业务操作标识和业务操作的唯一ID,来判断两边的数据是否具备一致性的回调实现。

5.3 流程图

5.3.1 数据一致性的校验核对同步核对链路

5.3.2 数据一致性的校验核对异步核对链路

6、实践过程中一些经验分享

这一部分,我将会对平台侧系统和业务侧系统的接口设计的部分细节,做一些简单的扩展阐述。希望为大家后续的研发工作提供一些思路。后续的文章中,将会针对其中一些具体的解决方案,做更详细的阐述。

首先,接口幂等性设计,将从如下角度进行阐述:  数据结构,状态存储,异常处理,返回结果唯一等等角度做一些总结分享。

6.1 数据结构设计

接口幂等性设计,是基于业务操作的标识(这里是称之为Tag)和业务操作的唯一ID来实现的。业务操作标识的设计,可以是单层的设计,也可以是多层的设计。其中,多层的设计是为了满足业务侧系统的存在复杂并且多业务场景的诉求。业务操作的唯一ID的生成方式,可以是没有任何业务含义的自增趋势的不可重复的ID,比如MySQL的自增主键ID,分布式ID生成器等等方式,也可以是业务侧系统的某些特定的业务字段 ,比如用户的userId,订单的orderId,商品的spuId,skuId等等。在实际实践中,后者是我们比较推荐的常用方式,可以实现在不增加系统复杂度和额外依赖资源的同时,又可以和业务侧系统达到高度的契合。

6.2 状态存储设计

在一般情况下,建议把MySQL存储当做我们首选的存储,MySQL提供非常完善的数据一致性保证能力,最简单的方式是基于数据库的联合唯一索引设计,多次层Tag + 唯一ID的业务唯一键。但是也是有缺陷的,比如MySQL自身的性能瓶颈和昂贵的存储成本。性能上的瓶颈,可以通过访问MySQL的幂等校验之前,增加访问Redis的幂等校验,校验不通过抛出异常,在MySQL幂等校验通过以后,异步刷数据到Redis中,这样保证Redis校验通过的同时MySQL校验一定是通过的。我们可以接受Redis的幂等校验的不准确性,仅仅是期望它成为流量漏斗的上层,为MySQL承担起流量过滤作用,当然你可以有其他的更多的方案来做这件事,甚至组合起来使用。也可以增加分库分表的策略,来解决MySQL的性能瓶颈。在MySQL的存储成本是相对比较高的,我们可以对历史的数据做归档处理,只保留一部分的热数据,原则上保持单表的数据行数在500w~1000w之间,同时也可以有能支持一定量的历史数量查询。同时这个过程也需要考虑无锁处理问题和MySQL空间碎片的问题等等。

6.3 异常处理设计

第一步,明确导致发生异常的原因有哪些?一般可以归为几个分类,网路异常,数据格式错误,业务逻辑异常。第二步,针对特定类型的问题,我们做出相应处理方案。比如我们重试机制,控制重试频次,重试周期的衰减时间执行控制,处理数据处理的终态的异常数据的兜底处理机制等等方式。

完善告警机制,比如异常状态告警,超出阈值告警等等,让相关的业务侧系统和平台侧系统同学可以快速感知到问题并且介入解决问题。

建设监控大盘,比如 MySQL,Redis,MQ,以及数据核对工作的状态的监控等等,都是需要我们去一步一步建设起来的。

定位和排查问题的工具,拆分后的系统,其系统的复杂度是指数增长的,这个方面也是非常重要的。

7、总结

在本篇文章中,阐述了两种处理数据一致性问题的解决方案,从核心思想,设计原则,系统交互流程等等做了详细的阐述,比对两种方案,各有优劣和各自的适用场景。方案一,业务侧系统来保证数据的一致性,更适用于对数据的一致性有相对比较强的耦合依赖关系的业务场景,需要依赖业务操作的执行结果做出判断,执行不同后续业务逻辑分支的执行。 案例: 同一个商品在不同修改商品信息(变更不同的字段,变更不同表的字段)的入口触发异步更新C端缓存的单品维度的商品全量缓存数据构建,变更的事务是在成功完成提交以后,方可执行本次变更对应的后续缓存构建。方案二,平台侧系统来保证数据的一致性,更适用于业务侧系统,关注点是数据的最终执行结果的业务场景,案例: 不同业务场景入口的库存扣减和库存回滚执行结果。最后,提到在生产实践过程中一些经验和解决方案的总结分享,每个点都是值得继续深入探讨。

来源:得物技术内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯