一,为什么要冗余数据

互联网数据量很大的业务场景,往往数据库需要进行水平切分来降低单库数据量。

水平切分会有一个patition key,通过patition key的查询能够直接定位到库,但是非patition key上的查询可能就需要扫描多个库了。

此时常见的架构设计方案,是使用数据冗余这种反范式设计来满足分库后不同维度的查询需求。

例如:订单业务,对用户和商家都有查询需求:

Order(oid, info_detail);

T(buyer_id, seller_id, oid);

如果用buyer_id来分库,seller_id的查询就需要扫描多库。

如果用seller_id来分库,buyer_id的查询就需要扫描多库。

此时可以使用数据冗余来分别满足buyer_id和seller_id上的查询需求:

T1(buyer_id, seller_id, oid)

T2(seller_id, buyer_id, oid)

同一个数据,冗余两份,一份以buyer_id来分库,满足买家的查询需求;一份以seller_id来分库,满足卖家的查询需求。

如何实施数据的冗余,以及如何保证数据的一致性,是今天将要讨论的内容。

二,如何进行数据冗余

(1)服务同步双写

顾名思义,由服务层同步写冗余数据,如上图1-4流程:

业务方调用服务,新增数据

服务先插入T1数据

服务再插入T2数据

服务返回业务方新增数据成功

优点:

不复杂,服务层由单次写,变两次写

数据一致性相对较高(因为双写成功才返回)

缺点:

请求的处理时间增加(要插入两次,时间加倍)

数据仍可能不一致,例如第二步写入T1完成后服务重启,则数据不会写入T2

如果系统对处理时间比较敏感,引出常用的第二种方案。

(2)服务异步双写

数据的双写并不再由服务来完成,服务层异步发出一个消息,通过消息总线发送给一个专门的数据复制服务来写入冗余数据,如上图1-6流程:

业务方调用服务,新增数据

服务先插入T1数据

服务向消息总线发送一个异步消息(发出即可,不用等返回,通常很快就能完成)

服务返回业务方新增数据成功

消息总线将消息投递给数据同步中心

数据同步中心插入T2数据

优点:

请求处理时间短(只插入1次)

缺点:

系统的复杂性增加了,多引入了一个组件(消息总线)和一个服务(专用的数据复制服务)

因为返回业务线数据插入成功时,数据还不一定插入到T2中,因此数据有一个不一致时间窗口(这个窗口很短,最终是一致的)

在消息总线丢失消息时,冗余表数据会不一致

不管是服务同步双写,还是服务异步双写,服务都需要关注“冗余数据”带来的复杂性。如果想解除“数据冗余”对系统的耦合,引出常用的第三种方案。

(3)线下异步双写

为了屏蔽“冗余数据”对服务带来的复杂性,数据的双写不再由服务层来完成,而是由线下的一个服务或者任务来完成,如上图1-6流程:

业务方调用服务,新增数据

服务先插入T1数据

服务返回业务方新增数据成功

数据会被写入到数据库的log中

线下服务或者任务读取数据库的log

线下服务或者任务插入T2数据

优点:

数据双写与业务完全解耦

请求处理时间短(只插入1次)

缺点:

返回业务线数据插入成功时,数据还不一定插入到T2中,因此数据有一个不一致时间窗口(这个窗口很短,最终是一致的)

数据的一致性依赖于线下服务或者任务的可靠性

不管哪种方案,毕竟不是分布式事务,万一出现数据不一致,怎么办呢?

高并发的情况下,实时一致性很难,方法论是:最终一致性。

实现方式是:异步检测,异步修复。

三,如何保证数据的一致性

(1)线下扫描全量数据法

如上图所示,线下启动一个离线的扫描工具,不停的比对正表T1和反表T2,如果发现数据不一致,就进行补偿修复。

优点:

比较简单,开发代价小

线上服务无需修改,修复工具与线上服务解耦

缺点:

扫描效率低,会扫描大量的“已经能够保证一致”的数据

由于扫描的数据量大,扫描一轮的时间比较长,即数据如果不一致,不一致的时间窗口比较长

有没有只扫描“可能存在不一致可能性”的数据,而不是每次扫描全部数据,以提高效率的优化方法呢?

(2)线下扫描增量数据法

每次只扫描增量的日志数据,就能够极大提高效率,缩短数据不一致的时间窗口,如上图1-4流程所示:

写入正表T1

第一步成功后,写入日志log1

写入反表T2

第二步成功后,写入日志log2

当然,我们还是需要一个离线的扫描工具,不停的比对日志log1和日志log2,如果发现数据不一致,就进行补偿修复

优点:

虽比方法一复杂,但仍然是比较简单的

数据扫描效率高,只扫描增量数据

缺点:

线上服务略有修改(代价不高,多写了2条日志)

虽然比方法一更实时,但时效性还是不高,不一致窗口取决于扫描的周期

有没有实时检测一致性并进行修复的方法呢?

(3)线上实时检测“消息对”法

这次不是写日志了,而是向消息总线发送消息,如上图1-4流程所示:

写入正表T1

第一步成功后,发送消息msg1

写入反表T2

第二步成功后,发送消息msg2

这次不是需要一个周期扫描的离线工具了,而是一个实时订阅消息的服务不停的收消息。

假设正常情况下,msg1和msg2的接收时间应该在3s以内,如果检测服务在收到msg1后没有收到msg2,就尝试检测数据的一致性,不一致时进行补偿修复。

优点:

效率高

实时性高

缺点:

方案比较复杂,上线引入了消息总线这个组件

线下多了一个订阅总线的检测服务

however,技术方案本身就是一个投入产出比的折衷,可以根据业务对一致性的需求程度决定使用哪一种方法。我曾经做过IM系统,好友关系链上亿,好友数据正反表的数据冗余,使用的就是方法二。

