disgare 的博客
首页
博客
分类
标签
首页
博客
分类
标签
  • 网络

    • 计算机网络学习笔记
    • 网络安全相关
    • 域名和子网掩码
    • CORS 跨域资源共享
    • DNS、HTTP 与 HTTPS
    • Server-Sent Events (SSE)
    • WebSocket 长连接
  • 计算机基础

    • 操作系统 IO 相关知识
    • 操作系统学习笔记
    • 程序的机器级表示
    • 音频文件基础
    • 正则表达式相关概念
    • ffmpeg 的安装以及实现音频切分功能
    • Hex 和 Base64 编码
    • XML 的使用
  • 数据结构与算法

    • 动态规划算法学习笔记
    • 基于比较的排序算法的最坏情况下的最优下界为什么是O(nlogn)
    • 集合与数据结构学习笔记
    • 面试常见算法总结
    • 算法导论第二部分排序学习笔记
    • 算法导论第一部分学习笔记
  • Java

    • 对象之间的映射与转换
    • 反射学习笔记
    • 泛型相关概念
    • 关于 boolean 类型的坑
    • 如何使用 lambda 表达式实现排序
    • CompletableFuture 相关用法
    • CompletableFuture 源码浅要阅读
    • FutureTask 源码阅读
    • Guava 常用 API
    • Guava 源码阅读:Multimap 相关
    • Jackson 的各种使用
    • Java 的 Excel 相关操作
    • java 的常见性能问题分析以及出现场景
    • java 基础知识
    • JAVA 枚举的基础和原理
    • Java 图片文件上传下载处理
    • Java 序列化
    • Java 异常
    • Java 语法糖
    • Java 中关于字符串处理的常用方法
    • Java 中强、软、弱、虚引用
    • JAVA 注解小结
    • Java Http 访问框架
    • Java Stream 的使用
    • Java8 新特性
    • netty 学习笔记
    • Scanner 的各种用法
    • Servlet 学习笔记
    • String、StringBuffer、StringBuilder 学习笔记
  • JVM

    • 虚拟机执行子系统
    • JVM 自动内存管理
    • Linux 中 JVM 常用工具以及常见问题解决思路
  • Linux

    • crontab 表达式
    • Linux 常见命令
    • Linux 文件系统
  • 中间件

    • 关于定时任务原理
    • 详解 kafka
    • ES 搜索引擎
    • flink 提交流程
    • Grape-RAG
    • Hadoop 基础原理
  • 多线程

    • 多线程基础学习笔记
    • 简单了解并发集合
    • 如何手写单例
    • 深入理解 java 多线程安全
    • 生产者消费者问题
    • 线程池作用、用法以及原理
    • AQS 组件
    • ThreadLocal 原理以及使用
  • 非关系型数据库

    • Redis 集群
    • Redis 数据结构、对象与数据库
    • Redis 学习笔记
  • 关系型数据库

    • B+ 树的插入、删除和数据页分裂机制
    • MySQL 的 binglog、redolog、undolog
    • MySQL 的记录存储结构、存储引擎与 Buffer Pool
    • MySQL 基本的特性
    • MySQL 开发规范
    • MySQL 事务与锁与 MVCC
    • MySQL 数据类型、字符集相关内容
    • MySQL 索引与索引优化
    • PostgreSQL 更新数据时 HOT优化
    • PostgreSQL 相关用法
  • Python

    • Python 基础语法
    • Python 学习
  • Spring 项目

    • Lombok 的常用注解
    • maven 小结
    • MyBatis 框架的使用
    • MyBatis 重要知识点总结
    • MybatisPlus 的使用
    • Spring 框架基础使用
    • Spring 事务相关
    • Spring IOC 的原理及源码
    • Spring AOP 的使用和原理
    • SpringBoot 的原理
    • SpringBoot 基础使用
    • SpringWeb 重要知识点
  • 分布式

    • 初步了解 docker
    • 从 ACID 到 BASE 事务处理的实现
    • 访问远程服务
    • 分布式 id
    • 分布式缓存相关问题
    • 分布式集群理论和分布式事务协议
    • 分布式架构的观测
    • 分布式一致性算法
      • Paxos 算法
        • 算法过程
      • raft 算法
      • ZAB 协议
        • 崩溃恢复模式
        • 崩溃恢复需要满足的要求
        • 消息广播模式
    • 负载均衡 Load Balancing
    • 关于分布式系统 RPC 中高可用功能的实现
    • 集群间数据同步的目的
    • 三高问题下的系统优化
    • 数据库分库分表
    • 详解 Spring Cloud
    • Dubbo 基础概念
    • Gossip 协议
    • nginx 学习笔记
    • Protobuf 通信协议
    • Zookeeper 基础学习
  • 架构设计

    • 参数校验与异常处理
    • 抽象方法与设计模式
    • 代码整洁之道
    • 权限系统设计
    • 用低内存处理大量数据
    • 设计模式——策略模式
    • 设计模式——过滤器模式在 Spring 中的实践
    • 状态模式
    • 统一结果返回
    • 为什么要打日志?怎么打日志?打什么日志?
    • 运维监控常见指标含义
    • 资深研发进阶
    • DDD 架构学习笔记
    • Java 常用的规则引擎
    • MVC 架构学习笔记
  • AI

    • 如何编写 Prompt
    • Agent 工程架构
    • LLM 相关内容
    • NLP 相关知识
    • vibe coding 最佳实践
    • windows 下 ollama 迁移到 D 盘
  • 开发工具

    • 如何画时序图、流程图、状态流转图
    • excel 关于 =vlookup 的用法
    • git 的学习以及使用
    • IDEA 插件推荐
    • IDEA 常用快捷键以及调试
    • Shell 脚本
    • swagger 的使用
  • 前端

    • 简单了解前端页面开发
    • 伪静态是什么
    • GitHub Pages 部署教程
    • Vercel 部署教程
    • vue-admin-template 简单使用
    • VuePress 博客搭建指南
  • 项目

    • 面试刷题网——技术方案
    • 影视资源聚合站——技术方案
  • 问题记录

    • 定时任务单线程消费 redis 中数据导致消费能力不足
    • 提供可传递的易受攻击的依赖项
    • Liteflow 在 SpringBoot 启动时无法注入组件问题 couldn‘t find chain with the id[THEN(NodeComponent)]
  • 金融

    • 股票分析——关于电力
    • 股票技术面——量价关系
    • 股票技术面——盘口
    • 股票技术面——基础
    • 基础的金融知识
    • 基金与股票
    • 韭菜的自我总结
    • 聊聊价值投资
  • 其他

    • 程序员职场工作需要注意什么
    • 创业全链路SOP:从灵光一现到系统化增长的实战指南
    • 观罗翔讲刑法随笔
    • 价格和价值
    • 立直麻将牌效益理论
    • 梅花易数学习笔记
    • 压力管理
