【设计数据密集型应用】复制

  • 👏作者简介:大家好,我是爱敲代码的小黄,阿里淘天Java开发工程师,CSDN博客专家
  • 📕系列专栏:Spring源码、Netty源码、Kafka源码、JUC源码、dubbo源码系列
  • 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
  • 🍂博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人
  • 📝联系方式:smallyellow521,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬👀

文章目录

  • 复制
    • 领导者与追随者
    • 同步复制与异步复制
    • 如何设置新从库
    • 处理节点宕机
      • 从库失效:追赶恢复
      • 主库失效:故障切换
    • 复制日志的实现
      • 基于语句的复制
      • 逻辑日志复制(基于行)
      • 基于触发器的复制
  • 复制延迟问题
      • 读已之写
      • 单调读
      • 一致前缀读
      • 多主复制
        • 运维多个数据中心
        • 需要离线操作的客户端
        • 协同编辑
      • 处理写入冲突
        • 同步与异步冲突检测
        • 避免冲突
        • 收敛至一致的状态
      • 多主复制拓扑
    • 无主复制
      • 节点故障
        • 读修复和反熵
  • 总结

与可能出错的东西比,“不可能”出错的东西最显著的特点就是:一旦真的出错,通常就彻底玩完了。

—— 道格拉斯・亚当斯(1992)

复制

简介:通过网络连接的多台机器上保留相同数据的副本。

原因:降低延时、可用性、吞吐量

  • 数据存放地与用户接近,减少网络请求延时
  • 避免单机故障,提升可用性
  • 机器数量可伸缩,提升读取吞吐量

困难:

  • 如果复制的数据不随时间而改变,复制将变的非常简单
  • 但复制的过程中,数据经常是变更的

解决:

在分布式场景下,一般使用三种变更复制算法:

  • 单领导者
  • 多领导者
  • 无领导者

领导者与追随者

副本:存储数据库拷贝的每个节点

问题:当存在多个副本时,如何确保所有数据都落在了所有的副本上?

解决方案:基于领导者的复制

原理:

image-20240219231709711

  • 我们将其中一个副本指定为 领导者(主库)
    • 当客户端想要写入数据时,必须将请求发送给领导者(主库)
    • 它将数据写入到本地存储
  • 其他副本成为追随者(只读副本)
    • 每当领导者将新数据写入本地存储时,它也会将数据变更发送给所有的追随者,称为复制日志。
    • 每个追随者从领导者拉取日志,并更新本地数据库副本,按照领导者相同的处理顺序来进行写入
  • 当客户想要从数据库查询数据
    • 领导者和任一追随者都可以查询
    • 只有领导者可以写入数据

同步复制与异步复制

image-20240219233053467

  • Follower 1:同步复制
    • 好处:保持与主库强一致的最新数据
    • 坏处:从库挂掉,主库也无法写入数据
  • Follower 2:异步复制
    • 好处:从库挂掉,主库也能写入数据
    • 坏处:无法保持与主库强一致的最新数据

目前业界常用方式:半同步

  • 在数据库中开启同步复制,其中一个从库是同步的,其余所有的从库均是异步的
  • 如果该从库不可用,则将另外一个异步从库改为同步复制

通常情况下,基于领导者的复制都配置成完全异步,一旦主库失效不可恢复,复制给从库的数据也将丢失。

即使已经向客户端确定成功,写入也不能保证是持久的。

当然也有优点:即使所有的从库都落后了,主库也可以正常写入。

如何设置新从库

原因:

  • 增加从库副本数量
  • 替换失败的节点

过程:

  • 在某个时刻获取主库的一致性快照
  • 将快照复制到新的从库节点
  • 从库链接主库并拉取快照后的所有数据变更
  • 等从库处理完快照之后的数据变更,从库就赶上了主库

复制过程可参考:RedisMySQL

处理节点宕机

系统中的任何节点都可能宕机,即使个别节点生效,也能保持整个系统的运行并尽可能控制节点停机带来的影响

从库失效:追赶恢复

在本地磁盘中,从库记录从主库收到的数据变更。

如果从库崩溃并重新启动或者网络中断等原因,从本地日志中获取最后一个事务

连接到主库,请求在从库断开期间发生的所有数据变更,当解决完这些变更之后,就赶上了主库,正常接受数据变更流。

主库失效:故障切换

