首页 文章 精选 留言 我的

精选列表

搜索[数据一致性],共1752篇文章
优秀的个人博客,低调大师

分布式系统:数据一致性解决方案

点击上方蓝色字体,选择“设为星标” 回复”资源“获取更多资源 大数据技术与架构 点击右侧关注,大数据开发领域最强公众号! 大数据真好玩 点击右侧关注,大数据真好玩! 在分布式系统中,随着系统架构演进,原来的原子性操作会随着系统拆分而无法保障原子性从而产生一致性问题,但业务实际又需要保障一致性,下面我从学习和实战运用总结一下分布式一致性解决方案。 1. CAP & Base理论  CAP定理指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。这三个要素最多只能同时实现两点,不可能三者兼顾: 一致性:在分布式系统中的所有数据备份,在同一时刻是否同样的值。 分区容错性:可靠性,无论应用程序或系统发生错误,还是用户以意外或错误的方式使用,软件系统都能继续运行。 可用性:在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。   CAP理论3选2是伪命题,实际上必须从A和C选择一个和P组合,更进一步基本上都会选择A,相比一致性,系统一旦不可用或不可靠都可能会造成整个站点崩溃,所以一般都会选择AP。但是不一致的问题也不能忽略,使用最终一致是比较好的办法。  BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结, 是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。接下来看一下BASE中的三要素: 基本可用(Basically Available):基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。注意,这绝不等价于系统不可用。比如: 响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒 系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。 软状态(Soft State):软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。 最终一致(Eventually Consistent):最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。  最终一致的核心做法就是通过记录对应操作并在操作失败时不断进行重试直到成功为止。 2. 重试 在出现一致性问题时如果系统的并发或不一致情况较少,可以先使用重试来解决。  在调用Service B超时或失败时进行重试: 同步调用,捕获异常重新调用Service B。 异步消息,捕获异常发送延迟消息重新调用Service B。 异步线程,捕获异常开启异步线程重新调用Service B。  如果重试还是不能解决问题,那么需要使用分布式事务来解决。 3. 分布式事务 对于分布式一致性问题可以采用分布式事务来解决。 3.1 2PC-XA协议 XA事务由一个或多个资源管理器(Resource Managers)、一个事务管理器(Transaction Manager)以及一个应用程序(Application Program)组成。 资源管理器(RM):参与者。提供访问事务资源的方法。通常一个数据库就是一个资源管理器。 事务管理器(TM):协调者。分配标识符,监视事务的进度,并负责事务完成和故障恢复。 应用程序(AP):发起者。定义事务的边界,制定全局事务中的操作。  整个过程分为2个阶段:准备(prepare)和提交(commit),prepare前需要先执行对应的DML操作。   Mysql XA事务语句: 注:执行前需要先生成全局唯一的xidXA {START|BEGIN} xid [JOIN|RESUME]DML操作XA END xid [SUSPEND [FOR MIGRATE]]XA PREPARE xid //1.准备XA COMMIT xid [ONE PHASE] //2.提交XA ROLLBACK xidXA RECOVER 简单的事例: //准备前阶段mysql> XA START 'xatest';Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO mytable (i) VALUES(10);Query OK, 1 row affected (0.04 sec)mysql> XA END 'xatest';Query OK, 0 rows affected (0.00 sec)//准备mysql> XA PREPARE 'xatest';Query OK, 0 rows affected (0.00 sec)//提交mysql> XA COMMIT 'xatest';Query OK, 0 rows affected (0.00 sec) XA看起来很美好,但还是存在一些问题: commit丢失/超时导致数据不一致。A commit成功,B commit时网络超时导致数据库未收到commit请求。 性能低。所有事务参与者在等待其它参与者响应的时候都处于同步阻塞状态。 主备数据不一致。 协调者单点故障,在任意阶段协调者发生故障都会导致分布式事务无法进行。  3.2 3PC 3PC通过在参与者加入超时机制解决2PC中的协调者单点带来的事务无法进行的问题,但是性能和一致性仍没有解决。  3.3 TCC  这样看下来强一致是很难做了,还是最终一致把。。。  TCC是通过最终一致来达到分布式事务的效果,即:在短时间内无法保证一致性,但最终会一致。核心分为2个阶段:1.Try 2.Confirm or Cancel。先尝试(Try)操作数据,如果都成功则全部确认(Confirm)该修改,如果有任意一个尝试失败,则全部取消(Cancel)。简单点说就是增加了中间态和可回改能力。   通过重试机制保障Confirm和Cancel一定能成功。TCC解决了性能问题,但是业务系统想要实现对业务代码的侵入性很大,可以学习一下阿里GTS是如何做的。  3.4 事务管理器 在实际运用中事务管理器(TM)一般是由应用程序(AP)兼职实现的,这样对业务代码侵入性大,最好是把TM做成中间层。接下来详细看一下TM的职责:协调者。分配标识符,监视事务的进度,并负责事务完成和故障恢复。TM需要具备持久化能力才能完成监控、故障恢复和协调,整个协调过程可以分为3个阶段: 准备阶段:向TM注册全局事务并获取到全局唯一XID,这一步需要定义好事务的范围。 执行阶段:应用程序AP执行业务功能操作自己的RM,全部执行完毕后向TM commit,如果无失败则整个事务成功。 确认/回滚阶段:如果第2步出现异常会触发该阶段,TM咨询各个AP对应操作是否成功,如果成功则commit,如果失败则调用AP进行rollback。  下面简单介绍几种实现方式。 3.4.1 本地事务管理器 对于简单的业务可能只要保障2个数据库之间的一致,这样在本地实现事务管理器比较快成本也不高。   1. 在做业务逻辑之前把对应事件添加到本地event表中(记录订正时所需要的关键数据) 2. 执行业务逻辑 1.本地业务逻辑,操作表数据等等 2.RPC调用其他服务 3.修改event状态为确认 4. 如果第2步不成功,则event状态还是预提交,通过定时任务捞取再执行订正逻辑 5. 检查业务逻辑中的操作是否完成,如未完成则执行订正逻辑 1.本地业务逻辑是否执行成功 2.RPC调用其他服务是否执行成功 6.返回订正结果 1.成功则修改event为确认提交 2.未成功则不操作,等待轮询订正 3.4.2 外部事务管理器 阿里GTS:https://help.aliyun.com/document_detail/157850.html 3.5 DB和MQ之间的一致性  在实际场景中,业务系统对本地DB数据变更后会广播对应的消息,消费者消费消息做自己的业务逻辑,按正常逻辑消息会在数据库变更后发出,如果消息发送超时且失败那么DB和MQ之间就产生了不一致问题,如何解决呢?使用可靠消息来解决,核心逻辑保证消息从投递到消费的过程中不会丢失:生产者confirm、消费者ack和持久化。理论上只要使用生产者确认机制即可,但是不使用消费者ack则没有意义。消费者需要开启手动ack同时做到幂等消费,MQ需要通过将exchange、queue和message进行持久化来保证消息不丢失,生产者则需要通过确认机制保证消息一定投递到MQ种,接下来重点讲解一下生产者确认机制。  confirm机制是在消息投递到所有匹配的queue之后发送确认消息给生产者,这样生产者就知道消息投递成功,但是由于消息是在DB操作之后发出的,生产者必须增加记录表来记录消息投递状态,如果投递成功就在收到确认消息时把记录标记为投递成功,如果长时间未收到确认消息则大概率是消息丢失了,再定时重新投递,这样就可以保证消息最终一定能投递成功。核心逻辑其实就是通过全局事务ID来标识DB操作和MQ消息是在一个分布式事务中的。  疑点:在学习RabbitMQ confirm机制时发现生产者接收到的确认消息只有消息ID,这个消息ID不能作为全局事务ID,所以无法解决DB和MQ之间的一致性问题,后续再看看其它MQ产品是怎么做的。  上面的方式需要业务系统维护消息状态,这部分可以交给中间件来实现,实现逻辑会变得不一样。   预投递的消息不会分发到queue中,只有在接收到确认投递的请求后才会进行投递,如果确认操作因为网络异常失败了,MQ在过一段时间之后主动询问业务系统该消息是否可投递(失败不断重试),这样就能在异常时做到最终一致,不过依赖MQ产品的能力。 3.6 DB和缓存之间的一致性 DB和缓存之间同样也存在不一致问题,先写DB再写缓存如果缓存写失败就不一致了,同样的需要重试更新缓存来做最终一致。方法可以参考“2.重试”部分,如果一定要保证重试不丢失可以用可靠消息或本地task表来记录重试操作,有条件的可以使用DB DRC消息对业务的侵入会小一些。需要注意的是同步更新和异步更新同时使用时可能会产生更新覆盖的问题,加上毫秒级的时间戳或版本号来丢弃旧的更新。 4. 兜底核对 虽然有了分布式事务,但是在实际场景中可能会因为bug导致数据不一致,这时需要兜底来做最后一道防线,通过定时核对数据是否一致,如不一致手动/自动进行订正。 4.1 系统自核对 如果系统数量和数据量不多的情况下可以由业务系统自行核对,通过发送延迟消息自消费或监听其他系统消息做相关数据核对并进行订正。  4.2 搭建核对系统 在核对工作繁多的情况下,由业务系统自己核对会存在很多耦合,这时可以选择搭建独立的核对系统进行核对和订正。  1.监听drc消息   2.监听业务消息  参考: 阿里GTS:https://help.aliyun.com/document_detail/157850.html?spm=a2c4g.11186623.6.554.47ae4df4Zy6hBI 饿了么DRC:https://zhuanlan.zhihu.com/p/34958596 Mysql XA:https://dev.mysql.com/doc/refman/8.0/en/xa-statements.html 版权声明: 本文为大数据技术与架构整理,原作者独家授权。未经原作者允许转载追究侵权责任。 编辑|冷眼丶 微信公众号|import_bigdata 欢迎点赞+收藏+转发朋友圈素质三连 文章不错?点个【在看】吧!👇 本文分享自微信公众号 - 大数据技术与架构(import_bigdata)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