四,总结

互联网数据量大的业务场景,常常:

使用水平切分来降低单库数据量

使用数据冗余的反范式设计来满足不同维度的查询需求

冗余数据三种方案:

(1)服务同步双写法能够很容易的实现数据冗余

(2)为了降低时延,可以优化为服务异步双写法

(3)为了屏蔽“冗余数据”对服务带来的复杂性,可以优化为线下异步双写法

保证数据一致性的方案:

(1)最简单的方式,线下脚本扫全量数据比对

(2)提高效率的方式,线下脚本扫增量数据比对

(3)最实时的方式,线上检测“消息对”

mysql 冗余字段 同步_冗余数据一致性,到底如何保证?相关推荐

  1. mysql主从增量同步_生产环境中mysql主从同步/完整/增量备份

    环境:某项目的DB19数据库服务器,无从库也无开过binlog日志,负载有时比较高但基本运行稳定.备份情况:本地每天完整备份保留一周再rsync到异地备份机保留一月,由于数据量的增长加上每天晚上rsy ...

  2. oracle和mysql数据实时同步_异构数据源的CDC实时同步系统——最终选型实战

    引言: <异构数据源的CDC实时同步系统> 系列第一篇 (已完成) <零编码打造异构数据实时同步系统--异构数据源CDC之2> 系列第二篇(已完成) <零编码打造异构数据 ...

  3. mysql按字段同步_MySQL同步(一) 基础知识

    6 MySQL 同步 同步功能在MySQL 3.23.15就开始引进了,它可以把一个MySQL服务器上的数据复制到另一个服务器上去.本章描述了MySQL的各种复制特性.介绍了同步的概念,如何设置同步服 ...

  4. mysql 修改字段长度_面试官:InnoDB记录存储结构都不知道,你敢说你懂MySQL?

    前言 了解MySQL的人都知道,MySQL服务器上负责对表中数据的读取和写入工作的部分是存储引擎,而MySQL的存储引擎有MyISAM和InnoDB.不同的存储引擎一般是由不同的人为实现不同的特性而开 ...

  5. mysql数据对比同步_跨数据库mysql语句同步数据和对比运算

    首先,A数据库[需要同步的数据库]A_product数据表[产品基本信息]product_id产品唯一IDprice产品价格A_product_option_value数据表[产品选项]product ...

  6. mysql数据库字段变形_详解如何利用amoeba(变形虫)实现mysql数据库读写分离

    摘要:这篇MySQL栏目下的"详解如何利用amoeba(变形虫)实现mysql数据库读写分离",介绍的技术点是"MySQL数据库.数据库读写分离.amoeba.MySQL ...

  7. mysql explain字段含义_史上最全的explain常见结果含义分析,值得收藏

    概述 对于MySQL执行计划的获取,我们可以通过explain方式来查看,explain方式看似简单,实际上包含的内容很多,尤其是输出结果中的type类型列.理解这些不同的类型,对于我们SQL优化举足 ...

  8. mysql text字段导出_用命令创建MySQL数据库

    一.连接MYSQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1. 连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysqlbin,再键入命令mysql -u root ...

  9. mysql 文章 字段设计_在mysql数据库中,文章表设计有啥好的思路

    Q: 用mysql设计一张文章表,不知道有啥好的思路! 我是这样的,应为考虑附件和图片,所以我的文章表除了有varchar(1000)的文章内容,还设置了个Bolb接收附件和图片. 我用的是mysql ...

最新文章

  1. linux 命令自动提示错误信息,Linux基础命令---sar显示系统活动信息
  2. 怎么在idea中找实现类
  3. cdh用户权限_cdh设置hdfs权限
  4. 正确地kill java历程
  5. 运行shell脚本时怎么知道jdk路径_Shell写脚本关于ssh执行jar包,需要刷新JDK路径的问题...
  6. [Winodows Phone 7控件详解]Silverlight toolkit for Windows Phone 7.1控件-3
  7. java log4j 实例_log4j使用例子 - 小代码2016的个人页面 - OSCHINA - 中文开源技术交流社区...
  8. 多线程断点下载开发总结(一) - Http head Range标记
  9. \opencv\build\x86下的vc6、vc7、vc8、vc9、vc10、vc11、vc12、vc14、vc15是什么意思?
  10. c语言回溯算法数独,数独回溯算法
  11. 【计算机网络】谢希仁教材轻松解读 概述篇
  12. 泛微云桥e-Bridge-任意文件读取漏洞
  13. 北京知产局:鼓励当事人用区块链,获取、固定知识产权纠纷证据
  14. 基本流水线与记分牌算法和Tomasulo算法
  15. Android实时监听短信并上传服务器
  16. win10添加网络打印机_win10系统连接网络打印机
  17. 服务器装win7无限重启吗,win7系统重装系统后无限重启电脑的解决方法
  18. ROCK Pi 4B+ 快速上手指南(Windows 平台)
  19. 普莱菲尔密码矩阵生成算法
  20. 关于“东京爱情故事补拍结局”

热门文章

  1. 亚马逊运营培训自动型广告如何做高排名
  2. GL_BALANCE科目余额表
  3. 手写签名(H5\小程序)
  4. 上手安信可模块RTL8720DN(BW16)——arduino点亮神灯
  5. 凯育星辰:玩抖音,你不能碰的违禁词
  6. 亿智科技获北极光创投数千万天使轮投资,北极光创投领投
  7. Fenix – 基于 Node.js 的桌面静态 Web 服务器
  8. 使用ESP12和Arduino开发板制作一款基于物联网IoT的电能表
  9. 安全用电智能监控系统的应用
  10. DeepDream:图像合成教程