【主流分布式算法总结】

文章目录

  • 分布式常见的问题
  • 常见的分布式算法
    • Raft算法
      • 概念
      • Raft的实现
    • ZAB算法
    • Paxos算法

分布式常见的问题

分布式场景下困扰我们的3个核心问题(CAP):一致性、可用性、分区容错性。
1、一致性(Consistency):无论服务如何拆分,所有实例节点同一时间看到是相同的数据
2、可用性(Availability):不管是否成功,确保每一个请求都能接收到响应
3、分区容错性(Partition Tolerance):系统任意分区后,在网络故障时,仍能操作
在这里插入图片描述
而我们的业务中,一般一致性、可用性、分区容错性,三个满足两个,一般算法就是以CA和AP两个选择性,进行选择。

常见的分布式算法

Raft算法

概念

RAFT(Replicated State Machine Approach)算法是一种一致性分布式复制协议,用于在分布式系统中维护一组服务节点的一致状态。它是一种领导者选举算法,适用于解决分布式系统中的数据复制和一致性问题。
1.领导者选举:RAFT将系统中的节点分为三种角色:领导者(leader)、跟随者(follower)和候选者(candidate)。在任何给定的时刻,系统中都只有一个领导者。节点之间通过选举机制选出领导者,领导者负责处理客户端请求,并在系统中推动状态变更。
跟随者(Follower)
Fllower是所有节点的初始状态,内部都会有一个随机超时时间。这个超时时间,规定了在倒计时结束后仍然收不到Leader的心跳,Follower就会转变为Candidate。
候选者(candidate)
Follower在转变为Candidate后,超时时间重置,倒计时结束时就会向其他节点提名自己的实,拉取选票。
如果能获得半数以上(1/2以上,包含自己投给自己的)的选票,则当选为Leader,这个过程就叫做Leader选举。
所以节点最好是单数,避免极端情况下出现一个集群选举出两个Leader的脑裂问题。
领导者(leader)
Raft集群通过Leader与客户端进行交互,Leader不断处理写请求与发送心跳给Follower,Follower在收到Leader的心跳后,其超时时间会重置,即重新开始倒计时。
正常工作期间只有 Leader 和 Follower,且Leader至多只能有一个。
2.任期(Term):系统中的时间被分为一个个任期。每个任期都有一个唯一的标识符,领导者选举是基于这个任期进行的。当一个候选者成为领导者时,它会增加当前任期的编号,并在该任期内保持领导者身份。
3.日志(Log):RAFT将系统状态的变化表示为一系列日志条目。每个日志条目包含一个命令和任期号。这些日志条目按顺序附加到每个节点的日志中,并通过领导者复制到其他节点。
4.选举过程:当没有领导者时,节点会进入选举过程。在选举过程中,节点变为候选者状态,并向其他节点发送选举请求。候选者获得多数票后成为领导者。为了避免竞争和分裂投票,选举中使用随机化的超时机制。
5.日志复制:领导者负责将新的日志条目复制到其他节点。一旦大多数节点确认了日志条目,领导者就可以提交日志,并通知其他节点将其应用到状态机中。
6.安全性和一致性:RAFT确保在系统中只有一个领导者,并且所有节点都按相同的顺序应用相同的日志条目,从而确保了系统的一致性和安全性。

Raft的实现

public class Node {
    private int nodeId;
    private RaftNode raftNode;

    public Node(int nodeId, RaftNode raftNode) {
        this.nodeId = nodeId;
        this.raftNode = raftNode;
    }

    public int getNodeId() {
        return nodeId;
    }