数据一致性校验及数据同步,运维必看

主从数据不一致对DBA来说是一个比较头疼的事情,刚接触MySQL时,遇到这种问题我一般采用重新还原备库的方式恢复数据,这对我来说是个很痛苦的过程。今天就来介绍两款pt工具,通过这两款工具可以针对数据不一致的情况进行快速检测和修复。 pt-table-checksum pt-table-checksum可以在线校验主从数据库的一致性,他可以在主库上执行检查语句,在线检查MySQL复制的一致性,然后生成replace语句,通过复制传递到从库,再更新master_crc的值。最后 通过检测从服务器的this_crc和master_crc的值判断主从数据是否一致。 如 果复制有延迟,在从库的checksum会暂停直到赶上主库的计算时间点。 注意事项: 1. 主从数据库必须是同步状态。 2. 表中要有主键或者唯一索引。 使用示例 1.首先我们先创建一个校验用户 mysql> grant select,insert,update,delete,create,drop,super,process,replication slave on *.* to 'syncuser'@'%' identified by 'Syncuser@123'; 2. 通过pt-table-checksum命令对主从数据进行校验。 [root@node1 ~]# pt-table-checksum -usyncuser -pSyncuser@123 --nocheck-replication-filters --no-check-binlog-format --databases=test --replicate=test.checksums --create-replicate-tableChecking if all tables can be checksummed ...Starting checksum ... TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE09-04T21:36:43 0 0 0 0 1 0 0.089 test.efs_sys_loginfo409-04T21:36:43 0 0 1006 0 1 0 0.089 test.groupby09-04T21:36:43 0 0 0 0 1 0 0.030 test.groupby109-04T21:36:43 0 1 1006 0 1 0 0.030 test.groupby209-04T21:36:43 0 0 7 0 1 0 0.030 test.student09-04T21:36:43 0 0 7 0 1 0 0.032 test.student109-04T21:36:43 0 1 0 8 1 0 0.034 test.t09-04T21:36:43 0 0 57344 0 4 0 0.328 test.t109-04T21:36:43 0 1 1 0 1 0 0.028 test.test09-04T21:36:430080100.036test.tuser 3.参数详解 --nocheck-replication-filters:不检查复制的过滤规则,比如replicate-ignore-db、replicate-wild-do-table。 --no-check-binlog-format:不检查复制的binlog模式,如果binlog模式是row模式,需要启用该参数。 --create-replicate-table:第一次进行checksum需要启用该参数,会进行checksum表的创建,用于存放结果。 --replicate=test.checksums:存放checksum结果的表。 --databases:表示要检查的库。 --tables(-t):表示要检查的表。 --replicate-check-only:表示只显示不同步的表。 --recursion-method:正常情况下工具会自动识别从库,如果识别失败,可以用该参数 指定查找slave的方法,参数有四种,分别是processlist、hosts、dsn=DSN、no四种,用来决定查找slave的方式是通过show processlist、show slave hosts还是通过dsn=DSN的方式。 采用dsn=DSN方式时需要先创建dsn表,建表语句如下: CREATE TABLE `dsns` (`id` int(11) NOT NULL AUTO_INCREMENT,`parent_id` int(11) DEFAULT NULL,`dsn` varchar(255) NOT NULL,PRIMARY KEY (`id`)); 然后插入主从复制关系: insert into dsns(dsn) values('h=36.30.39.176,u=syncuser,p=Syncuser@123,P=3306'); 这样就可以采用dsn方式了,--recursion-method dsn=D=test,t=dsns。 4.结果分析 TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE09-04T22:29:52 0 0 1 0 1 0 0.029 test.dsnsTS:完成检查的时间ERRORS:错误和告警的数量。DIFFS:是否一致,0代表一致,1代表不一致。ROWS:表的行数DIFF_ROWS:CHUNKS:划分的块的数目SKIPPED:跳过的块的数目TIME:执行时长TABLE:表名 pt-table-sync 我们上面介绍了pt-table-checksum可以检查主从数据的一致性,接下来我们就来说一下如何进行主从数据的同步。参考官方文档时就已经晕了,写出来之后难免有纰漏之处,还请读者朋友多多批评指正。 该工具采用replace into的方式同步数据,建议同步的表上要有主键或者唯一索引,否则replace into就和普通的insert语句一样了,会导致主库出现数据重复的情况。如果表上没有主键,变更需要再从库执行命令,并且指定--no-check-slave。 该工具可以以两种方式运行,当使用--replicate参数时,会使用由pt-table-checksum命令检测的结果进行同步,否则它会自动检测不一致并且修复。 当你使用了--replicate时,说明已经通过checksum工具检测出差异并保存在数据表里了,需要确定是否使--sync-to-master选项,如果使用该选项,则表示在使用pt-table-sync时仅接受一个DSN主机,并且是slave的DSN。工具会自动找出它的主库,找出差异进行同步。 如果你没有指定--sync-to-master参数,则DSN代表的是主库,工具会自动它的从库进行数据同步。 如果不使用--replicate,则分为以下几种情况: 当只有一个DSN信息时,并且指定了--sync-to-master,那么DSN信息必须是从库,否则会报错。 当有多个DSN主机时,第一个DSN是源端数据库,这时候并不区分主库或者从库,它会按照顺序向后面的DSN主机同步数据。 使用示例: 1.在上面的例子中,我们已经通过pt-table-checksum检测出主从的不一致的表,接下来我 们开始进行同步。下面的命令中指定了--replicate,并且未指定--sync-to-master,则-h代表主库。 pt-table-sync h=36.30.39.117,P=3306,u=syncuser,p=Syncuser@123 --database=test --replicate='test.checksums' --execute 2. 同时指定--replicate和--sync-to-master,DSN只能有一个,且为从库。 pt-table-sync h=36.30.39.176,P=3306,u=syncuser,p=Syncuser@123 --database=test --tables=t1 --replicate='test.checksums' --sync-to-master --execute 3. 如果只指定一个DSN,那么必须使用--replicate或者--sync-to-master中的一个,否则报错: Atleastone DSN is required, and at least two are required unless --sync-to-master or --replicate is specified。 这里我们指定了--sync-to-master,那么DSN信息就代表了从库。 pt-table-sync h=36.30.39.176,u=syncuser,p=Syncuser@123,D=test,t=t1 --sync-to-master --execute 4. 当有多个DSN时,如果指定了--sync-to-master,那么所有的主机均为从库。否则报错: Can'tdeterminemasterofD=test,h=…..,p=...,t=t1,u=syncuserat/usr/bin/pt-table-syncline10020. pt-table-sync h=36.30.39.176,u=syncuser,p=Syncuser@123,D=test,t=t1 h=36.30.39.213,u=syncuser,p=Syncuser@123,D=test,t=t1 --sync-to-master --execute 5.多个DSN,不指定--sync-to-master和--replicate,如果需要修复从库的数据需要指定 --no-check-slave。 pt-table-sync h=36.30.39.117,u=syncuser,p=Syncuser@123,D=test,t=t1 h=36.30.39.176,u=syncuser,p=Syncuser@123 h=36.30.39.213,u=syncuser,p=Syncuser@123 --no-check-slave –execute 参数详解: --ask-pass: 连接MySQL时提示输入密码。 --[no]bin-log: 指定是否记录二进制日志,如果是--no-bin-log相当于执行了set sql_log_bin=0. --[no]check-slave: 检测目标服务器是否是从库。如果目标服务器是从库的话,直接对其变更是不安全的,但是有时候必须要这么做,所以此时需要指定参数--no-check-slave。 --chunk-size: 指定表分块的chunk大小。 --dry-run: 分析同步的过程,并打印出信息退出,并不实际执行。 --execute: 指定工具执行变更操作,使表数据达成一致。 --print: 打印出工具需要执行哪些语句来变更表。 --wait: 如果存在主从延迟,从库可以等待多长时间追上主库,等待的时间由该参数设置,超时会终止退出。 DSN选项: DSN syntax is key=value[,key=value...] Allowable DSN keys: KEY MEANING === ============================================= A 指定字符集 D 同步的数据库 P 端口 S Socket文件 h 要连接的host p 数据库密码 t 要同步的表 u 数据库用户 注意事项及建议 1. 当出现主从不一致时,我们需要判断哪个库的数据是正确的,大多数情况我们希望在主库执行变更并且同步到从库。 2. 建议要同步的表要有主键,避免出现数据重复的问题。 3. 执行变更命令前先通过--print或者--dry-run进行检查。 4. 使用多个DSN选项时,按照数据同步方向填写主机信息,如果有从库需要配合--no-check-slave参数使用。 5. 该工具在进行校验分析时会对表执行for update操作,避免在业务高峰期进行。 本文分享自微信公众号 - MySQL数据库技术栈(Mysqltechnology)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册