首页 > 编程知识 正文

mysql两个数据库同步数据,数据库的读写分离怎么实现

时间:2023-05-04 07:06:22 阅读:37966 作者:3214

目录

1、读写分离解决了什么问题

2、读写分离和业务框架

3、实际案例

4、解决办法

模拟binlog协议 延迟消费

1、读写分离解决了哪些问题? 读写分离实际上是在将数据库分离为一个主库、多个从库、主从库之前通过某种机制(例如binlog )进行数据同步的一种常见的数据库体系结构。 在许多互联网行业,读写较少的业务,为了线性提高数据库的读写性能,消除读写冲突,提高写入性能,一般采用读写分离的思想(当然是副本集、缓存策略) 其实,概括地说,读写分离的基本原理是将数据库的读写操作路由到不同的节点,解决数据库的读写性能瓶颈。

2、读写分离和业务框架在实际项目中,读写分离和业务框架如下图所示。 当APP应用程序a成功执行事件(事务的执行)时,其发送消息队列以通知APP应用程序c。 APP位置c从上游APP位置b获取数据。 其中,APP应用程序a主要是写操作,连接到主库,而APP应用程序b主要通过读取操作连接到从属库。 master和slave通过某种机制进行数据同步。

这种简单的体系结构有一个主要问题。 此外,本文重点讨论和解决的—— APP应用程序b获取的数据可能是尚未从库中同步的数据。

3、在实际案例中,首先结合案例介绍面临的问题(数据库为innodb )。

**年初,**写入操作后数据不生效,实际业务视图与上述一致。 原因现在看很清楚,但确定问题花了几天时间。 首先代码(通过TSM的afterCommit,然后发送的消息队列(当然,缓存设置也没有问题)是del还是直接设置(在此不显示) ) ) )

对于朴素的刺猬来说,在成功提交事务后,此数据始终显示在另一个事务中(除非另有说明,否则指的是Innodb,隔离级别为RR )。 接口从库中检索数据。 本节简要介绍了以下数据写入数据库的整个过程: update/insert/delete等操作依次发生还原日志、重做日志。 在2PC上,redolog prepare (是否崩溃,当然是通过innnodb_flush_log_aare的整个过程,将相关的page读取到内存中进行变更。 就是所谓的dirty page。 事务提交后,仅实际上没有记录日志,内存中的dirty page最终何时更新到磁盘是检查点。 在此期间经历过校验和、双写等。 这不是本论文的重点,从这里开始。 首先,保证重做日志/binlog /还原日志成功是有名的WAL ()为什么是WAL? 重做日志和binlog共存的意义是什么? 留下审查问题吧)。 在整个过程中,主库完成了数据的写入。

然后,mysql使用binlog同步数据。 库通常有IO线程,它从主库中检索binlog日志并将其存储在库中的内存(即relay log )中。 假设消耗时间为T1。 接着,利用sql线程再现数据,将消耗时间设为T2。 当前在线使用的是5.5的mysql版本号。 5.6的哪个版本似乎是支持binlog的多线程复制,而5.5的版本则始终是单线程复制。 binlog的复制方法是RBR (其他两个是SBR,MBR ),库使用的数据库存储引擎也是Innodb。 假设发送业务时间,例如mq,在下游接收mq,调用接口的时间为T3。 T3T1 T2是否意味着获取的数据是上次发布的数据? 没错,下游获取的数据没有更新是因为这种情况。 这是从当时在线获取的binlog同步到库相对主库的延迟监视图,从图中可以看到,有

些时刻,主从同步最大有甚至有1s,此时主库的CPU消耗也是挺高的。

  

4、解决方案

      解决数制库读写分离下的数据同步思路其实相当简单——确保从库与主库的数据已经同步即可。如轮询从库数据(当然这个不是很优雅的解决方案),订阅从库的binlog日志(当生成binlog日志时)。接下来我们对后面一种方案进行简单的描述。

      目前,已经有很多成熟的工具来模拟从库获取数据库实例的binlog日志并对其解析,如阿里的canal,京东的binlake等。他们可以按需过滤部分的binlog日志(如某个table的某些操作),然后发送到消息队列中,应用程序程序订阅该消息后,然后进行业务逻辑处理(如通过已经有工具解析binlog日志,然后进行业务逻辑处理,并按需发送消息给下游)。这里虽然解决了读写分离因同步延迟导致的业务不正确的问题,但并不完美,因此并没有彻底解决该问题。具体原因如下:

     在2PC中,分为两个阶段:第一阶段是redo/undo log的sync落盘, 第二阶段包含两步:前一步骤为binlog的sync操作,当这个阶段完成时,binlog已经写入,此时就可以发送给订阅者然后进行消费,后一步骤是commit操作[如释放mutex锁],只有commit全部完成之后,其他事务才能查询binlog日志所对应的事务产生的数据变更(这里有可能网友有疑问,如果binlog落盘了数据库崩溃了,能否恢复数据?答案当然是能够的)。因此在实际的项目中,我是通过延迟消费500ms的策略解决的,这里就完美的解决了数据同步的问题。

     binog日志落盘到整个2PC提交结束这个时间差可能导致数据不同步,要特别感谢该博文:https://www.jiqizhixin.com/articles/2018-12-05-14, 在这里我才意识到可能存在这个问题,并在实际的项目中与小伙伴一起验证,通过连接7天的数据验证,终于发现了一条这样的数据。

 

 

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。