算法基础——一致性
引入
最早研究一致性的场景既不是大数据领域,也不是分布式系统,而是多路处理器。
可以将多路处理器理解为单机计算机系统内部的分布式场景,它有多个执行单元,每一个执行单元都有自己的存储(缓存),一个执行单元修改了自己存储中的一个数据后,这个数据在其他执行单元里面的副本就面临数据一致的问题。
随着时代发展,互联网公司的快速发展,单机系统在计算和存储方面都开始面临瓶颈,分布式是一个必然的选择,但是这也进一步放大了数据一致性面临的问题。对于数据的一致性,最理想的模型当然是表现得和一份数据完全一样,修改没有延迟,即所有的数据修改后立即被同步。但在现实世界中,数据的传播是需要时间的,所以理想的一致性模型是不存在的。
不过从应用层的角度来看,我们并不需要理想的一致性模型,只需要一致性模型能满足业务场景的需求就足够了,比如在统计分析类的场景中,是能容忍一定的误差的,而评论之类的场景中,可能只要有因果关系的操作顺序一致就可以了。
同时由于一致性要求越高,实现的难度和性能消耗就越大,所以我们可以通过评估业务场景来降低数据一致性的要求,这样人们就定义了不同的一致性模型来满足不同的需求。这种思路其实和我们在深入HDFS提到基于环境去衡权是类似的。
一致性模型
下面我们先看看四个经典且常见的一致性模型:线性一致性、顺序一致性、因果一致性和最终一致性。
线性一致性(Linearizability)
线性一致性是 Herlihy 和 Wing 等于 1987 年在论文 “Axioms for Concurrent Objects” 中提出的,线性一致性也被称为原子一致性(Atomic Consistency)、强一致性(Strong Consistency)、立即一致性(Immediate Consistency)和外部一致性 (External Consistency)。
线性一致性是非常重要的一个一致性模型,在分布性锁、Leader 选举、唯一性约束等很多场景都可以看到它的身影。
这是最强的一致性模型。在这种模型下,系统表现得就好像只有一个数据副本,一旦新的值被写入或读取,所有后续的读都会看到写入的值,直到它被再次覆盖。在线性一致性模型中不论是数据的覆盖顺序还是读取顺序,都是按时间线从旧值向新值移动,而不会出现旧值反转的情况。
实现原理:要求所有的操作看起来是瞬时完成的,并且按照全局的时间顺序排列。
适用场景:对数据一致性要求极高的场景,如分布式事务处理。
优点:提供了最强的一致性保证,易于理解和推理。
缺点:实现代价高,性能开销大。
顺序一致性(Sequential Consistency)
顺序一致性是 Leslie Lamport 在 1979 年发表的论文 “How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Program” 中提出的,在论文中具体的定义如下:
A multiprocessor is said to be sequentially consistent if the result of any execution is the same as if the operations of all the processors were executed in some sequential order,and the operations of each individual processor appear in this sequence in the order specified by its program.
如果任何执行的结果与所有处理器的操作都以某种顺序执行的结果相同,并且每个单独的处理器的操作按照其程序顺序出现在该序列中,则称多处理器是顺序一致的
相对于线性一致性来说,顺序一致性在一致性方面有两点放松:
- 对于写操作,对没有因果关系的非并发写入操作,不要求严格按时间排序;
- 对于读操作,只要求所有的客户端观察到的顺序一致性,不要求写入后,所有的客户端都必须读取新值。
顺序一致性要求所有进程的操作都按照某种全局顺序执行,每个进程的操作在这个全局顺序中保持其原有的顺序。但并不要求操作的结果立即对所有进程可见,只需要保证所有进程看到的操作顺序是一致的。
实现原理:只要所有进程看到的操作顺序符合某种合法的全局顺序即可。
适用场景:多处理器系统中的共享内存模型。
优点:比线性一致性的限制稍弱,实现相对容易一些。
缺点:仍然对系统性能有一定影响。
因果一致性(Causal Consistency)
因果一致性是 Mustaque Ahamad, Gil Neiger, James E. Burns, Prince Kohli, Phillip W. Hutto 在 1991 年发表的论文 “Causal memory: definitions, implementation, and programming” 中提出的一种一致性强度低于顺序一致性的模型。
相对于顺序一致性来说,因果一致性在一致性方面有两点放松:
- 对于写操作,对没有因果关系的非并发写入操作,不仅不要求按时间排序,还不再要求节点 之间的写入顺序一致了;
- 对于读操作,由于对非并发写入顺序不再要求一致性,所以自然也无法要求多个客户端必须 观察到一样的顺序。
因果一致性模型保证如果一个操作 A 的执行结果会影响到另一个操作 B 的执行,那么所有进程都必须以 A 在 B 之前的顺序看到这两个操作。也就是说,存在因果关系的操作在所有节点上都以相同的因果顺序执行,但没有因果关系的操作可以以不同的顺序执行。
实现原理:通过识别和跟踪操作之间的因果关系来实现。
适用场景:对部分操作有顺序要求,但又希望提高系统性能和扩展性的场景,如分布式社交网络。
优点:在保证一定因果顺序的前提下,提高了系统的灵活性和性能。
缺点:因果关系的判断和处理较为复杂。
最终一致性(Eventual Consistency)
最终一致性是 Amazon 的 CTO Werner Vogels 在 2009 年发表的一篇论文 “Eventual Consistency” 里提出的,它是 Amazon 基于 Dynamo 等系统的实战经验所总结的一种很务实的实现,它不同于前面几种由大学计算机科学的教授提出的一致性模型,所以也没有非常学院派清晰的定义。
最终一致性是指在经过一段时间的延迟后,系统中的所有数据副本最终会达到一致的状态。在数据更新后的一段时间内,不同节点上的数据可能存在不一致,但随着时间的推移,数据会逐渐趋于一致。
“最终”是一个模糊的、不确定的概念,它是没有明确上限的,Vogels 提出这个不一致的时间窗口可能是由通信延迟、负载和复制次数造成的,但是最终所有进程的观点都一致,这个不一致的时间窗口可能是几秒也可能是几天。所以,最终一致性是一个一致性非常低的模型,但是它能非常高性能地实现,在一些业务量非常大,但是对一致性要求不高的场景,是非常推荐使用的。
实现原理:通常通过数据的异步复制和传播来实现。
适用场景:对数据一致性要求不那么严格,对可用性和性能要求较高的场景,如缓存系统。
优点:具有高可用性和良好的性能扩展性。
缺点:可能会在一段时间内存在数据不一致的情况。
经典一致性算法
2PC(Two-Phase Commit,两阶段提交)
2PC协议解决阻塞、数据不一致问题和单点问题。
原理:
- 准备阶段:协调者向所有参与者发送事务请求,参与者执行事务操作但不提交,记录日志并向协调者反馈执行结果。
- 提交阶段:若所有参与者都反馈成功,协调者发送提交指令,参与者正式提交事务;否则,协调者发送回滚指令,参与者回滚事务。
- 应用场景:对一致性要求较高,且能容忍一定性能开销的事务处理场景。
优点:原理简单、实现方便。能够保证事务的原子性,在大多数情况下可以有效地保证数据一致性。
缺点:单点故障问题,协调者故障可能导致整个事务阻塞;没有容错机制,参与者故障可能导致数据不一致;同步阻塞问题,会影响系统性能和并发度。
3PC(Three-Phase Commit,三阶段提交)
3PC协议解决2PC的阻塞,但还是可能造成数据不一致。
原理:
- 询问阶段:协调者询问参与者是否可以执行事务,参与者根据自身情况回复是否可以。
- 准备阶段:若询问阶段所有参与者都回复可以,协调者发送预提交请求,参与者执行事务操作并记录日志,向协调者反馈结果。
- 提交阶段:根据准备阶段的反馈,协调者决定提交或回滚事务并通知参与者执行。
应用场景:类似 2PC,但对系统可用性要求更高的场景。
优点:能够减小参与者阻塞范围,并能够在出现单点故障后继续达成一致。
缺点:实现相对复杂,性能开销较大;引入预提交阶段,在这个阶段如果出现网络分区,协调者将无法与参与者正常通信,参与者依然会进行事务提交,造成数据不一致。
Paxos算法
Paxos是基于消息传递的一致性算法。
其实,2PC和3PC都是分布式一致性算法的“残次”版本。Google Chubby的作者迈克·伯罗斯(Mike Burrows)说过,这个世界上只有一种一致性算法,那就是Paxos,其他算法都是残次品。
原理:通过多个节点之间的消息交互,选举出一个主节点来决定提案的通过与否,保证在多个节点中就某个值达成一致。主要角色有提议者、接受者、学习者,提议者提出提案,接受者决定是否接受提案,学习者学习被选定的提案。
应用场景:常用于分布式系统中的配置管理、分布式数据库的一致性维护等,如ZooKeeper中就使用了Paxos的变种算法。
优点:理论上能够保证在任何分布式环境下的一致性,具有很强的容错性和可靠性。
缺点:算法复杂,理解和实现难度大;性能方面,在大规模集群中可能存在较多的消息交互,影响效率。
Raft算法
Raft协议解决Paxos的实现难度。在Raft实现上,其将角色简化为Follower、Candidate、Leader这3种,角色本身代表状态,角色之间进行状态转移是一件非常自由的事情。Raft虽然有角色之分,但是采用的是全民参与选举的模式。在Paxos里,更像是议员参政模式。
原理:将节点分为领导者、跟随者和候选人三种角色。通过选举产生领导者,领导者负责接收客户端请求并向跟随者同步数据,保证数据的一致性。选举过程中,节点通过投票来选出任期内的领导者。
应用场景:广泛应用于分布式存储系统、分布式数据库等,如etcd就采用了Raft算法来保证数据一致性。
优点:相比Paxos算法更易于理解和实现,在性能和可用性方面表现较好,能够快速进行领导者选举和数据同步。
缺点:在极端网络环境下,如网络分区时间过长时,可能会出现数据不一致的情况。
ISR(In-Sync Replicas,同步副本)
ISR机制解决了容错的2N+1成本问题。
原理:Kafka中的每个分区都有一个领导者副本和多个跟随者副本,ISR 是与领导者副本保持同步的跟随者副本集合。生产者发送消息到领导者副本,领导者副本将消息写入本地日志后,会等待ISR中的所有副本都复制完消息后才向生产者确认消息发送成功,保证消息的一致性。
应用场景:适用于分布式消息队列系统,如Kafka在处理大规模消息的生产和消费时,并没有使用Zab或Paxos协议的多数投票机制来保证主备数据的一致性,而是通过ISR机制来保证数据一致性,并确保消息的可靠传递。
优点:能够在保证数据一致性的同时,提供较高的吞吐量和性能,支持大规模的消息处理。
缺点:ISR的管理和维护相对复杂,当ISR中的副本数量较少时,可能会影响数据的可靠性和一致性。
实用拜占庭容错(Practical Byzantine Fault Tolerance,PBFT)
实用拜占庭容错协议解决节点不可信问题(拜占庭将军问题)。Lamport证明在存在消息丢失的不可靠信道上试图通过消息传递的方式达到一致性是不可能的。因此,在研究拜占庭将军问题的时候,要先假定信道是没有问题的,然后去做一致性和容错性的相关研究。
原理:在分布式系统中,节点之间通过消息传递进行通信,PBFT通过节点之间的消息交互和验证,在存在恶意节点(拜占庭节点)的情况下,仍然能够保证系统的一致性和正确性。算法通过视图切换、预准备、准备、提交等多个阶段来达成共识。
应用场景:对安全性要求极高的分布式系统,尤其是存在恶意攻击风险的环境。如区块链、金融交易系统等。
优点:能够容忍一定数量的拜占庭故障节点,保证系统的安全性和一致性,在联盟链等场景中有较好的应用。
缺点:通信复杂度高,性能开销大,随着节点数量增加,消息数量呈指数级增长,会影响系统的性能和扩展性。
总结
本文梳理了一致性问题来源和解决模型,以及经典常用的一致性算法,感兴趣的小伙伴可以深入了解不同算法的具体落地应用。后续在深入大数据相关技术技术框架时,遇到相关算法,我们再深入看看。
相关文章:
算法基础——一致性
引入 最早研究一致性的场景既不是大数据领域,也不是分布式系统,而是多路处理器。 可以将多路处理器理解为单机计算机系统内部的分布式场景,它有多个执行单元,每一个执行单元都有自己的存储(缓存),一个执行单元修改了…...
【数据采集】案例01:基于Scrapy采集豆瓣电影Top250的详细数据
基于Scrapy采集豆瓣电影Top250的详细数据 Scrapy 官方文档:https://docs.scrapy.org/en/latest/豆瓣电影Top250官网:https://movie.douban.com/top250写在前面 实验目的:基于Scrapy框架采集豆瓣电影Top250的详细数据。 电脑系统:Windows 使用软件:PyCharm、Navicat Python…...
设计模式 - 行为模式_Template Method Pattern模板方法模式在数据处理中的应用
文章目录 概述1. 核心思想2. 结构3. 示例代码4. 优点5. 缺点6. 适用场景7. 案例:模板方法模式在数据处理中的应用案例背景UML搭建抽象基类 - 数据处理的 “总指挥”子类定制 - 适配不同供应商供应商 A 的数据处理器供应商 B 的数据处理器 在业务代码中整合运用 8. 总…...
Spring Boot框架下的单元测试
1. 什么是单元测试 1.1 基本定义 单元测试(Unit Test) 是对软件开发中最小可测单位(例如一个方法或者一个类)进行验证的一种测试方式。在 Java 后端的 Spring Boot 项目中,单元测试通常会借助 JUnit、Mockito 等框架对代码中核心逻辑进行快…...
git中文件的状态状态切换
在 Git 中,文件的状态是指文件相对于 Git 仓库的当前情况。以下是一些常见的文件状态及其含义: 未跟踪(Untracked): 这是新创建的文件或从其他位置复制过来的文件,Git 还没有开始跟踪这些文件的更改。 这些…...
基于脉冲响应不变法的IIR滤波器设计与MATLAB实现
一、设计原理 脉冲响应不变法是一种将模拟滤波器转换为数字滤波器的经典方法。其核心思想是通过对模拟滤波器的冲激响应进行等间隔采样来获得数字滤波器的单位脉冲响应。 设计步骤: 确定数字滤波器性能指标 将数字指标转换为等效的模拟滤波器指标 设计对应的模拟…...
RabbitMQ快速上手及入门
概念 概念: publisher:生产者,也就是发送消息的一方 consumer:消费者,也就是消费消息的一方 queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理 exchang…...
自动化构建-make/Makefile 【Linux基础开发工具】
文章目录 一、背景二、Makefile编译过程三、变量四、变量赋值1、""是最普通的等号2、“:” 表示直接赋值3、“?” 表示如果该变量没有被赋值,4、""和写代码是一样的, 五、预定义变量六、函数**通配符** 七、伪目标 .PHONY八、其他常…...
计算机网络之计算机网络的分类
计算机网络可以根据不同的角度进行分类,以下是几种常见的分类方式: 1. 按照规模和范围: 局域网(LAN,Local Area Network):覆盖较小范围(例如一个建筑物或校园)…...
MySQl的日期时间加
MySQL日期相关_mysql 日期加减-CSDN博客MySQL日期相关_mysql 日期加减-CSDN博客 raise notice 查询目标 site:% model:% date:% target:%,t_shipment_date.site,t_shipment_date.model,t_shipment_date.plant_date,v_date_shipment_qty_target;...
响应式编程与协程
响应式编程与协程的比较 响应式编程的弊端虚拟线程Java线程内核线程的局限性传统线程池的demo虚拟线程的demo 响应式编程的弊端 前面用了几篇文章介绍了响应式编程,它更多的使用少量线程实现线程间解耦和异步的作用,如线程的Reactor模型,主要…...
智能小区物业管理系统推动数字化转型与提升用户居住体验
内容概要 在当今快速发展的社会中,智能小区物业管理系统的出现正在改变传统的物业管理方式。这种系统不仅仅是一种工具,更是一种推动数字化转型的重要力量。它通过高效的技术手段,将物业管理与用户居住体验紧密结合,无疑为社区带…...
从Proxmox VE开始:安装与配置指南
前言 Proxmox Virtual Environment (Proxmox VE) 是一个开源的虚拟化平台,基于Debian Linux,支持KVM虚拟机和LXC容器。它提供了一个强大的Web管理界面,方便用户管理虚拟机、存储、网络等资源。Proxmox VE广泛应用于企业级虚拟化、云计算和开…...
【Docker项目实战】使用Docker部署MinIO对象存储(详细教程)
【Docker项目实战】使用Docker部署MinIO对象存储 前言一、 MinIO介绍1.1 MinIO简介1.2 主要特点1.3 主要使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载MinIO镜像五、…...
【C++】B2115 密码翻译
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目解析💯1. 老师的做法代码实现:思路解析: 💯2. 我的做法代码实现:思路分析: 💯3. 老师…...
02.04 数据类型
请写出以下几个数据的类型: 整数 a ----->int a的地址 ----->int* 存放a的数组b ----->int[] 存放a的地址的数组c ----->int*[] b的地址 ----->int* c的地址 ----->int** 指向printf函数的指针d ----->int (*)(const char*, ...) …...
Leetcode—598. 区间加法 II【简单】
2025每日刷题(206) Leetcode—598. 区间加法 II 实现代码 class Solution { public:int maxCount(int m, int n, vector<vector<int>>& ops) {int ans m * n;int x ops.size();if(ops.empty()) {return ans;}int xm ops[0][0], ym …...
AI浪潮下的IT从业者:危机、机遇与进化之路
目录 0. 前言1. 当前形势:站在十字路口1.1 AI的突飞猛进1.2 行业现状分析 2. 核心应对策略2.1 技术深度与广度的平衡2.2 人机协同的工作模式2.3 持续学习与创新 3. 结语 0. 前言 在人工智能快速发展的今天,IT从业者面临前所未有的挑战与机遇。本文将从实…...
OpenCV:图像轮廓
目录 简述 1. 什么是图像轮廓? 2. 查找图像轮廓 2.1 接口定义 2.2 参数说明 2.3 代码示例 2.4 运行结果 3. 绘制图像轮廓 3.1 接口定义 3.2 参数说明 3.3 代码示例 3.4 运行结果 4. 计算轮廓周长 5. 计算轮廓面积 6. 示例:计算图像轮廓的面…...
洛谷P11655「FAOI-R5」Lovely 139
P11655「FAOI-R5」Lovely 139 题目背景 Update:数据有 0 0,答案为 1,请选手特判以正常通过。 Height ≤ 139 \text{Height}\leq139 Height≤139。 题目描述 对于一个 01 \tt 01 01 串 S S S(下标从 1 1 1 开始)…...
文字显示省略号
多行文本溢出显示省略号...
Windows图形界面(GUI)-QT-C/C++ - QT Tab Widget
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 一、概述 1.1 什么是 QTabWidget? 1.2 使用场景 二、常见样式 2.1 选项卡式界面 2.2 动态添加和删除选项卡 2.3 自定义选项卡标题和图标 三、属性设置 3.1 添加页面&…...
C++11 多线程 锁与条件变量:mutex、lock_guard、unique_lock 和 condition_variable
文章目录 mutex核心成员函数使用场景 lock_guard功能和特性构造函数使用场景 unique_lock功能和特性构造函数核心成员函数使用场景 lock_guard对比unique_lockcondition_variable核心成员函数使用场景 mutex std::mutex 是 C 标准库中提供的一种互斥量,用于在多线程…...
【Proteus】NE555纯硬件实现LED呼吸灯效果,附源文件,效果展示
本文通过NE555定时器芯片和简单的电容充放电电路,设计了一种纯硬件实现的呼吸灯方案,并借助Proteus仿真软件验证其功能。方案无需编程,成本低且易于实现,适合电子爱好者学习PWM(脉宽调制)和定时器电路原理。 一、呼吸灯原理与NE555功能分析 1. 呼吸灯核心原理 呼吸灯的…...
Cosmos - 世界模型开发平台
文章目录 一、关于 Cosmos主要特点模型家族 二、使用示例1、推理2、后训练 许可证和联系方式 一、关于 Cosmos NVIDIA Cosmos是开发者第一的世界基础模型平台,旨在帮助物理AI开发者更好、更快地构建他们的物理AI系统。宇宙包含 预训练模型,可通过拥抱脸…...
图像分割中根据mask的ROI,去除mask和image中没有勾画ROI层数以外的图像
在分割任务中,一个患者有很多层图像,但是勾画的ROI仅有那么几层。我想去除ROI以外层数的那些没用的图像。这里以一个36张图像的nii格式数据为例 查看一下mask文件中有多少个非0图像 import nibabel as nib import numpy as np# 加载 .nii 文件 file_pat…...
【Java基础-42.3】Java 基本数据类型与字符串之间的转换:深入理解数据类型的转换方法
在 Java 开发中,基本数据类型与字符串之间的转换是非常常见的操作。无论是从用户输入中读取数据,还是将数据输出到日志或界面,都需要进行数据类型与字符串之间的转换。本文将深入探讨 Java 中基本数据类型与字符串之间的转换方法,…...
全栈开发:使用.NET Core WebAPI构建前后端分离的核心技巧(一)
目录 cors解决跨域 依赖注入使用 分层服务注册 缓存方法使用 内存缓存使用 缓存过期清理 缓存存在问题 分布式的缓存 cors解决跨域 前后端分离已经成为一种越来越流行的架构模式,由于跨域资源共享(cors)是浏览器的一种安全机制,它会阻止前端应用…...
springboot使用rabbitmq
使用springboot创建rabbitMQ的链接。 整个项目结构如下: 1.maven依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>3.4.1</version> </dependency>application.y…...
Linux——ext2文件系统(二)
Linux——ext2文件系统 ext2文件系统宏观认识一、磁盘分区与格式化二、块组(Block Group)结构三、文件系统特性 文件名与目录名与inode一、inode的作用原理二、文件与目录名与inode的关系 路径一,路径解析二,路径缓存三࿰…...
