IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 关于关联商品数据与商品主数据之间的一致性问题的一些思考 -> 正文阅读

[Java知识库]关于关联商品数据与商品主数据之间的一致性问题的一些思考

? ? ? ? 在最近的工作中遇到了一个问题。就是关于商品主数据和关联商品的数据一致性问题。比方说现在有一个商品主数据spuA。同时现在有一个促销套包的需求,套包里面会添加商品。如果这次这个套包里添加的商品是spuA的话,那么在前端展示的促销套包里面的商品的状态应该怎么取呢(商品名称/价格/上下架等等信息)?因为这是个普遍性问题,所有需要保证一致性的、添加商品数据的需求都会存在这个问题。所以我想单独提出来,写出我的思考和我最终的解决方案。


1 主动查询

????????第一种方案是促销套包里面不存商品的信息,最多存一个spuId,每次前端过来的请求都会拿着spuId主动去调用商品的接口,返回最新的商品信息。

????????这种方案虽然不会有数据一致性的问题,但是每次都会去调用商品的接口来获取数据,小数据量下还好,如果遇到大数据量下效率不是很高。


2 定时任务

????????第二种方案是促销套包这里会存商品的信息,冗余一份数据。然后通过定时的方式来刷新套包里面的商品数据。

????????这种方案虽然不用前端过来的每次请求都去查商品接口了,但是有时延性的问题。十分钟一刷,那么数据得等到十分钟后才能被修改。另外如果当前这个商品很少发生改动,比如说几个月内都不会发生数据变化,那么也会十分钟一刷,浪费系统资源。还有,刷新的频率设置成多少也是个问题,需要在时延性和系统资源浪费上做取舍。


3 数据监听

????????第三种方案就是类似于canal的那种,监听商品表数据变化,如果变化了,就发送一条mq的广播消息。这样下游的促销套包就可以感知到数据变化,以此来进行数据更新。

????????本来我以为这种方案挺好,但跟同事一交流的话,发现这种方案也有它的问题。比如说当前这个监听发送的服务有多个集群节点。那么一个商品spuA,一开始是将价格从100改为200,然后又将价格从200改为300。这是两次操作。可能第一个节点监听到从100改为200的操作,而第二个节点监听到从200改为300的操作。而第一个节点组装完数据所花费的时间是要大于第二个节点的。这样造成的结果就是价格从200改为300的操作会先发送出去,而价格从100改为200的操作会后发送。这样的话促销套包那里最后这个商品记录的价格会是200,而不是数据库记录的300,从而出现bug:

第一个节点10:00监听到商品数据从100改为200

第一个节点组装发送所需的数据花了10分钟,10:10完成

第一个节点10:11发送mq消息

促销套包10:12接收到消息,将商品的价格从300改为200

第二个节点10:05监听到商品数据从200改为300

第二个节点组装发送所需的数据花了3分钟,10:08完成

第二个节点10:09发送mq消息

促销套包10:10接收到消息,将商品的价格从100改为300

????????我知道RocketMQ里有分区顺序消息的功能,但是它也只是能保证数据的发送和消费是有顺序的,但如果我在这之前的业务操作上的组装数据不能保证有顺序、有先后性的话,那还是会有问题。

????????当然这种情况下是可以加上分布式锁的,但是这样会使性能有所损失。如果商品数据一段时间内的改动很频繁的话,这样会很影响发送消息的性能。


4 数据监听(优化)

????????第四种方案,基于第三种方案出现的问题,做出以下改动:不再组装数据,只记录spuId或skuId,同时记录当前是增/删/改操作(第三种方案也会记录增/删/改),下游的促销套包拿到商品id后主动再查询一次商品接口来获得最新的数据。

????????这种方案是我目前正在使用的方案,兼顾了数据查询的性能和资源调度上的取舍。其实对于第三种方案还有一个问题:RocketMQ的消息体大小是有上限的(其他的MQ应该也会有类似的限制),如果商品数据量很大的话,这点也会是个问题。而第四种方案,消息体里面只会放商品id和增/删/改操作,最大程序上可以避免这个问题。同时下游服务不是完全依赖于mq发送过来的数据,也就没有第三种方案出现的问题。因为发mq消息肯定是在数据发生变动之后才发送的,所以等到下游服务接收到消息时,再去查询商品数据肯定是最新的,只要能保证每一次数据的变化都能成功发送mq消息即可。


5 总结

????????最后想说的一点是:具体采用什么方案还是要看数据量的大小和业务的需求。如果前期数据量不大的情况下还是要学着简单处理,后续再调整。不要一上来就整大而全的解决方案。盲目引入多个组件会使程序复杂度增高,难于维护。另外,如果业务是需要保证强一致性场景的话,那么也就不能使用canal了。就得采用别的方案。


原创不易,未得准许,请勿转载,翻版必究

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 15:33:33  更:2022-05-01 15:37:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:55:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码