【分布式】Viewstamped Replication Revisited
篇前感悟:
阅读分布式系统文章的意义其实并不在于你个人真正地去开发这样一个基于这种协议的系统,因为真正去开发一个高可用的分布式系统实在是太难了(对我来说…)更多的还是汲取其中的思想,包括设计思路,优化思路等等。 简单地举个例子,比如说这篇优化中的witness角色引入,也许也可以在其他系统中得到应用。 真正能在工程实践中使用到的并非是完整的一篇论文,而是其中的一个点、两个点。
建议阅读:
- 更多背景介绍: https://zhuanlan.zhihu.com/p/428147777
- 更多细节:https://zhuanlan.zhihu.com/p/66427412
一、假设
- 仅处理crash failure,不考虑拜占庭故障
- 针对异步网络
- 2f+1个节点可以容忍f个节点发生非拜占庭故障
二、协议架构

在这里,Replica也就是节点; VR Code负责处理VR协议,Service Code负责处理和执行命令 。
三、协议组成
1. normal operation
正常执行流程。
- client发送消息到primary
- primary收到后比较request-number和client-table中的信息,如果req-num < client table中记录的,则丢弃+ 发送response,因为req已经处理过了。否则继续。
- primary 的 op-number 增加,request 增加到log末尾,然后发送prepare消息给其他节点(backups,副本)
- backups按顺序处理prepare。 一个副本需要具备op-number前所有entry才能处理请求。如果缺失entry,说明状态落后,需要state transfer。
处理的时候,同primary,本地的op-number增加,request 增加到本地log中,更新client-table, 返回prepareOK给primary - primary收集了多数prepareOK消息时,就可以认为当前的operation可以commit了,这个operation就可以被顺序执行到,commit-number增加,通知client,更新执行结果到client-table
- 对于已经commit的消息,需要通知backups,这个通知消息并不是单独发,而是包含在下一次prepare消息中(这样节约了一次发送开销)。如果长期没有client请求,也就是长期无需发送prepare消息的话,那就再单独发送一次commit消息给backups
- backups接收到发来的commit消息,再执行operation,更新result到client-table
注: 这里的op-number 类比于是Raft中的log index, commit-number类比于是commit index。 如果一切正常,长时间来看commit-number == op-number
如果step5,primary已经commit,但此时primary宕机了,那如何将commit-number通知到backup呢?那就涉及到part 3-recovery了。而其他节点也会发现primary不在了,那么此时就要做view change
2. view change
在VR协议中的view 可以理解为Raft的term。view change就是切主;view number可以理解为Raft的任期号。
-
发生时间:replica发现自己超时未收到primary的消息,那么递增自己的view-number or 收到了view change的更大的view-number(说明存在其他replica已经开始选主),那么view-number更新为收到的新number
-
一个replica收到f个startViewChange消息时候,就发送消息doViewChange给新的primary
-
新的primary收到f+1条消息,更新自己的view-number,并选择view-number最大的消息log作为new log,如果view-number相同,则选择op-number最大的;设置commit-number为所有消息中的最大值,更新status为normal,发送给其他副本view change结束的消息;其他副本更新相关信息
(对比Raft, Raft只能是主给从发log,而这里可以从节点给新主节点发log) -
new primary开始负责接收client消息
3. recovery
宕机后的节点重新加入集群,需要重新请求所有日志。
区别于state transfer: 节点并没有宕机,但是日志落后,此时需要state transfer。
- 发送recovery给所有replica,携带唯一序号
- 处于normal状态的replica响应, 只有primary给请求者回复log内容
- 收到f+1个响应(包括primary),则更新本地log,更新完后切换状态到normal
四、优化
-
effective recovery
就是需要节点每隔一段时间持久化一下当前state,在recovery的时候直接从磁盘中拿出之前该节点的state就行,而不用传输全部的log (和Raft的 snapshot还是有点区别的,snapshot是指传输的时候把log打包,但目的是一样的,就是让恢复的时候无需全量传输log) -
view change
doViewChange消息中携带1-2个最新的log,而不是全部log。log用于更新新primary状态,由于新primary一般比较新,所以带少量即可。 -
witness
2f+1节点集群中只有f+1个节点需要active(active状态的节点需要存储状态和执行operation),其他f个为witness(不需要存state和执行op)。 active replica出现故障,witness才参与进来。大多数正常时间,witness节点把资源拿去干别的。 -
batching
客户端发来的请求可以收集一下,一起跑。节约通信开销,但是一次处理的时间变长(延迟增加) -
fast reads
仅primary处理读请求,而不需要得到其他节点的response (prepareOK)
需要额外实现lease机制,保证读请求的primary在有效期内,防止网络分区带来的脑裂问题。
相关文章:
【分布式】Viewstamped Replication Revisited
篇前感悟: 阅读分布式系统文章的意义其实并不在于你个人真正地去开发这样一个基于这种协议的系统,因为真正去开发一个高可用的分布式系统实在是太难了(对我来说…)更多的还是汲取其中的思想,包括设计思路,优…...
微服务07-分布式缓存
前提: 单机的Redis存在四大问题: 解决办法:基于Redis集群解决单机Redis存在的问题 1、Redis持久化 Redis 具有持久化功能,其会按照设置以 快照 或 操作日志 的形式将数据持久化到磁盘。 Redis有两种持久化方案: RDB持久化AOF持久化注意: RDB 是默认持久化方式,但 Red…...
QGraphicsView放大时,paint有时不被调用,导致图像绘制不出来(2)
此前(1)解决的是在QGraphicsItem::boundingRect不变的情况下造成不绘制。这次解决的是QGraphicsItem::boundingRect随时都发生变化导致的不绘制。 这问题是我在不继承QGraphicsLineItem(调用setLine),而是继承QGraphic…...
深入理解设计模式-创建型之建造者模式(与工厂区别)
什么是建造者设计模式?和工厂设计模式有什么区别 建造者设计模式(Builder Design Pattern)和工厂设计模式(Factory Design Pattern)都是面向对象设计中的创建型模式,但它们解决的问题和应用场景有所不同。…...
Centos7多台服务器免密登录
准备四台服务器: docker0 docker1 docker2 docker3 在docker0服务器上生成公钥和私钥 [rootwww ~]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory /root/.ssh. Enter passp…...
C语言实现哈希搜索算法
一、哈希搜索算法原理 哈希搜索,也叫散列查找,是一种通过哈希表(散列表)实现快速查找目标元素的算法。哈希搜索算法通常适用于需要快速查找一组数据中是否存在某个元素的场景,其时间复杂度最高为 O(1),而平…...
MySQL卸载并重装指定版本
MySQL卸载并重装制定版本 学习新的项目,发现之前的Navicat已经失去了与现有MySQL的链接,而且版本也不适合,为了少走弯路,准备直接重装相应版本的MySQL 卸载现有MySQL 停止windows的MySQL服务,【windowsR】打开运行框…...
文件IO编程 1 2
头文件包含路径 linux 操作系统分为两大空间:用户空间和内核空间 这样划分,是为了保护内核的核心组件,不被轻易访问和修改 系统调用:安全的访问内核空间 其核心是:函数API(API:用户编程接口&…...
Java后端框架模块整合
提示:使用Java后端开发框架能够提高开发效率、代码质量,提升可扩展性,降低开发成本和易于维护。 文章目录 前言MyBatis 框架知识Spring 框架知识SpringMVC 框架知识SpringBoot 框架知识 前言 提示:这里可以添加本文要记录的大概内…...
17 synchronized关键字使用 synchronized方法、synchronized块
synchronized方法、synchronized块 线程的同步不安全的线程示例1:示例2示例3 synchronized方法、synchronized块 线程的同步 并发:同一个对象被多个线程同时操作。 解决方案:让多个线程排队操作对象。 使用队列和锁解决多线程的并发问题。 同…...
django-基本环境配置
文章目录 django 环境安装1. 安装环境1.1 安装 Python (配置虚拟环境)1.1.1 步骤 1.2 Conda配置环境参考 django 环境安装 1. 安装环境 1.1 安装 Python (配置虚拟环境) 由于国外源速度慢,可以pip添加清华源 pip config set global.index-url https://pypi.tuna.…...
Springboot 实践(4)swagger-ui 测试controller
前文项目操作,完成了项目的创建、数据源的配置以及数据库DAO程序的生成与配置。此文讲解利用swagger-ui界面,测试生成的数据库DAO程序。目前,项目swagger-ui界面如下: 以”用户管理”为例,简单讲述swagger-ui测试数据库…...
PHP实践:分布式场景下的Session共享解决方案实现
🏆作者简介,黑夜开发者,全栈领域新星创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责…...
07 - 查看、创建、切换和删除分支
查看所有文章链接:(更新中)GIT常用场景- 目录 文章目录 1. 查看分支2. 创建和切换分支3. 删除分支 1. 查看分支 git branch -va2. 创建和切换分支 第一种: 创建分支: git branch new_branch切换分支: …...
【SpringBoot】89、SpringBoot中使用@Transactional进行事务管理
事务是一组组合成逻辑工作单元的操作,虽然系统中可能会出错,但事务将控制和维护事务中每个操作的一致性和完整性。 1、SpringBoot 引用说明 新建的 Spring Boot 项目中,一般都会引用 spring-boot-starter 或者 spring-boot-starter-web,而这两个起步依赖中都已经包含了对…...
两天入门Linux、搭建Spring环境 第一天
一、Linux简介 1.什么是Linux 一个操作系统,未来公司里面会用到、接触的新操作系统。 2.为什么学Linux (1)个人职务需要,肯定会接触到Linux (2)职业发展,以后的发展肯定需要掌握Linux的许多使用方法 3.学哪些内容 (1)Linux基本介绍 (2)…...
OpenCV实例(九)基于深度学习的运动目标检测(一)YOLO运动目标检测算法
基于深度学习的运动目标检测(一) 1.YOLO算法检测流程2.YOLO算法网络架构3.网络训练模型3.1 训练策略3.2 代价函数的设定 2012年,随着深度学习技术的不断突破,开始兴起基于深度学习的目标检测算法的研究浪潮。 2014年,…...
CI/CD流水线实战
不知道为什么,现在什么技术都想学,因为我觉得我遇到了技术的壁垒,大的项目接触不到,做的项目一个字辣*。所以,整个人心浮气躁,我已经得通过每天的骑行和长跑缓解这种浮躁了。一个周末,我再次宅在…...
详解配置交换机多生成树MSTP+VRRP 的典型组网
详解配置交换机多生成树MSTPVRRP 的典型组网 组网: 1. 这是一个由三台交换机组成的倒三角型二层交换网络;网络中有4个VLAN:10、20、30、40;接口编号如图所示;SW3为接入层交换机,SW1、SW2为汇聚层交换机&am…...
二.net core 自动化发布到docker (Jenkins安装之后向导)
目录 参考资料:https://www.jenkins.io/doc/book/installing/docker/#setup-wizard Post-installation setup wizard.(安装后安装向导) 基于上一篇文章安装,在安装并运行Jenkins(不包括使用Jenkins Opera…...
实战演练:基于快马平台与AI模型打造一个智能电商导购Agent
最近在尝试将AI技术落地到实际业务场景中,发现电商导购是个非常实用的切入点。今天就来分享下如何用InsCode(快马)平台快速搭建一个智能电商导购Agent的全过程。 项目架构设计 这个导购Agent采用前后端分离架构,主要分为三个模块: 前端交互…...
从Java全栈工程师视角看Web开发的实战与思考
从Java全栈工程师视角看Web开发的实战与思考 面试现场:一次真实的技术对话 面试官:你好,我是今天的面试官,很高兴见到你。请先简单介绍一下自己。 应聘者:你好,我叫李明,28岁,本科学…...
多模态场景:头巾误判为厨师帽 — 问题分析与调优指南
多模态场景:头巾误判为厨师帽 — 问题分析与调优指南适用对象:使用 Qwen-VL 等多模态大模型做「厨师帽 / 头饰」相关识别时的面试问答、方案设计与落地调优参考。1. 问题本质:为什么会把头巾当成厨师帽 这通常不是「模型坏了」,而…...
OpenClaw个性化设置:Qwen3.5-9B模型参数调优实战
OpenClaw个性化设置:Qwen3.5-9B模型参数调优实战 1. 为什么需要调整模型参数? 上周我在用OpenClaw自动处理一批技术文档时,遇到了一个奇怪的现象:同样的任务指令,有时候AI能完美执行,有时候却会输出一堆无…...
深入解析Camera-IMU联合标定:从理论到实践
1. 为什么需要Camera-IMU联合标定? 在机器人定位和三维重建领域,相机和IMU(惯性测量单元)是最常用的传感器组合。相机能提供丰富的环境特征信息,但在快速运动或弱光环境下容易失效;IMU可以稳定输出运动数据…...
如何写 Skill
核心概念 Skill 是一个自包含的模块,用来给 Claude/Cascade 注入特定领域的知识、工作流和工具。本质上就是一个"新手入职指南",让通用 AI 变成某个领域的专家。 目录结构 skill-name/ ├── SKILL.md # 必须,核心文件 └…...
内网渗透全流程拆解|从入门到实战,小白也能看懂的步骤
内网渗透不是“盲目尝试”,而是遵循固定流程的系统化操作,核心流程可概括为:信息收集→漏洞利用→权限提升→横向移动→权限维持→痕迹清理,每个环节环环相扣,缺一不可。本文将结合小白易理解的实战场景,详…...
若依管理系统实战:基于Vuex的用户角色权限与动态菜单路由解析
1. 若依管理系统权限控制核心逻辑解析 若依管理系统作为一款基于SpringBoot和Vue的企业级中后台解决方案,其权限控制体系设计得非常精巧。我在实际项目中使用这套方案时,发现它通过前后端协同工作,实现了细粒度的权限管理。整个流程可以概括为…...
Adafruit NeoMatrix 原理与坐标映射详解
1. 项目概述 Adafruit NeoMatrix 是一款专为 NeoPixel 矩阵与网格显示设备设计的嵌入式图形库,其核心定位是作为 Adafruit_GFX 图形抽象层的硬件适配实现。它并非独立渲染引擎,而是通过继承并扩展 Adafruit_GFX 的绘图接口(如 drawPixel() …...
突破3D打印障碍:SketchUp STL插件的技术革新与实践指南
突破3D打印障碍:SketchUp STL插件的技术革新与实践指南 【免费下载链接】sketchup-stl A SketchUp Ruby Extension that adds STL (STereoLithography) file format import and export. 项目地址: https://gitcode.com/gh_mirrors/sk/sketchup-stl 当一位产品…...