故障切换:将其中一个从库提升为新的主库,重新配置客户端,将他们的写操作发送给新的主库,其他从库需要开始拉取来自新主库的数据变更。

过程:

  • 确定主库失效(心跳检测)
  • 选择一个新的主库(选举机制)
  • 重新配置系统以启动新的主库

问题:

  • 异步复制,新主库的数据落后老主库。解决方式:丢掉老主库中未复制的写入

  • 数据库与外部存储协调,丢弃写入内容极其危险

    例如在 GitHub 的一场事故中,一个过时的 MySQL 从库被提升为主库

    数据库使用自增 ID 作为主键,因为新主库的计数器落后于老主库的计数器,所以新主库重新分配了一些已经被老主库分配掉的 ID 作为主键

    这些主键也在 Redis 中使用,主键重用使得 MySQL 和 Redis 中的数据产生不一致,最后导致一些私有数据泄漏到错误的用户手中。

  • 脑裂,两个节点都误认为自己是主库

  • 超时时间的配置,如何正确的配置主库失效的超时时间

复制日志的实现

基于语句的复制

主库记录每个写入请求并将该语句发送给从库

问题:

  • 任何调用 非确定下函数 的语句,在每个副本生成不同的值。
    • NOW():获取当前时间
    • RAND():获取一个随机数
  • 语句必须按照顺序执行,避免并发问题
    • UPDATE … WHERE <某些条件>,必须现有某些条件数据,再进行 UPDATE

### 传输预写式日志(WAL)

存储引擎通常会将写操作追加到日志中

mysql 通过 redo、undo 日志实现 WAL。

redo log 称为重做日志,每当有操作时,在数据变更之前将操作写入 redo log,这样当发生掉电之类的情况时系统可以在重启后继续操作。

undo log 称为撤销日志,当一些变更执行到一半无法完成时,可以根据撤销日志恢复到变更之间的状态。

mysql 中用 redo log 来在系统 Crash 重启之类的情况时修复数据(事务的持久性),而 undo log 来保证事务的原子性。

缺点:由于日志记录的非常底层(WAL包含哪些磁盘块中的哪些字节发生了变化),当从库和主库运行不同版本时,会出现数据解析问题。

逻辑日志复制(基于行)

复制和存储引擎使用不同的日志格式,将复制日志从存储引擎的内部实现中解耦出来,这种复制日志被称为逻辑日志。

例如:MySQLBinlog

  • 插入行:日志包含所有列的新值
  • 删除行:日志包含主键
  • 更新行:日志包含主键及更新列的新值

优点:逻辑日志和存储引擎内部实现解耦,系统可以做到兼容。从而使主库和从库可以运行不同版本的数据库软件。

基于触发器的复制

将数据更改发生时的自定义代码记录在数据库系统中,使用外部程序读取该表,进行响应的复制。

复制延迟问题

当前存在一个主库,多个从库,在数据复制的过程中,如果从库落后于主库,我们会看到过时的信息。

对主库和从库执行相同的查询,得到不同的结果,等后续一段时间后,从库追上主库保持一致,被称为 最终一致性

读已之写

image-20240220234051681

用户在界面提交一些数据,将其写入到主库,主库异步复制给从库,从而从库追赶上主库。

但如果用户在提交完数据后,立即查询(从库),会发现自己提交的数据库丢失不见

这种情况下,我们需要 写后读一致性,也称为 读己之写一致性,我们需要保证:如果用户重新加载页面,他们总会看到他们自己提交的任何更新

解决方法:

  • 对于用户可能修改的内容,总是从主库获取
    • 用户个人资料只能本人编辑,而不能其他人编辑
    • 从主库读取自己的档案,其他用户档案去从库读取
  • 跟踪上次更新的时间,在数据更新的一分钟内,从主库读取
  • 监控从库的复制延迟,滞后主库超过一分钟的从库不接受查询请求

单调读

image-20240220235435088

当前从库 2 落后从库 1如果用户从不同从库读取

  • 先读取的从库 1,拿到了最新数据
  • 后续读取从库 2,拿到了旧数据

从用户体验来看,时间看上去好像回退了,所以我们需要单调的读取。

单调读 可以保证这种异常不会发生,其程度比 强一致性 弱,比 最终一致性 更强。

实现方式:每个用户总是从一个副本中进行读取(不同客户可以从不同副本读取)。可以基于用户 ID Hash 来选择副本,而不是随机选择读取的数据库副本。

一致前缀读

如果我们有两个因果关系的数据:

