举个例子,在搜索领域,往往会采用ES这一类的全文检索引擎进行加速,但由于搜索往往还要带有广告、推荐等信息,很多时候还需要读取具备ACID的RDMS数据库,或者是一些NoSQL数据库,多种数据库组合在一起,才能满足业务上的需求。
这么多异构的数据源组合在一起,虽然能够将系统做的更大和更灵活,但也会带来很多问题,例如:
工程上的实现更加繁琐,没有办法将所有数据库的 *** 作封装到统一的DAL层;
在一些可回滚的业务场景里,数据要在多个数据库之间同步的进行ACID *** 作。
例如广告业务场景里,有一个业务场景是只计费一次,流程有如下的步骤:
数据写入Mysql;
数据写入ES;
数据写入Redis。
步骤1是为了将数据传递给财务系统,步骤2是为了重新调整检索顺序,步骤3是为了一些事实的推荐场景应用。如果第1步就失败了,那么整个顺序就不需要执行,但如果第1步成功而第2步失败,那么虽然计费成功了,但是在检索的时候就会出现问题,导致出现第二次的计费。
如果业务对于一致性的要求不高,那么在工程侧是可以不考虑一致性问题的,把现场日志记录完整,通过后续的补救 *** 作,比如对第二次计费进行退费 *** 作,依然可以解决问题。但如果业务场景是要求强一致性,显然工程上可能就需要考虑牺牲部分性能,以满足一致性的要求了。
|02 本地事务和分布式事务
在展开后续的叙述前,我们先普及一下本地事务和分布式事务的一些特点。
传统软件行业多使用关系型数据库,如Mysql、PostgreSQL等。好处是通过ACID的事务特性,可以在数据库层面保证数据的强一致性,ACID分别指:
原子性(Atomicity):一个事务要么全部提交成功,要么全部失败回滚,不能只执行其中的一部分 *** 作;
一致性(Consistency):事务的执行不能破坏数据库数据的完整性和一致性;
隔离性(Isolation):事务的隔离性是指在并发环境中,并发的事务是相互隔离的,一个事务的执行不能不被其他事务干扰;
持久性(Durability):一旦事务提交,那么它对数据库中的对应数据的状态的变更就会永久保存到数据库中。
虽然ACID确实能够保证强一致性,但随着业务系统的越来越复杂,绝大多数场景里,对于速度的要求是压过了对于一致性的要求,这个时候为了能够解决业务快速跑起来的问题,我们就会考虑牺牲一部分的性能,来满足业务的能力的问题。这时候CAP理论就应运而生了:
一致性(Consistency):在分布式系统中,更新 *** 作执行成功后所有的用户都应该读取到最新值;
可用性(Availability):每一个 *** 作总是能够在一定时间内返回结果;
分区容忍性(Partition Tolerance):是否可以对数据进行分区。
在分布式系统下,为了保证分区容忍性,就必须要在一致性与可用性之间做出选择,这时候“鱼与熊掌不可兼得”。为了能部分程度上弥补这个问题,我们又提出了BASE理论:
基本可用(Basically Available):假设系统,出现了不可预知的故障,但还是能用;
软状态(Soft state):允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性;
最终一致性(Eventually Consistent):系统能够保证在没有其他新的更新 *** 作的情况下,数据最终一定能够达到一致的状态,因此所有客户端对系统的数据访问最终都能够获取到最新的值。
BASE与ACID理论不同的是,它是满足CAP理论的,即通过“时间换空间”的思路,通过牺牲强一致性的方式,在处理系统请求的过程里,允许存在短时间的不一致状态,延迟保证数据的一致性。
所以,这里我们可以给“最终一致性”下一个定义,即:系统中的所有数据副本经过一定时间后,最终能够达成一致的状态。
|03 解决数据一致性的模式
通过上一阶段理论演进的阐述,可以看出,互联网工程领域往往通过“最终一致性”的方式,来保障数据的一致性。因此接下来提到的解决思路,都是围绕“最终一致性”展开的。接下来主要介绍三种方式:
第一种是“可靠消息”,即通过保障消息传递的方式,来保障下游数据的一致性,这种方式本质上属于事件驱动的方案设计。例如在电商领域用户下单后,后续会发送消息给各个子系统:银行、仓储、物流等,各个子系统根据消息的结果来做下一步的业务逻辑。
这种方案主要考虑的问题是:如何确保消息能够传达,以及如何避免重复消息的传递,用更专业的语言来描述,就是“幂等”。
其实如果感觉到自己设计系统太过于复杂的时候,可以借鉴一些开源系统的实现方案,比如Kafka就支持“幂等性”。Kafka的思路是这样的:设计唯一的ProducerID及一个从0开始单调递增的SeqNum值,下游通过判断SeqNum是否大于1来判断是否接受消息。或者参考一些流式计算引擎,比如Flink和Storm,都有实现exactly-once的方法。
第二种是“TCC两阶段补偿”,TCC是Try-Confirm-Cancel的简称,这是当下比较火的一种柔性事务方案。TCC的概念最早由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。
TCC主要分为如下三个阶段:
Try阶段:完成所有业务检查(一致性),预留业务资源(准隔离性);
Confirm阶段:确认执行业务 *** 作,不做任何业务检查,只使用Try阶段预留的业务资源;
Cancel阶段:取消Try阶段预留的业务资源。
以航班的预定为例,很多时候因为价格问题,我们不会直接飞到目的地,而是通过中转的方式抵达,于是我们会预定两张机票。但问题来了,这两张机票不一定都会顺利使用,如果遇到天气、管制、机票预留等问题,其中一张取消了,那么整个行程就不会顺利完成。这个时候,我们把机票的预定修改为三个接口:机票预留接口、确认接口、取消接口,分两次进行 *** 作,如果两段行程任意一段机票预留失败,那么调用两段行程的取消接口,反之调用确认接口。
这个概念与MR的两阶段计算思路比较类似,即通过一种折中的方案,来实现最终一致性。
第三种是“逆向接口补偿”,使用额外的协调服务来保证微服务之间的最终一致性。微服务通常采用接口进行调用,在常规的提供正向业务逻辑的基础上,再要求每个接口提供一个逆向业务逻辑的方案。如果在顺序调用接口的过程中,某个服务出现了错误,那么再重复调用之前已成功的微服务接口的逆向接口,取消本次事务的 *** 作。
这种场景在优惠领域比较常见,比如用户通过优惠券买了一件商品,但商品库存没了,需要退货,那么理论上优惠券是需要返还给用户的,这时候正向接口就是消耗优惠券,而逆向接口就是返还优惠券。
但各个接口之间的调用不一定会100%成功,所以补偿方案也需要一个最终一致性解决方法,即针对单次原子的逆向 *** 作,至少保证被调用一次。这时候最理想的方案就是系统记录Log,通过事后分析再判断进行一次调用。
|04 从全局角度再思考
不论是从数据库层面,还是从工程层面,或者是人工兜底层面,数据一致性总有解决的方法,区别只是场景适用性与成本高低的问题。
随着技术发展的越来越快,解决方案手段的不断增加,技术架构解耦就是一种必然的要求,在不同的场景下选用自己最适合的方案,但由此带来的数据一致性问题也将成为技术融合道路上的一个阻碍。可以预见,未来的技术生态,对于技术点的组合编排创新必然成为主旋律。就像Hadoop的出现是为了解决集群一致性的问题,数据驱动的方法论也终将像框架一样,成为下一代的创新点。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。
展开剩余内容
打开APP阅读全文并永久保存
更多类似文章
猜你喜欢
类似文章
破解世界性技术难题! GTS让分布式事务简单高效
也谈分库分表在实际应用的实践
事务的ACID属性&5种状态
微服务跨服务事务的实现
Java 框架实战 springAOP 实现数据库事务 *** 作
如何实现微服务架构下的分布式事务
更多类似文章 >>
生活服务
搜索
数据一致性分布式系统数据一致性数据一致性检验方法批流一体如何保证数据一致性在线数据一致性标准药品一致性评价查询官网数据一致性架构数据库一致性如何提升数据的一致性数据最终一致性
首页万象文化人生生活健康
教育职场理财娱乐艺术上网
留言交流回顶部
联系我们
触屏版| 下载APP
京ICP证090625号 京ICP备05038915号
京网文[2022]3822-110号 京公网安备 11010502030377号
关注公众号
保存
生成长图
分享
使用AIDE的第一件事当然是建立一个数据库,以便将来检查。这项工作要在系统或应用程式安装完毕以后,要连接到网络上之前进行。能够使用以下参数启动AIDE完成这项工作:
aide --init
数据库产生后一定要放到一个安全的地方。
aide有两种参数:命令参数和选项参数,以下是aide的命令参数:
--check
检查数据库的一致性。需要一个初始化的AIDE数据库。也是AIDE的默认命令选项。
--init
初始化一个数据库
--update
检查数据库,并且以非交互的方式升级数据库。输入的数据库和输出的数据库必须是不同的。
选项参数:
--config=configfile
指定configfile文档作为配置文档,不使用默认的./aide.conf。假如使用-,aide就从标准输入中读取。
--before=configparameters
在读取配置文档之前,首先处理configparameters指定的配置选项。
--after=configparameters
处理完配置文档配置的配置选项以后,再处理configparameters配置的配置选项。
--verbose=verbosity_level,-V verbosity_level
控制aide信息显示的冗余程度。值在0到255之间。
--report=reporter,-r
指定报告输出的URL。
--version,-v
显示版本号
--help,-h
显示帮助信息
aide是个Tipwire的替代和扩展软件,他有一些Tripwire所不具备的特征。aide当前具备的特征包括:多种完整性检验算法、把数据库输出到标准输出设备/文档的能力、通过配置文档进行配置连同数据库压缩支持。将来aide会提高更多的特征。
以上内容由 华夏名网 收集整理.作者:ChinaUnix博客
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)