算法基础——一致性
引入
最早研究一致性的场景既不是大数据领域,也不是分布式系统,而是多路处理器。
可以将多路处理器理解为单机计算机系统内部的分布式场景,它有多个执行单元,每一个执行单元都有自己的存储(缓存),一个执行单元修改了自己存储中的一个数据后,这个数据在其他执行单元里面的副本就面临数据一致的问题。
随着时代发展,互联网公司的快速发展,单机系统在计算和存储方面都开始面临瓶颈,分布式是一个必然的选择,但是这也进一步放大了数据一致性面临的问题。对于数据的一致性,最理想的模型当然是表现得和一份数据完全一样,修改没有延迟,即所有的数据修改后立即被同步。但在现实世界中,数据的传播是需要时间的,所以理想的一致性模型是不存在的。
不过从应用层的角度来看,我们并不需要理想的一致性模型,只需要一致性模型能满足业务场景的需求就足够了,比如在统计分析类的场景中,是能容忍一定的误差的,而评论之类的场景中,可能只要有因果关系的操作顺序一致就可以了。
同时由于一致性要求越高,实现的难度和性能消耗就越大,所以我们可以通过评估业务场景来降低数据一致性的要求,这样人们就定义了不同的一致性模型来满足不同的需求。这种思路其实和我们在深入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通过节点之间的消息交互和验证,在存在恶意节点(拜占庭节点)的情况下,仍然能够保证系统的一致性和正确性。算法通过视图切换、预准备、准备、提交等多个阶段来达成共识。
应用场景:对安全性要求极高的分布式系统,尤其是存在恶意攻击风险的环境。如区块链、金融交易系统等。
优点:能够容忍一定数量的拜占庭故障节点,保证系统的安全性和一致性,在联盟链等场景中有较好的应用。
缺点:通信复杂度高,性能开销大,随着节点数量增加,消息数量呈指数级增长,会影响系统的性能和扩展性。
总结
本文梳理了一致性问题来源和解决模型,以及经典常用的一致性算法,感兴趣的小伙伴可以深入了解不同算法的具体落地应用。后续在深入大数据相关技术技术框架时,遇到相关算法,我们再深入看看。
相关文章:

算法基础——一致性
引入 最早研究一致性的场景既不是大数据领域,也不是分布式系统,而是多路处理器。 可以将多路处理器理解为单机计算机系统内部的分布式场景,它有多个执行单元,每一个执行单元都有自己的存储(缓存),一个执行单元修改了…...

刷题记录 动态规划-6: 62. 不同路径
题目:62. 不同路径 难度:中等 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” &#x…...

docker直接运行arm下的docker
运行环境是树莓派A 处理器是 arm32v6 安装了docker,运行lamp 编译安装php的时候发现要按天来算,于是用电脑vm下的Ubuntu系统运行arm的docker 然后打包到a直接导入运行就可以了 第一种方法 sudo apt install qemu-user-static 导入直接运行就可以了…...

014-STM32单片机实现矩阵薄膜键盘设计
1.功能说明 本设计主要是利用STM32驱动矩阵薄膜键盘,当按下按键后OLED显示屏上会对应显示当前的按键键值,可以将此设计扩展做成电子秤、超市收银机、计算器等需要多个按键操作的单片机应用。 2.硬件接线 模块管脚STM32单片机管脚矩阵键盘行1PA0矩阵键盘…...

Sentinel 断路器在Spring Cloud使用
文章目录 Sentinel 介绍同类对比微服务雪崩问题问题原因问题解决方案请求限流线程隔离失败处理服务熔断解决雪崩问题的常见方案有哪些? Sentineldocker 安装账号/ 密码项目导入簇点链路请求限流线程隔离Fallback服务掉线时的处理流程 服务熔断 Sentinel 介绍 随着微…...

[内网安全] 内网渗透 - 学习手册
这是一篇专栏的目录文档,方便读者系统性的学习,笔者后续会持续更新文档内容。 如果没有特殊情况的话,大概是一天两篇的速度。(实验多或者节假日,可能会放缓) 笔者也是一边学习一边记录笔记,如果…...