Mr. Poons

​ Mrs. Cake,你能看到多远的未来?

Mrs. Cake

​ 通常约十秒钟,Mr. Poons.

假如:

  • Cake 说的话是一个延迟较低的从库
  • Poons 说的话是一个延迟较高的从库

当第三个人在读取数据时,会出现这种情况:

Mrs. Cake

​ 通常约十秒钟,Mr. Poons.

Mr. Poons

​ Mrs. Cake,你能看到多远的未来?

如果某些分区的复制速度慢于其他分区,那么观察者可能会在看到问题之前先看到答案。

需要保证一致前缀读:如果一系列写入按照某个顺序进行,那么任何人读取这些写入时,也看以同样的顺序读取。

解决方案:确保任何因果相关的写入都写入到相同的分区

多主复制

如果数据库被分区,每个分区有一个主库。

多领导配置:处理写入的每个节点都必须将该数据变更转发给其他节点

在这种情况下,每个主库同时是其他主库的从库。

### 多主复制的应用场景

运维多个数据中心

image-20240222000840409

多主配置中在每个数据中心都有主库,每个数据中心内使用常规的主从复制;

在数据中心之间,每个数据中心的主库会将自身变更同步到其他主库。

单主和多主对比:

  • 性能
    • 单主:每个写入操作必须穿过互联网,进入主库所在的数据中心,网络延时较大
    • 多主:每个写入操作在本地数据中心进行处理,与其他数据中心异步复制,网络延时较小
  • 容忍数据中心停机
    • 单主:主库所在的数据中心发生故障,切换另一从库成为主库
    • 多主:数据中心可以独立于其他数据中心继续运行

多主复制的缺点:多主复制在数据库属于改装的功能,常常存在微妙的配置缺陷。因此,多主复制被认为是危险的领域,应尽可能避免。

需要离线操作的客户端

多主复制的另一种适用场景是:应用程序在断网之后仍然需要继续工作。比如:日历应用

在这种情况下,每个设备都有一个充当主库的本地数据库,在所有的设备的日志副本之间同步。

协同编辑

实时协作编辑应用程序允许多个人同时编辑文档

当一个用户编辑文档时,所做的更改将立即应用到其本地副本并异步复制到服务器。

如果不发生编辑冲突,则应用程序必须对文档加锁,为了加速协作,尽可能将加锁的单位设置的非常小。

处理写入冲突

多主复制最大的问题:写入冲突

image-20240222002907115

假如两个人同时更改一个页面

  • 用户 1 将页面标题从 A 更改为 B
  • 用户 2 将页面标题从 A 更改为 C

当异步复制时,就会出现冲突。

同步与异步冲突检测

如果在单主数据库中,两个操作是串行的,不会发生冲突

但多主数据库中,两个分别写入不同的主库,后续异步复制,必然出现冲突问题

避免冲突

处理冲突的最简单的策略就是避免它们:如果应用程序可以确保特定记录的所有写入都通过同一个主库,那么冲突就不会发生。

例如:一个用户编辑自己数据的应用程序,确保来自特定用户的请求始终路由到同一数据中心并使用该数据中心的主库进行读写。

收敛至一致的状态

我们上述的例子中,在多个主库的情况下,我们的写入顺序是不确定的

数据库必须以一种收敛的方式解决冲突,所有副本必须在变更复制完成时收敛到一个相同的最终值。

解决方案:

  • 给每个写入分配唯一ID(时间戳、长随机数、UUID),挑选最高 ID 的写入作为胜利者
  • 给每个副本分配唯一ID,ID更高的写入具有更高的优先级
  • 将这些值链接在一起,比如:B/C
  • 将冲突显式的暴露出来,交于用户决定,比如:GIT冲突

多主复制拓扑

复制拓扑用来描述写入操作从一个节点传播到另一个节点的通信路径。

image-20240222004135809

无主复制

客户端直接写入几个副本中,另一种情况,由一个 协调者 代表客户端写入。

节点故障

无主配置中,发生节点故障,不需要故障转移

如果有三个副本,两个副本写入成功,一个副本写入失败

image-20240222005455126

当我们不可用的副本重新上线,存的是落后的数据

解决方案:当一个客户端从数据库中读取数据时,它不仅仅把它的请求发送到一个副本,而是将读请求将被并行地发送到多个节点,通过版本号来确定哪个值是最近更新的。

读修复和反熵

