分布式系统中的数据复制

简介: 网络故障可能会导致主主架构中的数据不一致。让我们用一个例子来理解这一点,假设我们有两个数据库实例 A 和 B。

什么是数据复制?

数据复制是指将数据复制到一个或多个数据容器以确保可用性的过程。复制的数据通常存储在不同的数据库实例中,即使一个实例发生故障,我们也可以从其他实例获取数据。

一种流行数据复制的实现架构是主从架构。

推荐博主开源的 H5 商城项目waynboot-mall,这是一套全部开源的微商城项目,包含三个项目:运营后台、H5 商城前台和服务端接口。实现了商城所需的首页展示、商品分类、商品详情、商品 sku、分词搜索、购物车、结算下单、支付宝/微信支付、收单评论以及完善的后台管理等一系列功能。 技术上基于最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中间件。分模块设计、简洁易维护,欢迎大家点个 star、关注博主。

github 地址:github.com/wayn111/way…

主从架构

为了理解这个架构,我们举一个例子。

  • 我们有四个客户端,每个客户端都连接到一个负载均衡器。
  • 然后负载均衡器将请求分发到三个应用程序服务器。
  • 每台服务器连接到一个数据库实例。

你能注意到这里有什么问题吗?

我们的数据库存在单点故障。如果它崩溃了,我们的整个系统就会停止工作。

为了避免这种单点故障,我们可以使用另一个数据库(最好是不同的数据库实例)来存储原始数据的副本(一般我们成为从库)。现在如果原始数据库(主库)崩溃,我们可以将请求转到从库。

但是我们如何保持从库与主库同步呢?这有两种方法。

同步复制数据

  • 在这种方法中,数据同时写入主库和从库
  • 数据始终一致。即数据如果写入主库,它也会写入从库
  • 数据库负载较高

异步复制数据

  • 在这种方法中,首先将数据写入主库,并定期将更新写入从库
  • 由于复制以固定间隔进行,因此存在数据丢失和不一致的可能性
  • 数据库负载相对较低

这里我们的一般定义是收到写请求的主库数据库是 master)。从库被称为 slaves。

image.png

如上图我们的主站也就是 Server2 维护事务日志。他会更新从站中(Server1)的数据,它发送命令,然后从站以相同的顺序执行这些命令。

如果服务器向从站发送写入请求会发生什么?

有两种方法可以处理这种情况

  • 不允许对从站的写请求,从站无法写入数据库,它只能去读从库数据。
  • 允许从站写入数据。我们将允许从站写入数据。然后从站将更改复制到主站。在这种情况下,从站就接替了主站的角色。所以不再是主从架构而是主主架构

主主架构的问题

网络故障可能会导致主主架构中的数据不一致。

让我们用一个例子来理解这一点,假设我们有两个数据库实例 A 和 B。

  • 两人都是 master。
  • 它们之间的路由器出现故障。所以 A 认为 B 离线,B 认为 A 离线。
  • 他们有一个数据项 X,其值最初为 100。

现在用户发送以下请求,

  • X 减去 20,该请求被路由到 A,此时 A 中 X 的值为 80。
  • X 减去 80,这个请求被路由到 B(因为都是 master,所以写请求可以路由到任何数据库)。现在 B 中 X 的值为 20。

由于存在通信故障,A 和 B 无法同步,它们具有不同的数据值,因此不一致。

  • 现在,如果用户发出读请求,他/她将获得不同的值,具体取决于他/她将连接到的数据库。

这个问题被称为裂脑问题。

解决裂脑问题

image.png

我们可以通过添加第三个节点(数据库实例)来解决裂脑问题。

这里我们假设一个节点崩溃以及其他两个节点之间的路由器崩溃的可能性极小。

让我们考虑三个数据库实例 A、B 和 C。

  • 如果 C 崩溃,A 和 B 是主库并且它们是同步的。所以他们处于一致的状态。当 C 在线时,他们可以读取 A 或 B 的内容。
  • 如果 A 和 B 之间出现通信故障
  • 当 A 收到写入请求时,它将其状态传播到 C。最初状态为 S0,然后转移到 Sx。所以现在 A 和 C 都有 Sx。
  • 当 B 收到写入请求时,它将其状态从 S0 移至 Sy。它尝试将其状态传播到 C,但失败,因为 B 的先前状态不等于 C。现在 B 中止写入请求并将其状态更新为 Sx。现在 B 可以接受写入请求并将更改传播到 C。

这称为分布式共识。多个节点就特定值达成一致。在这种情况下,A、B 和 C 在最终状态上达成一致。

最后

感谢您的阅读,希望本文能对你理解分布式架构中的数据复制有所帮助。

目录
相关文章
|
1月前
|
算法 Java 关系型数据库
漫谈分布式数据复制和一致性!
漫谈分布式数据复制和一致性!
|
存储 大数据
大数据数据存储的分布式文件系统的HDFS的核心机制理解的数据复制和原理
在 Hdfs 中,数据的复制和原理是基于块的分布式存储。
140 1
|
1月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
3月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
112 2
基于Redis的高可用分布式锁——RedLock
|
3月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
8天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
41 16
|
1月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
59 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
1月前
|
NoSQL Redis 数据库
计数器 分布式锁 redis实现
【10月更文挑战第5天】
47 1
|
1月前
|
NoSQL 算法 关系型数据库
Redis分布式锁
【10月更文挑战第1天】分布式锁用于在多进程环境中保护共享资源,防止并发冲突。通常借助外部系统如Redis或Zookeeper实现。通过`SETNX`命令加锁,并设置过期时间防止死锁。为避免误删他人锁,加锁时附带唯一标识,解锁前验证。面对锁提前过期的问题,可使用守护线程自动续期。在Redis集群中,需考虑主从同步延迟导致的锁丢失问题,Redlock算法可提高锁的可靠性。
74 4
|
1月前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
61 4

热门文章

最新文章