算法总结-二分查找
文章目录 1.搜索插入位置1.答案2.思路 2.搜索二维矩阵1.答案2.思路 3.寻找峰值1.答案2.思路 4.搜索旋转排序数组1.答案2.思路 5.在排序数组中查找元素的第一个和最后一个位置1.答案2.思路 6.寻找旋转排序数组中的最小值1.答案2.思路 1.搜索插入位置 1.答案 package com.sunxi…...

基于python的Kimi AI 聊天应用
因为这几天deepseek有点状况,导致apikey一直生成不了,用kimi练练手。这是一个基于 Moonshot AI 的 Kimi 接口开发的聊天应用程序,使用 Python Tkinter 构建图形界面。 项目结构 项目由三个主要Python文件组成: 1. main_kimi.py…...

动手学深度学习-3.2 线性回归的从0开始
以下是代码的逐段解析及其实际作用: 1. 环境设置与库导入 %matplotlib inline import random import torch from d2l import torch as d2l作用: %matplotlib inline:在 Jupyter Notebook 中内嵌显示 matplotlib 图形。random:生成…...

Spring 面试题【每日20道】【其二】
1、Spring MVC 具体的工作原理? 中等 Spring MVC 是 Spring 框架的一部分,专门用于构建基于Java的Web应用程序。它采用模型-视图-控制器(MVC)架构模式,有助于分离应用程序的不同方面,如输入逻辑、业务逻辑…...

嵌入式八股文面试题(一)C语言部分
1. 变量/函数的声明和定义的区别? (1)变量 定义不仅告知编译器变量的类型和名字,还会分配内存空间。 int x 10; // 定义并初始化x int x; //同样是定义 声明只是告诉编译器变量的名字和类型,但并不为它分配内存空间…...

Vue06
目录 一、声明式导航-导航链接 1.需求 2.解决方案 3.通过router-link自带的两个样式进行高亮 二、声明式导航的两个类名 1.router-link-active 2.router-link-exact-active 三、声明式导航-自定义类名(了解) 1.问题 2.解决方案 3.代码演示 四…...

deepseek-r1模型本地win10部署
转载自大佬:高效快速教你deepseek如何进行本地部署并且可视化对话 deepseek 如果安装遇到这个问题 Error: Post “http://127.0.0.1:11434/api/show”: read tcp 127. 用管理员cmd打开 接着再去切换盘符d: cd 文件夹 重新下载模型:ollama run deepseek…...

自定义数据集 使用scikit-learn中SVM的包实现SVM分类
生成自定义数据集 生成一个简单的二维数据集,包含两类数据点,分别用不同的标签表示。 import numpy as np import matplotlib.pyplot as plt# 生成数据 np.random.seed(42) X np.r_[np.random.randn(100, 2) - [2, 2], np.random.randn(100, 2) [2, …...