复制方案应确保最终将所有数据复制到每个副本。在一个不可用的节点重新联机之后,它如何赶上它错过的写入?

  • 读修复:当客户端并行读取多个节点时,检测落后节点的回应,并将最新值写会落后节点。适用于频繁读取的值
  • 反熵过程:数据存储具有后台进程,进程不断查找副本之间的数据差并进行相关的复制追齐。

总结

鲁迅先生曾说:独行难,众行易,和志同道合的人一起进步。彼此毫无保留的分享经验,才是对抗互联网寒冬的最佳选择。

其实很多时候,并不是我们不够努力,很可能就是自己努力的方向不对,如果有一个人能稍微指点你一下,你真的可能会少走几年弯路。

如果你也对 后端架构中间件源码 有兴趣,欢迎添加博主微信:smallyellow521,一起学习,一起成长

我是爱敲代码的小黄,阿里巴巴淘天集团Java开发工程师,双非二本,培训班出身

通过两年努力,成功拿下阿里、百度、美团、滴滴等大厂,想通过自己的事迹告诉大家,努力是会有收获的!

双非本两年经验,我是如何拿下阿里、百度、美团、滴滴、快手、拼多多等大厂offer的?

我们下期再见。

从清晨走过,也拥抱夜晚的星辰,人生没有捷径,你我皆平凡,你好,陌生人,一起共勉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/437665.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pycharm+Selenium WebdriverPython自动化测试

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Windows下CMake使用PCL提示全局作用域没有_open等文件读写函数

表现 解决办法 在导入PCL之前导入Windows SDK相关头文件: #if _WIN32 #include <corecrt_io.h> #endif

Activating More Pixels in Image SuperResolution Transformer

摘要 基于 Transformer 的方法在低级别视觉任务中表现出了令人印象深刻的性能&#xff0c;例如图像超分辨率。然而&#xff0c;我们通过归因分析发现&#xff0c;这些网络只能利用有限的输入信息空间范围。这意味着transformer 的潜力在现有网络中仍未得到充分利用。为了激活更…

2024年最新阿里云服务器地域选择方法,以及可用区说明

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

Qt 绘制中的视口(setViewport)和窗口(setWindow)

重点 &#xff1a; 1.绘制&#xff08;QPainter&#xff09;可以设置视口&#xff0c;视口下设置窗口&#xff0c;而绘制的构件是以窗口为坐标系进行绘画。 2.先根据绘图设备的物理坐标系的矩形位置&#xff0c;设置视图视口setViewport&#xff0c;然后在以视口为区域去设置…

vue基础教程(4)——深入理解vue项目各目录

博主个人微信小程序已经上线&#xff1a;【中二少年工具箱】。欢迎搜索试用 正文开始 专栏简介1. 总览2. node_modules3.public4.src5.assets6.components7.router8.stores9.views10.App.vue11.main.js12.index.html 专栏简介 本系列文章由浅入深&#xff0c;从基础知识到实战…

【开源物联网平台】使用MQTT.fx模拟设备接入FastBee物联网平台

​&#x1f308; 个人主页&#xff1a;帐篷Li &#x1f525; 系列专栏&#xff1a;FastBee物联网开源项目 &#x1f4aa;&#x1f3fb; 专注于简单&#xff0c;易用&#xff0c;可拓展&#xff0c;低成本商业化的AIOT物联网解决方案 目录 一、接入步骤 1.1 创建产品&#xff…

HTTP Cookie 你了解多少?

Cookie是什么&#xff1f; 先给大家举个例子&#xff0c;F12 打开浏览器的页面之后&#xff0c;我们能在 Response Headers 的字段里面看到一个header 叫做 Set-Cookie&#xff0c;如下所示 图中包含的 Set-Cookie 为 Set-Cookie:uuid_tt_dd10_20293537580-1709432565344-232…

【C++】string类的基础操作

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 1. 基本概述 2. string类对象的常见构造 3. string类对象的容量操作 4. string类对象的访问及遍历操作 5. 迭代器 6.…

【智能家居入门1之环境信息监测】(STM32、ONENET云平台、微信小程序、HTTP协议)

作为入门本篇只实现微信小程序接收下位机上传的数据&#xff0c;之后会持续发布如下项目&#xff1a;①可以实现微信小程序控制下位机动作&#xff0c;真正意义上的智能家居&#xff1b;②将网络通讯协议换成MQTT协议再实现上述功能&#xff0c;此时的服务器也不再是ONENET&…

