《数据密集型系统应用》笔记(四)
[TOC]
分布式数据
可扩展性, 水平扩展
replication / partition
区别是冗余还是分片/区
replication复制
术语: leader follower (master/salve)
常见架构:
同步复制和异步复制
区别在于是否丢失,数据一致性
1.是同步的 ,只有复制完成了,才进行确认这叫做同步 有点一致缺陷, 效率
- 是异步的,
保证你至 少在两个节点上拥有最新的数据副本:主库和同步从库。 这种配置有时也被称为半同步 (semi-synchronous)
这其实就和Raft等一致性协议相统一了,保证版本的节点确认;
设置新从库
加入集群?
- 读取快照
- 复制如从库
- 拉取最新变更 如binlog
- catchup 追赶完成
这个基本上也是mysql redis 措施
宕机
不影响可用性 HA
从库recover 故障恢复
护肤后能能够连接主库进行追赶
主库故障failover
发生故障能够切换 1, 故障检测 2. 重新选主 3. 配置新主库, 老主库退化为从库
复制延迟
这种不一致只是一个暂时的状态——如果停止写 入数据库并等待一段时间,从库最终会赶上并与主库保持一致。
写后读
一些读写分离的集群会遇到问题,
用户的写后状态无法被立即读到, 读写一致性,那么如何保证呢? 这也是对一些基架团队的一些挑战
145/469
方案一:
读用户可能已经修改过的内容时,都从主库读;。因此一个简单的规则是:从主库读取用户自 己的档案,在从库读取其他用户的档案。 ( 有点将连接进行分片的意思)
方案二:
更新后一定时间内从主库读(这个时间根据主从延迟决定);监控从库的复制延迟,防止任向任何滞后超过一分钟到底从库发出查询。
方案三:
客户端可以记住最近一次写入的时间戳,系统需要确保从库为该用户提供任何查询时, 该时间戳前的变更都已经传播到了本从库中。如果当前从库不够新,则可以从另一个从 库读,或者等待从库追赶上来
根据数据的事件戳
方案四:
leader根据请求进行路由分配,但是这个策略也要细化,比较复杂
单调读
从不同的存库读取;
但调度就是指是这种异常不会发生的保证。要保证读取的快照一直是往前的
一致前缀读
这个问题讨论的是数据之间存在有序性, 一直前缀读解决的是乱序问题: 按照顺序写入,也许按照顺序读取;
(仅讨论这个问题,一般情况下,我想到的方案主要是通过消息队列保证顺序消费, 这里要至于统一的分片key)
复制延迟的解决方案
解决复制的延迟,可以解决的读取一致性问题;
多主复制
解决的是一个主库,都要从他进行复制的单点性能瓶颈,降低复制延迟
多主复制的好处
1.性能,多主处理写入
2.停机容忍 |
3.网络容忍| 合起来就是错误容忍
缺点:
1.更复杂的一致性问题,同时修改?
2.复杂的配置问题; 如自增主键?触发器? 完整性约束?
多主写入冲突的解决;
同步异步冲突检测;
其实就是写入加锁 进行阻塞;
收敛一致状态
,每个复制方案都必须确保数据在所有副本 中最终都是相同的。因此,数据库必须以一种收敛(convergent)的方式解决冲突,这意味 着所有副本必须在所有变更复制完成时收敛至一个相同的最终值
解决方案
- 对写入加id ,保证有序
- 副本加id,对处理副本的写入按照副本id进行排序; 但是有损失指令间的有序性被抹掉了
多主复制
解决方案: 版本向量:
无主复制
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]` 可以知道数据是独立更新的,没有冲突发生。
版本向量在分布式数据库、文件系统以及各种需要数据同步和冲突检测的系统中广泛应用,能够有效地帮助这些系统保持数据的一致性。