当前位置:首页 > 技术分析 > 正文内容

让程序员头疼的微服务下数据聚合join(二)

ruisui882个月前 (04-09)技术分析14

回首

上文中我们介绍了冗余方案来解决了数据聚合join。

让程序员头疼的微服务下数据聚合join(一)

聚合服务

本文我们介绍另一种方案,聚合服务,如下图

从上图中,聚合服务先从订单服务、用户服务、商品服务中各自取出数据,然后再聚合服务中进行计算、组装

此聚合服务的架构,在任何一个大厂,比如:阿里、京东、美团等,他们在网站页面上的数据,大部分都是通过后台的分布式聚合服务组装出来的。通常叫做聚合服务层(或者叫BFF层);此架构在复杂业务的微服务架构中普遍存在。

当然引入此方案,我们的系统架构的复杂度就高了一点,而且会衍生出其他的问题

N + 1 问题

有的时候,为了获得A和B服务的聚合数据,可能A只需要调用一次,但是B却需要调用N次才能获取完整数据。

这个就是软件开发领域臭名昭著的N + 1问题,它通常是性能杀手

数据量问题

聚合服务把订单服务、用户服务、商品服务的部分数据加载到本地内存,然后才能进行聚合运算。但访问量大的时候,聚合服务会占用大量的内存开销,严重时可能会造成内存OOM

业务服务发展问题

随着业务发展,业务服务也会越来越多,那么聚合服务需要聚合的数据也会越来越多。而且有些聚合出来的数据是可以重复利用的,如果不做缓存的话,那么会出现大量频繁和重复的聚合运算,白白消耗大量的服务器资源。

如何解决上面的问题?

数据分发 + 预聚合

此解决方案也叫CQRS模式

英文全称是Command/Query Responsibility Segregation;命令/查询职责分离模式

如上图所示,左边是Command命令端,通常只负责写入右边是Query查询端,通常只负责读取。底层一般是数据分发技术,如MQ(kafka),将命令端的变更数据,通过MQ中,聚合服务订阅MQ,把数据聚合存储到Redis、ES、MongoDB或HBase等。

查询端调用聚合服务就可以查询预先聚合的数据

小伙伴想一下,这个方案是不是跟数据库的视图View很类似,视图View也是聚合了数据,保障了查询性能。

写入端的数据存储,通常采用传统的SQL数据库。而查询端则可以根据需要选择适合的存储机制,比如如果通过KV健查询的话,可以选择Redis;通过关键字查询的话,可以采用elasticsearch;大数据领域可以采用Spark/Flink平台。

那左边的更新的数据,如何发送到MQ中呢?老顾开源的【彩虹桥】项目,采用了阿里的canal同步binlog实现发送到MQ中。有兴趣的小伙伴可以去了解一下。

项目地址:

https://gitee.com/gujiachun/bridge.git

最终一致性问题

按照上面的方案,能够支持大量的并发查询;非常好的解决了分布式数据Join。但是因为有MQ的分发,导致查询端会有一定的延迟问题

按照上面的架构,延迟最多1-2秒。

如果有些业务对时效性要求很高,那应该怎么解决呢?

乐观更新

UI在发出请求后,马上更新UI,页面反应已经更新的数据状态

比方说你点赞了某社交网站上的视频或图片,页面马上会显示一颗红心。然后页面后台再通过ajax等方式查询更新结果,

如果确认更新成功,那就不需要做什么;

如果确认更新失败,只需将页面状态回滚即可。

这种方式仅适用于一些简单的场景

拉模式

UI向命令端发出请求时,请求中带上版本号,然后通过ajax等方式不断轮询查询端,并检查更新后的视图的版本号是否和请求的版本号一致,直到版本号匹配为止,也就是等到视图明确更新成功或失败为止。

发布订阅模式

UI向命令端发出请求,同时通过websocket等方式订阅在查询端,查询端更新好视图,通过发消息通知UI更新页面展示。

总结

到此老顾就介绍完了微服务下的数据Join方案。小伙伴可以自行选择不同的方案,各有千秋。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3389.html

分享给朋友:

“让程序员头疼的微服务下数据聚合join(二)” 的相关文章

HTML5学习笔记三:HTML5语法规则

1.标签要小写2.属性值可加可不加””或”3.可以省略某些标签 html body head tbody4.可以省略某些结束标签 tr td li例:显示效果:5.单标签不用加结束标签img input6.废除的标签font center big7.新添加的标签将在下一HTML5学习笔记中重点阐述。...

三维家-系统快捷键使用

快键件使用:通过简单的键盘+鼠标操作,快速完成搭配。1.基础快捷键1) Ctrl+V:复制选中对象第一步:鼠标左击物体,按下Ctrl+V 即可复制选中对象。2) Ctrl+G:组合多选对象第一步:按住Ctrl键多选对象--按住Ctrl+G--确定。3) Ctrl+B:解组选中对象第一步:左击选中对象...

第99p,用简单案例说明同步与异步的区别

大家好,我是杨数Tos,这是《从零基础到大神》系列课程的第99篇文章,第三阶段的课程:Python进阶知识:用一个简单的案例说明同步与异步之间的区别,以及异步的效率。异步的原理已经在前面的文章讲过,本文主要比较同步与异步的差异;使用一个模拟下载文件的案例,比较同步与异步在效率上的差异。1、使用同步的...

每日分享- Vue 3.0 + vite + axios 出现跨域问题如何解决

在 Vue 3.0 + Vite + Axios 中,如果接口请求的地址与前端代码不在同一域下,就会出现跨域问题。这种情况下,可以采取以下几种简单的解决办法:一 使用代理在 Vite 的配置文件中,可以通过 proxy 选项来配置代理,使得前端代码与接口请求在同一域下。例如:// vite.conf...

gin-vue-admin 基于vue和gin 搭建的后台管理系统脚手架

项目地址:https://github.com/piexlmax/gin-vue-admingin-vue-admin gin+vue开源快速项目模板更新代码后如果遇到前端报错请执行 npm i 前端开发会不定期增加新的依赖 请注意更新重构记录2019年12月12日 17:15...

微信小程序入门教程之二:页面样式

这个系列的上一篇教程,教大家写了一个最简单的 Hello world 微信小程序。但是,那只是一个裸页面,并不好看。今天接着往下讲,如何为这个页面添加样式,使它看上去更美观,教大家写出实际可以使用的页面。所有示例的完整代码,都可以从 GitHub 的代码仓库[1]下载。一、总体样式微信小程序允许在顶...