《数据密集型系统应用》笔记(四)

89 阅读5分钟

《数据密集型系统应用》笔记(四)

[TOC]

分布式数据

可扩展性, 水平扩展

replication / partition

区别是冗余还是分片/区

replication复制

术语: leader follower (master/salve)

常见架构:

image-20240614174130600.png

同步复制和异步复制

区别在于是否丢失,数据一致性

image-20240614174226646.png

1.是同步的 ,只有复制完成了,才进行确认这叫做同步 有点一致缺陷, 效率

  1. 是异步的,

保证你至 少在两个节点上拥有最新的数据副本:主库和同步从库。 这种配置有时也被称为半同步 (semi-synchronous)

这其实就和Raft等一致性协议相统一了,保证版本的节点确认;

设置新从库

加入集群?

  1. 读取快照
  2. 复制如从库
  3. 拉取最新变更 如binlog
  4. catchup 追赶完成

这个基本上也是mysql redis 措施

宕机

不影响可用性 HA

从库recover 故障恢复

护肤后能能够连接主库进行追赶

主库故障failover

发生故障能够切换 1, 故障检测 2. 重新选主 3. 配置新主库, 老主库退化为从库

复制延迟

这种不一致只是一个暂时的状态——如果停止写 入数据库并等待一段时间,从库最终会赶上并与主库保持一致。

写后读

一些读写分离的集群会遇到问题,

image-20240614200040921.png

用户的写后状态无法被立即读到, 读写一致性,那么如何保证呢? 这也是对一些基架团队的一些挑战

145/469

方案一:

读用户可能已经修改过的内容时,都从主库读;。因此一个简单的规则是:从主库读取用户自 己的档案,在从库读取其他用户的档案。 ( 有点将连接进行分片的意思)

方案二:

更新后一定时间内从主库读(这个时间根据主从延迟决定);监控从库的复制延迟,防止任向任何滞后超过一分钟到底从库发出查询。

方案三:

客户端可以记住最近一次写入的时间戳,系统需要确保从库为该用户提供任何查询时, 该时间戳前的变更都已经传播到了本从库中。如果当前从库不够新,则可以从另一个从 库读,或者等待从库追赶上来

根据数据的事件戳

方案四:

leader根据请求进行路由分配,但是这个策略也要细化,比较复杂

单调读

从不同的存库读取;

image-20240614201013952.png

但调度就是指是这种异常不会发生的保证。要保证读取的快照一直是往前的

一致前缀读

image-20240614201105221.png

这个问题讨论的是数据之间存在有序性, 一直前缀读解决的是乱序问题: 按照顺序写入,也许按照顺序读取;

(仅讨论这个问题,一般情况下,我想到的方案主要是通过消息队列保证顺序消费, 这里要至于统一的分片key)

复制延迟的解决方案

解决复制的延迟,可以解决的读取一致性问题;

多主复制

解决的是一个主库,都要从他进行复制的单点性能瓶颈,降低复制延迟

image-20240617153610647.png

多主复制的好处

1.性能,多主处理写入

2.停机容忍 |

3.网络容忍| 合起来就是错误容忍

缺点:

1.更复杂的一致性问题,同时修改?

2.复杂的配置问题; 如自增主键?触发器? 完整性约束?

多主写入冲突的解决;

同步异步冲突检测;

其实就是写入加锁 进行阻塞;

收敛一致状态

,每个复制方案都必须确保数据在所有副本 中最终都是相同的。因此,数据库必须以一种收敛(convergent)的方式解决冲突,这意味 着所有副本必须在所有变更复制完成时收敛至一个相同的最终值

解决方案

  1. 对写入加id ,保证有序
  2. 副本加id,对处理副本的写入按照副本id进行排序; 但是有损失指令间的有序性被抹掉了

多主复制

image-20240617161043189.png

解决方案: 版本向量:

无主复制

LWW(last write wins) 最后写入胜利, 表示并发写入会被丢弃,只保留最后更改

合并同时写入的值

有点像是redis 重写

版本向量

版本向量(Version Vector)是一种数据结构,常用于分布式系统中,以跟踪不同节点上的数据副本的版本信息。它的主要目的是解决数据同步和冲突检测问题。

### 版本向量的工作原理:

1. **初始化**:每个节点都维护一个版本向量。版本向量中的每个条目通常由一个节点标识符(如节点的ID)和一个计数器组成。
2. **更新操作**:每当节点更新数据时,它会增加其版本向量中相应计数器的值。这样,版本向量就反映了该节点的最新状态。
3. **同步操作**:当两个节点进行数据同步时,它们交换各自的版本向量。通过比较版本向量,系统可以确定哪些更新是最新的,哪些是冲突的。
4. **冲突检测**:如果两个节点的版本向量中对应的计数器值不同,则可能存在冲突。系统需要应用冲突解决策略(如基于时间戳或特定的业务逻辑)来处理这些冲突。

### 示例:

假设有三个节点 A、B、C,它们的初始版本向量都是 `[0, 0, 0]`- 节点 A 更新数据后,版本向量变为 `[1, 0, 0]`- 节点 B 更新数据后,版本向量变为 `[0, 1, 0]`- 当节点 A 和节点 B 进行同步时,它们交换版本向量并检测到版本不同。通过版本向量 `[1, 0, 0]``[0, 1, 0]` 可以知道数据是独立更新的,没有冲突发生。

版本向量在分布式数据库、文件系统以及各种需要数据同步和冲突检测的系统中广泛应用,能够有效地帮助这些系统保持数据的一致性。