2022-09-03
分布式
目录

分布式一致性算法

分布式一致性通常指的是系统中的所有节点对某个状态或值达成一致的过程。它涵盖了更广泛的概念,包括数据复制、状态同步、故障恢复等,他们是为了保证值一致性的,特点是不依赖中心化协调者,通过多数派投票实现容错

分布式事务协议是指 2PC,3PC 这些,为了让所有节点要么全部提交,要么全部回滚,创造出来的。他们也是满足 CAP 思想的算法,也可以称作刚性事务。他们是为了处理跨节点事务原子性的,特点是必须存在协调者集中控制流程

# Paxos 算法

Paxos 算法是基于消息传递且具有高度容错特性的分布式一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一,其解决的问题就是在分布式系统中如何就某个值(决议)达成一致

paxos 它和 2PC、3PC 的区别是它实现的是最终一致性,即算法执行后,允许部分节点没有更新值的状态存在,以此它更适合去处理一些业务相关的数据,而 2PC 则偏向处理集群管理相关的功能

# 算法过程

简单来说就是将集群分为提案者、决策者和记录者,集群一起维护了一个单调递增的方案 ID,通过半数投票的方式,来界定方案中的日志是否需要记录。以下是具体算法流程

准备阶段:每个提案者在提出提案时都会首先获取到一个具有全局唯一性的、递增的提案编号 N,然后将该编号赋予其要提出的提案,在第一阶段是只将提案编号发送给所有的表决者

表决者在收到某提案后,会将该提案编号 N 记录在本地,每个表决者仅会通过编号大于自己本地增大编号的提案,在批准提案时表决者会将以前接受过的最大编号的提案作为响应反馈给 Proposer

执行阶段:如果提案者收到了超过半数的批准,那么此时提案者会给所有的参与者发送真正的提案,这个时候提案者会发送提案的内容和提案编号。如果从表决者处收到了比自己更新的提案,此时会发送更新的提案

表决者收到提案请求后会再次比较本身已经批准过的最大提案编号和该提案编号,如果该提案编号大于等于已经批准过的最大提案编号,那么就执行该提案(此时执行提案内容但不提交),随后将情况返回给提案者,如果不满足则不回应或者返回 NO

通知阶段:当提案者收到超过半数的 accept,那么它这个时候会向所有的参与者发送提案的提交请求让它们强制执行该提案;提案者如果没有收到超过半数的 accept,那么它将会将递增该提案的编号,然后重新进入准备阶段

