热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql读写分离,导致数据不一致问题

在互联网中大型项目中,读写分离应该是我们小伙伴经常听说的,这个主要解决大流量请求时,提高系统的吞吐量。因为绝大部分互联网产品都是读多写少,大部分都是读请求,很小部分是写请求。 上图

在互联网中大型项目中,读写分离应该是我们小伙伴经常听说的,这个主要解决大流量请求时,提高系统的吞吐量。因为绝大部分互联网产品都是读多写少,大部分都是读请求,很小部分是写请求。

《mysql-读写分离,导致数据不一致问题》

 

上图:

1)一个主库负责写请求,更新数据

2)两个从库负责读请求,可以提高系统吞吐量

3)主库和从库之间同步数据

为什么产生数据不一致

《mysql-读写分离,导致数据不一致问题》

 

上图中业务流程

1)写请求A进行数据更新,但写库还没有来得及把更新的数据更新到读库

2)读请求B进行数据查询,请求B是访问的读库,获取的是旧值

3)因为写库和读库之间存在同步延迟,导致数据在不同库中不一致

这个问题我们如何解决?

方案一:利用数据库自身特性

我们一般用的数据库是mysql和oracle,mysql是我们互联网项目都会用到的,oracle一般大公司用的比较多(很贵啊)。

我们分析一下问题,原因就是在主库(写库)与从库(读库)之间数据同步延迟导致,mysql中有全同步复制机制、半同步复制、异步复制三种复制方案(小伙伴可以自行去了解)。

mysql全同步复制

《mysql-读写分离,导致数据不一致问题》

 

全同步复制,当A提交更新请求主库事务之后,不是立即返回,而是等到所有的从库节点必须收到、APPLY并且提交这些事务,主库线程才返回请求A结果,才能做后续操作。这样就解决了数据同步延迟的问题。

问题:但这个同步方案严重的问题就是写请求耗时会很长,而且会随者从库数量增加,耗时也会增加。(不推荐)

oracle共享存储

《mysql-读写分离,导致数据不一致问题》

 

上图采用了oracle RAC方案,DB服务其实就代表一个应用服务,所有的数据存储在同一个地方,所有就不存在数据同步这个问题。当然这个部署方案不是我们严格意义上面的读写分离,存储是独立的。

问题:oracle成本很高,对存储硬件要求很高。

方案二:不解决

我们设计任何架构方案,都要围绕着业务,如果业务能够接受可以不解决;其实很多互联网产品都有短时间的数据不一致问题。如:58同城,美团,贴吧等。

但有些场景是不允许的。如:

《mysql-读写分离,导致数据不一致问题》

 

上图中:

1)用户写了一篇文章,点击保存按钮

2)系统执行保存方法,提示用户保存成功

3)保存成功后一般系统就会立即跳转到文章列表,按照时间倒序,最新的文章排在第一个,这个业务是很正常的,让用户可以看到自己的文章列表(我们的头条号就是这样的)

4)这样就是调用获取文章列表的方法getArticleList,但这个方法是读请求,走的是从库。

5)如果出现主库和从库同步延迟,就出现了不一致。

这样用户就看不到他刚刚提交保存的文章,这个用户是接受不了的。那我们怎么解决?

方案三:客户端保存法

这个方案是从一个朋友公司用到的,老顾没有采用过。一些业务的操作是有前端页面的,不管是网页或App等。此方案的思路就是把之前保存的文章缓存到客户端,在用户到文章列表时,数据的组成就是(客户端缓存文章 + 后端读库返回的文章数据)。客户端要做的就是缓存要设置一个时间(这个缓存时间,可以预估主库同步到从库的时间延迟);以及要做文章去重,防止读库已经同步完成,客户端缓存没有过期。

问题:客户端逻辑复杂;客户端有缓存数据大小的限制,不能保存大数据。列表分页处理复杂。

方案四:缓存标记法

《mysql-读写分离,导致数据不一致问题》

 

上图流程:

1)A发起写请求,更新了主库,但在缓存中设置一个标记,代表此数据已经更新,标记格式(业务代号:数据库:表:主键ID)根据自己业务场景。

2)设置此标记,要加上过期时间,可以为预估的主库和从库同步延迟的时间

3)B发起读请求的时候,先判断此请求的业务在缓存中有没有更新标记

4)如果存在标记,走主库;如果没有走从库。

这个方案就有效了解决了数据不一致的问题。

但这个方案会有个严重的问题,也就是每次的读请求都要到缓存中去判断是否存在缓存标记,如果是单机部署用的是jvm缓存,对性能还好;但如果是集群部署缓存肯定用redis,每次读都要和redis进行交互,这样肯定会影响系统吞吐量。

那怎么办?怎么办?继续往下看

方案五:本地缓存标记

《mysql-读写分离,导致数据不一致问题》

 

上图流程:

1)用户A发起写请求,更新了主库,并在客户端设置标记,过期时间,如:COOKIEs

2)用户A再发起读请求时,带上这个本地标记在后端

3)后端在处理请求时,获取请求传过来的数据,看有没有这个标记(如:COOKIEs)

4)有这个业务标记,走主库;没有走从库。

这个方案就保证了用户A的读请求肯定是数据一致的,而且没有性能问题,因为标记是本地客户端传过去的。

但有写小伙伴就会问那其他用户在本地客户端是没有这个标记的,他们走的就是从库了。那其他用户不就看不到这个数据了吗?说的对,其他用户是看不到,但看不到的时间很短,过个1~10秒就能够看到。

但这个方案解决了当前用户的数据一致性的问题,如上面举的例子,写文章,然后到文章列表,本用户是能够看到的。其他用户暂时看不到是没有关系的。还是那句话,脱离业务的方案是耍流氓。(推荐)


推荐阅读
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 本文介绍了Paxos的世界中关于复制日志与状态机的概念和重要性。通过存储日志来实现数据的持久化,并通过日志流来记录数据的变化,而不是直接持久化数据本身。这样做的好处是简化了持久化存储的操作,并且方便多机之间的数据同步。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • MongoDB用户验证auth的权限设置及角色说明
    本文介绍了MongoDB用户验证auth的权限设置,包括readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase、cluster相关的权限以及root权限等角色的说明和使用方法。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 【Java面试】简单说一下你对序列化和反序列化的理解
    Hi,大家好,我是Mic一个工作4年的粉丝,投了很多简历好不容易接到一个互联网公司的面试邀约。在面试第一轮就被干掉了,原因是对主流互联网技术理解太浅了。其中就有一个这样的问题:“简 ... [详细]
author-avatar
QK丫头419QJ
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有