    public RaftNode getRaftNode() {
        return raftNode;
    }
}

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class RaftNode implements Runnable {
    private int nodeId;
    private List<Node> cluster;
    private String state;
    private int currentTerm;
    private Integer votedFor;
    private List<String> log;
    private int commitIndex;
    private int lastApplied;
    private Map<Integer, Integer> nextIndex;
    private Map<Integer, Integer> matchIndex;
    private Integer leaderId;
    private final Lock lock;

    public RaftNode(int nodeId, List<Node> cluster) {
        this.nodeId = nodeId;
        this.cluster = cluster;
        this.state = "Follower";
        this.currentTerm = 0;
        this.votedFor = null;
        this.log = new ArrayList<>();
        this.commitIndex = 0;
        this.lastApplied = 0;
        this.nextIndex = new ConcurrentHashMap<>();
        this.matchIndex = new ConcurrentHashMap<>();
        this.leaderId = null;
        this.lock = new ReentrantLock();
    }

    public void start() {
        new Thread(this).start();
    }

    @Override
    public void run() {
        while (true) {
            switch (state) {
                case "Follower":
                    runFollower();
                    break;
                case "Candidate":
                    runCandidate();
                    break;
                case "Leader":
                    runLeader();
                    break;
            }
        }
    }

    private void runFollower() {
        long timeout = (long) (150 + Math.random() * 150);
        long lastHeartbeat = System.currentTimeMillis();
        while ("Follower".equals(state)) {
            if (System.currentTimeMillis() - lastHeartbeat >= timeout) {
                state = "Candidate";
                return;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void runCandidate() {
        currentTerm++;
        votedFor = nodeId;
        int votesReceived = 1;
        for (Node peer : cluster) {
            if (peer.getNodeId() != nodeId && sendRequestVote(peer.getRaftNode())) {
                votesReceived++;
            }
        }

        if (votesReceived > cluster.size() / 2) {
            state = "Leader";
            leaderId = nodeId;
            for (Node peer : cluster) {
                if (peer.getNodeId() != nodeId) {
                    nextIndex.put(peer.getNodeId(), log.size());
                    matchIndex.put(peer.getNodeId(), 0);
                }
            }
        } else {
            state = "Follower";
        }
    }

    private void runLeader() {
        while ("Leader".equals(state)) {
            sendHeartbeats();
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private boolean sendRequestVote(RaftNode peer) {
        peer.lock.lock();
        try {
            if (peer.currentTerm <= currentTerm && (peer.votedFor == null || peer.votedFor == nodeId)) {
                peer.votedFor = nodeId;
                return true;
            }
        } finally {
            peer.lock.unlock();
        }
        return false;
    }

    private void sendHeartbeats() {
        for (Node peer : cluster) {
            if (peer.getNodeId() != nodeId) {
                sendAppendEntries(peer.getRaftNode());
            }
        }
    }

    private void sendAppendEntries(RaftNode peer) {
        peer.lock.lock();
        try {
            if (peer.currentTerm > currentTerm) {
                state = "Follower";
            }
        } finally {
            peer.lock.unlock();
        }
    }
}

import java.util.*;

public class RaftCluster {
    public static void main(String[] args) {
        List<Node> cluster = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            RaftNode raftNode = new RaftNode(i, cluster);
            Node node = new Node(i, raftNode);
            cluster.add(node);
            raftNode.start();
        }
    }
}

ZAB算法

ZAB(ZooKeeper Atomic Broadcast)算法是分布式系统中用来实现一致性的重要协议。它是Apache ZooKeeper分布式协调服务的核心组件,确保集群中的所有节点在数据上的一致性。以下是对ZAB算法的详细解释。

  1. 目标
    ZAB的主要目标:
    顺序一致性:确保所有事务在所有ZooKeeper服务器上以相同的顺序被应用。
    原子广播:确保每个事务被可靠地传递到集群中的所有节点。
    容错性:在部分节点故障的情况下,仍能保证系统的正确性和可用性。
  2. 工作模式
    ZAB算法有两种主要的工作模式:
    广播模式(Broadcast mode):用于正常操作期间处理客户端请求。
    恢复模式(Recovery mode):用于集群启动或领导者故障后,选举新领导者并同步状态。
  3. 广播模式
    在广播模式下,ZAB的工作流程如下:
    领导者选举:集群启动或领导者故障后,会进行领导者选举。新领导者负责处理客户端请求并广播事务。
    事务处理:
    客户端请求被发送到领导者。
    领导者生成提案(Proposal),将提案广播给所有追随者(Follower)。
    追随者接收提案并将其写入事务日志,然后发送确认(ACK)给领导者。
    当领导者收到大多数追随者的确认后,认为提案已提交(Commit),并将提交信息广播给所有追随者。
    每个节点应用提交的事务到其状态机。
  4. 恢复模式
    在恢复模式下,ZAB的工作流程如下:
    数据同步:确保新领导者和追随者之间的数据一致性。追随者将与领导者进行数据同步,获取最新的事务日志。
    领导者选举:如果没有现任领导者,集群会通过投票机制选举出新的领导者。
    状态同步:新领导者与追随者同步状态,以便进入广播模式继续处理客户端请求。
  5. 容错处理
    ZAB通过以下机制实现容错:
    复制日志:每个事务都被写入多个节点的事务日志,确保在部分节点故障时仍然可以恢复数据。
    多数派确认:事务在大多数节点确认后才被提交,保证系统在多数节点可用的情况下仍然一致。
    持久化存储:事务日志被持久化存储在磁盘上,防止数据因节点重启或崩溃而丢失。

Paxos算法

Paxos是一种广泛使用的分布式一致性算法,由计算机科学家Leslie Lamport提出。它用于在分布式系统中达成一致性,即使某些节点发生故障也能保证系统的一致性。Paxos算法的核心思想是在分布式环境中,通过一系列的消息传递和投票机制,确保多个节点对某个值达成共识。
Paxos算法的基本概念
Paxos算法涉及三个主要角色:
提议者(Proposer):提出提案并争取达成共识。
接受者(Acceptor):对提议者提出的提案进行投票。
学习者(Learner):一旦共识达成,学习最终达成的值。
Paxos算法的基本过程
Paxos算法通常分为两个主要阶段:准备阶段(Prepare Phase)和接受阶段(Accept Phase)。

  1. 准备阶段(Prepare Phase)
    提议者选择一个提案编号n并向大多数接受者发送Prepare(n)请求。
    接受者收到Prepare(n)请求后,如果n大于它已经响应过的所有Prepare请求的编号,则接受该请求,并承诺不再接受编号小于n的提案。同时,接受者会向提议者回复它已经接受的提案中编号最大的提案。
  2. 接受阶段(Accept Phase)
    提议者在收到大多数接受者对Prepare(n)请求的响应后,可以确定一个提案值。如果接受者返回了已经接受的提案,提议者会选取编号最大的那个提案值;否则,可以选择任意值。
    提议者将提案(n, value)发送给大多数接受者,请求他们接受该提案。
    接受者收到提案后,如果提案编号n不小于它已经响应过的所有Prepare请求的编号,则接受该提案,并向提议者回复确认消息。
    达成共识
    当提议者收到大多数接受者对Accept(n, value)请求的确认时,认为提案已经被接受,达成共识。
    学习者通过接受者的消息获知已经达成共识的值。
    Paxos算法的特点
    容错性:Paxos算法能够容忍少量的节点故障,只要大多数节点正常工作,系统就能达成一致性。
    一致性:Paxos算法保证所有参与节点最终会达成一致的决策。
    复杂性:Paxos算法的实现和理解相对复杂,特别是在处理边界情况和优化性能时。
    Paxos的变种
    Paxos算法有许多变种,用于在不同的应用场景中优化性能和简化实现,例如:
    Multi-Paxos:扩展Paxos算法以支持多个提案的连续达成共识,常用于实现分布式日志。
    Fast Paxos:通过减少消息传递的轮数来加速达成共识。
    Cheap Paxos:优化资源使用,降低实现成本。
    应用场景
    Paxos算法广泛应用于需要分布式一致性的系统中,例如分布式数据库、分布式文件系统和分布式协调服务等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654972.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

玄机平台应急响应—webshell查杀

1、前言 这篇文章说一下应急响应的内容&#xff0c;webshell查杀呢是应急响应的一部分。那么什么是应急响应呢&#xff0c;所谓的应急响应指的是&#xff0c;当网站突然出现异常情况或者漏洞时&#xff0c;能够马上根据实际问题进行分析&#xff0c;然后及时解决问题。 2、应…

内网安全-隧道搭建穿透上线内网穿透-nps自定义上线内网渗透-Linux上线-cs上线Linux主机

目录 内网安全-隧道搭建&穿透上线内网穿透-nps-自定义-上线NPS工具介绍搭建过程 nps原理介绍MSF上线CS上线 内网渗透-Linux上线-cs上线Linux主机1.下载插件2.导入插件模块3.配置监听器4.服务端配置5.配置C2监听器并生成木马6.执行木马 内网安全-隧道搭建&穿透上线 内网…

做抖店如何避免被同行内卷?这5点建议,可以解决这个问题

我是王路飞。 都说2024年的抖店不赚钱了&#xff0c;商家太多了&#xff0c;太内卷了&#xff0c;一点都不好做~ 那为什么依然有很多商家在坚持做呢&#xff1f;为什么依然有很多新手入局呢&#xff1f; 无非是抖店确实能带来可观的利润回报罢了。 那如何避免被同行内卷呢&…

idea中git检出失败

之前clone好好的&#xff0c;今天突然就拉取不下来了。很多时候是用户凭证的信息没更新的问题。由于window对同一个地址都存储了会话。如果是新的会话&#xff0c;必须要更新window下的凭证。 然后根据你的仓库找到你对应的账户&#xff0c;更新信息即可。

【前端】从手动部署到自动部署:前端项目进化之路

从手动部署到自动部署&#xff1a;前端项目进化之路 在前端开发的领域内&#xff0c;部署是一个不可忽视的环节。随着项目复杂度的增加和线上更新频率的提升&#xff0c;手动部署逐渐暴露出它的弊端。本文将带你从手动部署过渡到自动部署&#xff0c;完成前端项目进化的重要一…

Round-Robin 调度逻辑算法

Round-Robin 调度逻辑算法 1 Intro1.1 固定优先级1.2 Round-Robin算法 之前上学还是工作&#xff0c;都接触过调度算法&#xff1a;Round-Robin和weight-Round Robin算法&#xff0c;但只知道它的功能和目的是什么&#xff0c;没有具体了解如何实现的&#xff1b; 现在是工作上…

移动云服务器选购指南(图文教程详解)

目录 一、前言 二、基本概念 2.1 定义 2.2 部署形式 2.3 用处 三、主流平台 四、主流产品推荐 4.1 云电脑 4.2 云主机ECS 4.3 弹性公网 IP 五、选购指南 5.1 明确场景 5.2 明确需求 5.3 明确身份 新用户 老用户 5.4 明确时间 5.5 明确教程 六、总结 一、前言…

【多态】(超级详细!)

【多态】&#xff08;超级详细&#xff01;&#xff09; 前言一、 多态的概念二、重写1. 方法重写的规则2. 重写和重载的区别 三、多态实现的条件四、 向上转型五、动态绑定 前言 面向对象的三大特征&#xff1a;封装性、继承性、多态性。 extends继承或者implements实现&…

短视频商城全套源码:开启电商新纪元

随着数字媒体的快速发展&#xff0c;短视频平台已经成为人们获取信息、娱乐和社交的重要渠道。在这样一个大背景下&#xff0c;短视频商城的兴起&#xff0c;无疑为电商行业带来了新的机遇和挑战。本文将探讨短视频商城全套源码的重要性&#xff0c;以及它如何助力商家和开发者…

详解Spring MVC

目录 1.什么是Spring Web MVC MVC定义 2.学习Spring MVC 建立连接 RequestMapping 注解介绍及使用 获取单个参数 获取多个参数 获取普通对象 获取JSON对象 获取基础URL参数 获取上传文件 获取Header 获取Cookie 获取Session 总结 1.什么是Spring Web MVC 官⽅对于…

生成式AI模型大PK——GPT-4、Claude 2.1和Claude 3.0 Opus

RAG(检索增强生成)系统的新评估似乎每天都在发布&#xff0c;其中许多都集中在有关框架的检索阶段。然而&#xff0c;生成方面——模型如何合成和表达这些检索到的信息&#xff0c;在实践中可能具有同等甚至更大的意义。许多实际应用中的案例证明&#xff0c;系统不仅仅要求从上…

《征服数据结构》目录

我们知道要想学好算法&#xff0c;必须熟练掌握数据结构&#xff0c;数据结构常见的有 8 大类&#xff0c;分别是数组&#xff0c;链表&#xff0c;队列&#xff0c;栈&#xff0c;散列表&#xff0c;树&#xff0c;堆&#xff0c;图。但如果细分的话就比较多了&#xff0c;比如…

华为WLAN实验继续-2,多个AP如何部署

----------------------------------------如果添加新的AP&#xff0c;如何实现多AP的服务----------- 新增加一个AP2启动之后发现无法获得IP地址 在AP2上查看其MAC地址&#xff0c;并与将其加入到AC中去 打开AC&#xff0c;将AP2的MAC加入到AC中 sys Enter system view, re…

手写电纸书天花板,阅读办公新体验 | 汉王手写电纸本 N10 2024 版使用评测

手写电纸书天花板&#xff0c;阅读办公新体验 | 汉王手写电纸本 N10 2024 版使用评测 请问如果说到电纸书&#xff0c;你的认知还只是Kindle吗&#xff1f;然而遗憾的是&#xff0c;Kindle亦是过去&#xff0c;智能才是未来。 哈喽小伙伴们好&#xff0c;我是Stark-C~&#x…

【机器学习】【深度学习】批量归一化(Batch Normalization)

概念简介 归一化指的是将数据缩放到一个固定范围内&#xff0c;通常是 [0, 1]&#xff0c;而标准化是使得数据符合标准正态分布。归一化的作用是使不同特征具有相同的尺度&#xff0c;从而使模型训练更加稳定和快速&#xff0c;尤其是对于使用梯度下降法的算法。而标准化的作用…

Python自动化办公Excel数据处理实战指南

目录 一、引言 二、需求分析 三、技术选型 四、实战操作 数据读取 数据清洗 数据分析 数据输出 五、学习资源推荐&#xff1a; 六、结语 一、引言 在现代办公环境中&#xff0c;Excel数据处理是一项不可或缺的技能。然而&#xff0c;当数据量庞大、处理流程复杂时&a…

Nocobase快速上手 -第一个collection

本文记录Nocobase中如何创建collection&#xff0c;以及如何将collection展示到页面中&#xff0c;并且配置CRUD相应的操作. Collection 在NocoBase中&#xff0c;collection&#xff08;集合&#xff09;是用来组织和存储各种数据的容器&#xff0c;如订单、产品、用户、评论…

【算法】位运算算法——判断字符是否唯一

题解&#xff1a;判断字符是否唯一(位运算算法) 目录 1.题目2.题解3.位图参考代码4.细节5.总结 1.题目 题目链接&#xff1a;LINK 2.题解 题解有两种方法&#xff0c; 一是做一个哈希数组&#xff0c;去查重&#xff1b; 二是直接用一个变量每一位来对应表示是否有这个字母…

《QT实用小工具·六十七》QTabWidget实现的炫酷标签工具栏

1、概述 源码放在文章末尾 该项目基于QTabWidget和QTabBar实现了灵活的标签工具栏&#xff0c;主要包含如下功能&#xff1a; 1、标签栏可以收起&#xff0c;可以展开 2、可以在标签栏中添加新的标签界面 3、可以从标签工具栏中把界面拖出来&#xff0c;也可以拖回去 4、关闭拖…