pandas的melt方法使用
Pandas 的 melt 方法用于将宽格式(wide format)的 DataFrame 转换为长格式(long format)的 DataFrame。这种转换在数据处理和可视化中非常有用,尤其是在处理多列数据时。 宽格式 vs 长格式 宽格式(Wide F…...

一文讲解Spring中应用的设计模式
我们都知道Spring 框架中用了蛮多设计模式的: 工厂模式呢,就是用来创建对象的,把对象的创建和使用分开,这样代码更灵活。代理模式呢,是用一个代理对象来控制对真实对象的访问,可以在访问前后做一些处理。单…...

Linux的基本指令(下)
1.find指令 Linux下find命令在⽬录结构中搜索⽂件,并执⾏指定的操作。 Linux下find命令提供了相当多的查找条件,功能很强⼤。由于find具有强⼤的功能,所以它的选项也很多,其中⼤部分选项都值得我们花时间来了解⼀下。 即使系统中含…...

HAO的Graham学习笔记
前置知识:凸包 摘录oiwiki 在平面上能包含所有给定点的最小凸多边形叫做凸包。 其定义为:对于给定集合 X,所有包含 X 的凸集的交集 S 被称为 X 的 凸包。 说人话就是用一个橡皮筋包含住所有给定点的形态 如图: 正题:…...

Elasticsearch Queries
Elasticsearch Compound Queries Elasticsearch 的 Compound Queries 是一种强大的工具,用于组合多个查询子句,以实现更复杂的搜索逻辑。这些查询子句可以是叶查询(Leaf Queries)或复合查询(Compound Queries…...

利用matlab寻找矩阵中最大值及其位置
目录 一、问题描述1.1 max函数用法1.2 MATLAB中 : : :的作用1.3 ind2sub函数用法 二、实现方法2.1 方法一:max和find2.2 方法二:max和ind2sub2.3 方法对比 三、参考文献 一、问题描述 matlab中求最大值可使用函数max,对于一维向量࿰…...

SQL入门到精通 理论+实战 -- 在 MySQL 中学习SQL语言
目录 一、环境准备 1、MySQL 8.0 和 Navicat 下载安装 2、准备好的表和数据文件: 二、SQL语言简述 1、数据库基础概念 2、什么是SQL 3、SQL的分类 4、SQL通用语法 三、DDL(Data Definition Language):数据定义语言 1、操…...

【智力测试——二分、前缀和、乘法逆元、组合计数】
题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; const int mod 1e9 7; const int N 1e5 10; int r[N], c[N], f[2 * N]; int nr[N], nc[N], nn, nm; int cntr[N], cntc[N]; int n, m, t;void init(int n) {f[0] f[1] 1;for (int i …...

Spring Security(maven项目) 3.0.2.9版本 --- 改
前言: 通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往…...

并发编程中的常见问题
1 竞态条件 (Race Condition) 定义:竞态条件是指多个线程在访问共享资源时,由于执行顺序的不同导致结果不确定的情况。 示例: public class Counter {private int count = 0;public void increment() {count++;}public int getCount() {return count;} }在多线程环境下,…...

二维前缀和:高效求解矩阵区域和问题
在处理二维矩阵时,频繁计算某一子矩阵的和是一个常见的操作。传统的做法是直接遍历该子矩阵,时间复杂度较高。当矩阵非常大且有大量的查询时,直接计算将变得低效。为了提高效率,我们可以通过 二维前缀和 技巧在常数时间内解决这个…...

鸢尾花书《编程不难》02---学习书本里面的三个案例
文章目录 1.引言2.第一个例子---模拟硬币的投掷结果3.第二个例子---混合两个一元高斯分布的随机数4.第三个例子---线性回归的作图5.关于书中的问题的解决方案 1.引言 今天的这个文章主要是阅读学习鸢尾花书系列的第一本《编程不难》,今天主要是记录下书里面的两个例…...

MySQL(高级特性篇) 13 章——事务基础知识
一、数据库事务概述 事务是数据库区别于文件系统的重要特性之一 (1)存储引擎支持情况 SHOW ENGINES命令来查看当前MySQL支持的存储引擎都有哪些,以及这些存储引擎是否支持事务能看出在MySQL中,只有InnoDB是支持事务的 &#x…...

CSS Display属性完全指南
CSS Display属性完全指南 引言核心概念常用display值详解1. block(块级元素)2. inline(行内元素)3. inline-block(行内块级元素)4. flex(弹性布局)5. grid(网格布局&…...

【机器学习篇】K-Means 算法详解:从理论到实践的全面解析
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...

IntelliJ IDEA远程开发代理远程服务器端口(免费内网穿透)
IntelliJ IDEA远程开发代理远程服务器端口(免费内网穿透)(JetBrains家的其他IDE应该也支持) 之前看到宇宙第一IDE VS Code好像默认代理了远程的端口,但是一直没找到IDEA的同类功能,这次终于发现了 以Intell…...