作为一名程序员 , 你是不是经常在很多场景 , 例如看博客、聊天吹水等等时候听到这样一个词"系统数据一致性" , 是不是有时候感觉到了迷糊 , 不知道这个"系统数据一致性"到底是在说什么?其实 , 你可能只是不明白这个词 , 但是你肯定在实际工作中发现、解决过这样的问题 。
单体架构下系统数据一致性问题在传统的系统应用中 , 一般都是使用单体架构来构建系统的 。即所有的功能模块都放在一起实现 , 打成一个WAR包部署在Tomcat中 , 数据一般存放在关系型数据库中 , 如MySQL数据库 。
文章插图
前面我说过即使这种单体架构的系统也是数据一致性的问题的 , 举一个电商下单的例子 , 用户提交完订单 , 系统 , 系统在订单表order表中写入订单金额、用户等相关数据 , 在订单明细order_item表中写入商品价格、购买的数量等数据 , 最后更新商品的库存sku信息 。用户下单成功之后 , 系统操作了order、order_item、sku这三个数据表 , 对于这三个表的操作无论成功与失败 , 都应该是原子的 , 操作成功则都要成功 , 失败则都要一起失败 。不然就会出现脏数据 , 数据一致性被破坏 。
1、 如果操作order和order_item表成功 , 操作sku表失败 , 则会导致本应该扣减的库存没有扣减 , 则商品有可能出现超卖 。
2、如果操作order和order_item表失败 , 操作sku表成功 , 则会导致本不应该扣减的库存扣减了 , 则商品有可能出现少卖 。
3、如果操作order和sku表成功 , order_item操作失败 , 则这个订单数据丢失 , 订单后续的操作肯定也是操作不了了 。
上面只是简单的举了三种可能出现的情况 , 也可能会有其他的情况发生 。那我们怎么避免这些情况的发生呢?其实这种问题稍微有的开发经验的同学都会想到解决方案 , 那就是使用数据库的事务 , 事务的原子性保证上述的步骤成功则一起成功 , 失败则一起失败 。
BEGIN;INSERT INTO order;INSERT INTO order_item;UPDATE sku;COMMIT; # ROLLBACK
在单体架构的系统下解决内部模块的数据一致性的问题 , 用数据库的ACID特性就能保证 。单体架构的优点就是相对分布式来说开发简单 , 功能可以集中管理 , 模块之间通信没有损耗 。但随着业务越来越复杂、需求越来越庞大 , 人们对系统响应时间、吞吐量和出现故障的时候的系统可用性的要求也越来越高!传统的单体架构系统在这种情况下暴露的缺点也越来越多 , 人们开始寻求转变 。既然部署在一个服务器上的单体架构系统搞不定 , 那就多部署几台 , 即用多台单机节点组成集群 , 再用负载均衡向外提供服务 。
文章插图
但是这样做还是解决不了单体架构存在的一些问题:
- 只能使用同种语言开发 , 不能针对不同业务场景利用不同语言的优势开发对应的模块 。
- 系统模块耦合性太强 , 系统中某一个模块出现问题 , 例如高并发、大数据场景或者出现bug , 整个系统都会受到牵连 。
- 某个模块发布 , 整个系统都要停机发布 , 系统所有模块都不能对外提供服务 , 这样无法快速响应市场需求 。
- 集群负担大 , 如果想要集群 , 只能对整个系统进行集群 , 即使只有一个模块有压力 。
集群(Cluster): 系统单机部署对外服务能力出现瓶颈 , 则将系统进行多机部署 , 这些系统对外提供相同的服务 , 每个单机系统我们称之为节点 , 多个节点统一起来则可以称之为集群 。分布式架构下系统数据一致性问题天下大事分久必合、合久必分!既然单体架构解决不了问题 , 那我们就尝试拆分系统 , 让专业的人做专业的事 , 那如何进行拆分呢?拆分一般分为水平拆分和垂直拆分 。这里说的拆分并不单指数据库拆分 , 而是所有模块都进行拆分 , 每个模块都有自己的缓存、数据库等等 。
推荐阅读
- 从零开始教你安装Oracle数据库
- excel怎么输入下拉选项-excel中设置下拉列表的输入-_1
- 不喜欢摄影?照片拍不出它的美
- 手机上的Linux:Termux
- ae复制粘贴快捷键是什么?ae的复制键_2
- 东汉邓太后的历史评价?汉朝的邓太后
- 初窥 Python 的 import 机制
- PLC的基本知识?plc的一些基础知识点
- 修复Windows 10更新错误的最佳方法
- 基于SpringBoot的微服务架构与K8S容器部署实践