IPSEC VPN 网关模式实验

要求&#xff1a;FW1与FW3建立IPSEC通道&#xff0c;保证10.0.2.0/24网段能访问192.168.1.0/24网段 因为FW1与FW3都处于边界&#xff0c;所以使用网关部署模式来建立IPSEC VPN FW1 这里选择主模式跟隧道模式 FW3与FW1配置类似&#xff0c;与FW1的源目地址反过来&#xff0c;…

-bash: unzip: 未找到命令的解决方案

遇到 -bash: unzip: 未找到命令 这样的错误信息&#xff0c;表示你的系统中没有安装 unzip 工具。unzip 是一个常用的解压工具&#xff0c;用于解压缩 .zip 文件。你可以通过系统的包管理器安装它。 根据你使用的 Linux 发行版&#xff0c;安装 unzip 的命令会有所不同。下面是…

图形系统开发实战课程:进阶篇(上)——10.应用实例:交通路网

图形开发学院&#xff5c;GraphAnyWhere 课程名称&#xff1a;图形系统开发实战课程&#xff1a;进阶篇(上)课程章节&#xff1a;“图形样式”原文地址&#xff1a;https://www.graphanywhere.com/graph/advanced/2-10.html 第十章 应用实例&#xff1a;交通路网 \quad 在前面几…

老师如何发布已点评的学生在校表现,并让家长留言反馈?

教师想要在线上发布已点评过的成绩单&#xff0c;同时想让家长在线留言反馈&#xff0c;还要做到只能查自己孩子的成绩&#xff0c;应该如何实现&#xff1f; 可以使用易查分制作一个学生在校表现查询系统&#xff0c;家长自主查询&#xff0c;有问题可留言向班主任反馈&#x…

什么是工业协议网关?作用是什么?

在工业自动化和智能制造领域&#xff0c;数据的采集、传输和处理是实现设备监控、远程控制和优化的关键。而工业协议网关&#xff0c;作为连接工业设备与上层管理系统的桥梁&#xff0c;发挥着至关重要的作用。今天&#xff0c;我们就来深入解析一下HiWoo Box这一工业协议网关的…

银行数字化转型导师坚鹏:银行数字化转型案例研究

银行数字化转型案例研究 课程背景&#xff1a; 数字化背景下&#xff0c;很多银行存在以下问题&#xff1a; 不清楚银行科技金融数智化案例&#xff1f; 不清楚银行供应链金融数智化案例&#xff1f; 不清楚银行普惠金融数智化案例&#xff1f; 不清楚银行跨境金融数智…

ACM题解Day10|总结篇|进制转化,GCD ,LCM ,二分答案

&#x1f525;博客介绍&#xff1a; 27dCnc [Cstring中find_first_not_of()函数和find_last_not_of()函数-CSDN博客] 方差,期望 概率 今日打卡: 算法周总结 ACM题解Day3| To Crash or not To Crash,Integer Prefix ,I don’t want to pay for the Late Jar-CSDN博客 第3题:…

温室气体排放控制中的DNDC模型建模技术及双碳应用

由于全球变暖、大气中温室气体浓度逐年增加等问题的出现&#xff0c;“双碳”行动特别是碳中和已经在世界范围形成广泛影响。国家领导人在多次重要会议上讲到&#xff0c;要把“双碳”纳入经济社会发展和生态文明建设整体布局。同时&#xff0c;提到要把减污降碳协同增效作为促…

蓝牙 | 软件: Qualcomm BT Audio 问题分析(4)----检查MIPS使用情况

大家好&#xff01; 我是“声波电波还看今朝”成员的一位FAE Devin.wen&#xff0c;欢迎大家关注我们的账号。 今天给大家大概讲解“如何排查Qualcomm BT Audio”的疑难杂症&#xff08;四&#xff09;&#xff1a;MIPS检查。 如果大家还没有注册我们大大通的账号&#xff0c…

彻底理解Java并发:乐观锁、悲观锁和CAS

一、悲观锁与乐观锁 锁的一种宏观分类方式是悲观锁和乐观锁。悲观锁与乐观锁并不是特指某个锁&#xff08;Java 中没有哪个 Lock 实现类就叫 PessimisticLock 或 OptimisticLock&#xff09;&#xff0c;而是在并发情况下的两种不同策略。 1、乐观锁&#xff08;Optimistic L…