image-2026-01-31-21-05-30.png

# raft 算法

redis 的哨兵选举机制,使用了 raft 算法,其思想借鉴了 paxos,Raft 本来是一个用户管理日志一致性的协议。在大多数哨兵认定主机客观下线之后,就需要进行性的哨兵选举了

大致按照如下顺序:

  • 每个做主观下线的 sentinel 节点向其他 sentinel 节点发送命令,要求将自己设置为领导者,并且投自己一票。Follower 会自增自己的 term 号并且转换状态为 Candidate,然后将这个投出去
  • 接收到的 sentinel 可以同意或者拒绝
  • 如果该 sentinel 节点发现自己的票数已经超过半数并且超过了 quorum,将自己为领导者的消息同步集群中所有机器
  • 如果此过程选举出了多个领导者,那么将等待一段时重新进行选举,如果集群中只有两个哨兵,那么选举的流程将非常耗时。选出 Leader 后 Leader 会从从机中选举出合适的从机进行故障转移

这也是著名的半数选举机制。raft 他其实重点侧重于在一群机器中选择出一个老大,而且他最初的目的是管理日志一致性,即这个老大原本应该会受到请求,并且把请求作为日志条目加入到它的日志中,然后并行的向其他服务器发起请求以复制日志条目。当这条日志被复制到大多数服务器上,Leader 将这条日志应用到它的状态机并向客户端返回执行结果。redis 只借鉴了它前半部分,舍弃了后半部分

关于 raft 的最简单的总结:

  • 1,主节点客观下线后,从节点进行投票
  • 2,从节点会维护一个递增的提案 ID,如果本轮提案失败,ID 加1
  • 3,接受到提案的节点,每轮提案只能投一次票(一般是投给第一次收到本轮提案的机器),并且只会投票给比自己所记录的提案 ID(节点投票后会记录提案 ID)更大的候选人。这么做是为了选举安全性,防止有一些网络延迟的机器成为 leader
  • 4,收到超过半数同意票的机器成为 leader,并且发送终止投票命令 image-2026-01-31-21-05-45.png 看 raft 效果:https://raft.github.io/

# ZAB 协议

ZooKeeper 在解决分布式数据一致性问题自己写了一个协议叫 ZAB,该协议可以根据 ZK 的特殊情况更好的支持崩溃恢复功能。ZAB 和 redis 中的 raft 很像

# 崩溃恢复模式

当新建一个集群或者 Leader 挂掉之后会进入该模式,流程如下:

开始时我们按一定顺序启动集群中的机器,被启动的机器会首先投票给自己,投票内容为服务器的 myid 和 ZXID(服务器保存的最大提案 id),然后将消息广播出去,所有机器在收到投票信息后会将投票信息与自己的作比较。首先它会比较 ZXID,ZXID 大的优先为 Leader,如果相同则比较 myid,myid 大的优先作为 Leader

执行以上过程直到某台机器的票数超过半数,该机器成为 Leader

# 崩溃恢复需要满足的要求

Zab 协议崩溃恢复要求满足以下两个要求:

  • 1,确保已经被 Leader 提交的提案必须最终被所有的 Follower 服务器提交。为了满足这一点我们需要重试
  • 2,确保丢弃已经被 Leader 提出的但是没有被提交的提案

# 消息广播模式

当集群中存在 Leader 时,自动进入消息广播模式,流程如下:

客户端发起一个写操作请求,从机收到请求后会将该请求发给主机

Leader 服务器将求转化为事务提案,同时为每个提案分配一个全局的 ID,Leader 服务器为每个 Followe 服务器分配一个单独的队列,然后将需要广播的提案依次放到队列中,并且根据 FIFO 策略进行消息发送

Follower 接收到提案后,会首先将其以事务日志的方式写入本地磁盘中,写入成功后 Leader 反馈一个响应消息

Leader 接收到超过半数以上 Follower 的成功响应消息后,即认为消息发送成功,发送提交消息,自身也会完成事务提交

Leader 服务器与每一个 Follower 服务器之间都维护了一个单独的 FIFO 消息队列进行收发消息,使用队列消息可以保证数据传输的顺序性。请求处理的顺序不同就会导致数据的不同,从而产生数据不一致问题

#分布式
最后更新: 2/25/2026, 4:06:06 AM
分布式架构的观测
负载均衡 Load Balancing

← 分布式架构的观测 负载均衡 Load Balancing→

最近更新
01
vibe coding 最佳实践
02-24
02
立直麻将牌效益理论
02-23
03
伪静态是什么
02-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式