如何在SMR(State Machine Replication)系统中使用PAXOS算法

大家虽然看过那么多有关PAXOS算法的理论和论文,但仍然云里雾里,原因就是没有实践。这里咱们不讲理论,直接用实际开发来通俗讲解PAXOS算法的应用。

提案(proposal)是PAXOS算法一个重要的组成部分。

先来看一下用于在分布式节点间传递提案(accept_req)的数据结构:

struct accept_req {
    node_id_t node_id;
    view_stamp msg_vs;
    view_stamp req_canbe_exed;
};

struct view_stamp {
    view_id_t view_id;
    req_id_t req_id;
};

typedef uint32_t view_id_t;

对应它,我们还需要在节点上维护几个变量:

highest_committed_vs

highest_seen_vs

highest_to_commit_vs

我们的分布式系统使用的是三个节点,其中一个是leader,其余两个是secondary node。

highest_seen_vs表示该节点目前接受到的请求中提案号最大的。

在leader上,highest_seen_vs用于产生一个请求的提案号(也就是上面提到的view_stamp这个数据结构):

view_stamp next = get_next_view_stamp(comp);

view_stamp_inc(comp->highest_seen_vs);

leader每从client接受一个请求(准确地说,应该是一个socket operation,包括connect, send, close三种),就将next与这个请求绑定,按照到来的顺序依次加1。leader节点上的highest_seen_vs可以代表目前已接受请求中编号最大的那个。

在secondary节点上,highest_seen_vs的更新要根据来自leader的提案(一开始提到的accept_req)。这个提案代表一个请求,所以它包含这个请求的提案编号 msg_vs。当secondary节点接收到这个提案后,会将提案的msg_vs和这个节点上维护的highest_seen_vs进行比较,如果前者比后者大,就将后者更新为前者:

// update highest seen request
if(view_stamp_comp(&msg->msg_vs,comp->highest_seen_vs)>0){
    *(comp->highest_seen_vs) = msg->msg_vs;
}

再回到leader上,看看这个提案是如何构造的。一个提案代表一个请求。通过上面的介绍,我们已经知道提案中的msg_vs就是leader分配给这个提案的编号,那req_canbe_exed代表什么呢?先介绍一下highest_to_commit_vs:

highest_to_commit_vs表示该节点即将要提交的请求。

提交请求指的是这个请求已经获得三个节点大多数(两个或三个节点)认可,可以把它提交给真正的服务器进行处理。这是PAXOS用来将一个请求在三个节点间达成一致的方式。

highest_committed_vs 表示已经提交的请求中最大编号。

也就是说,请求可以分成三种类型:已被接收但未被认可,已认可但未被提交,已提交。

再回到leader上的req_canbe_exed,在leader构造一个请求的提案时,有:

msg->req_canbe_exed.view_id = comp->highest_to_commit_vs->view_id;
msg->req_canbe_exed.req_id = comp->highest_to_commit_vs->req_id;

可见req_canbe_exed传达的是leader节点上即将要提交的请求的提案号。当这个提案发给secondary节点时,secondary节点会把该提案中的req_canbe_exed与自身的highest_to_commit_vs进行比较,如果前者大,就将后者更新为前者:

if(view_stamp_comp(&msg->req_canbe_exed,
    comp->highest_to_commit_vs)>0){
    // 如果前者大于后者
    *(comp->highest_to_commit_vs) = msg->req_canbe_exed;
    SYS_LOG(comp,"Now Node %d Can Execute Request %u : %u .\n",
    comp->node_id,
    comp->highest_to_commit_vs->view_id,
    comp->highest_to_commit_vs->req_id);
}

可见,leader会和secondary节点时刻保持状态一致:leader更新了highest_seen_vs和highest_to_commit_vs,会通过发送给secondary节点的提案(accept_req)告诉secondary该更新了。

还有一个概念,先看一下figure:

还剩下msg_vs到highest_committed_vs的箭头。下面将涉及PAXOS的核心思想。

提案到达secondary节点后,该节点发现这个提案的编号小于或等于该节点已经提交的最大编号highest_committed_vs。这说明,这个新到的提案所代表的请求在该节点上已经被提交给真正服务器去处理了,此时该节点会忽略这个请求:

if(view_stamp_comp(&msg->msg_vs,comp->highest_committed_vs)<=0){
// we have committed the operation, safely ignore it
    SYS_LOG(comp, "I‘ve already committed the operation.
                    I‘ll ignore this one.\n");
    goto handle_accept_req_exit;
}

问题就来了,

问题一:什么情况下会令secondary节点忽略来自leader的提案?

问题二:为什么一个提案要获得大多数认可才能提交?

时间: 2024-10-07 20:35:14

如何在SMR(State Machine Replication)系统中使用PAXOS算法的相关文章

通过P-SMR看State Machine Replication

在一个复制系统中,为了保持一致性,各个replicated server是串行执行,这样性能上就会比只有一台server的系统慢,因为只有一台server可以进行并行处理.如果在复制系统中各个server也能进行并行处理的话, 这将是很大的进步. 但是如果各个线程之间没有共享变量的话,在复制系统的每个server上进行并行处理也是可行的,实际上以前很多复制系统并行处理都是基于这一点去做的. P-SMR也是要根据命令之间的依赖关系判断什么情况下可以并行,什么情况下是串行. 我们需要将服务程序抽象成

Android开发如何在4.0及以上系统中自定义TitleBar

本文将通过一个实例讲解怎么实现在4.0及以上系统版本中实现自定义TitleBar,这只是我自己找到的一种方法; xml布局文件 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="m

分布式数据库中的Paxos 算法

分布式数据库中的Paxos 算法 http://baike.baidu.com/link?url=ChmfvtXRZQl7X1VmRU6ypsmZ4b4MbQX1pelw_VenRLnFpq7rMvYfDDmg3Rg1Aw6YyobKozdN599x2sCiJNNHV_ Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的"La",此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法.这个算法被认为是类似算法中最有效的. 中文名 Paxo

如何在CentOS系统中安装配置SNMP服务

CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统)是Linux发行版之一,现在有一大部分服务器在使用此操作系统:SNMP(简单网络管理协议)能够使网络管理员提高网络管理效能,及时发现并解决网络问题以及规划网络的增长.网络管理员还可以通过SNMP接收网络节点的通知消息以及告警事件报告等来获知网络出现的问题.本文主要介绍如何在CentOS系统中安装配置SNMP服务. 工具/原料 CentOS操作系统 方法/步骤 使用SNMP服务前

MITK中State machine和configuration详解和调用顺序

(学习笔记,错误难免,请指正:私人劳动,转载请注明出处) 下面以MITK自带的mitkPointSetDataInteractor.h.mitkPointSetDataInteractor.cpp.PointSet.xml.PointSetConfig.xml为例,解释MITK中的交互原理,以及State machine和configuration的调用顺序. PointSet.xml: <statemachine> <state name="start" start

如何在ios 系统 中抓包??

为了实现在ios系统上抓包,如下步骤: 1,设备越狱 2,在cydia-软件源-设置中改为开发者,否则有些deb搜索不到 安装如下软件:OpenSSH,OpenSSL,wget (下载工具) Aptitude 及 APT 0.6 Transitional (deb包工具) unzip 及 zip (解压缩及压缩打包工具) 3,安装并启动sshd后,通过ssh -l root IPAD_IP_ADDRESS登录,默认口令是:alpine,这是ios系统默认的root密码,记得及时修改. 4,命令行

如何在CRM系统中集成ActiveReports最终报表设计器

有时候,将设计器集成到业务系统中,为用户提供一些自定义的数据表,用户不需要了解如何底层的逻辑关系和后台代码,只需要选择几张关联的数据表,我们会根据用户的选择生成可供用户直接使用的数据集.本文第一部分主要讲解了,如何构造三种报表模板,第二部分主要讲解了对于DataRelation类在动态绑定数据集之间的用法. 首先需要构造LayoutBuilder类,该类主要构造三种类型的报表以及为它们添加数据集字段. 1. 创建RDL 报表 使用PageReport对象,并添加属性 public static

手把手教你如何在Ubuntu系统中安装Pycharm

前几天带大家一起安装了Ubuntu14.04系统,没来得及上车的伙伴可以戳这篇文章:手把手教你在VMware虚拟机中安装Ubuntu14.04系统.今天小编带大家一起在Ubuntu14.04中安装Pycharm,具体的教程如下.1.首先在主目录下创建software文件夹,此时该文件夹为空文件夹.这个文件夹下用于放置安装软件,当然这个步骤不是必须的,只是小编习惯的做法. 2.去Pycharm官网上下载Pycharm的Linux安装包,建议下载专业版的,如下图所示. 3.下载到本地之后,将其用fi

linux内核探索之内存管理(二):linux系统中的内存组织--结点、内存域和页帧

本文主要参考<深入linux内核架构>(3.2节)及Linux3.18.3内核源码 概述:本文主要描述了内存管理相关的数据结构:结点pg_data_t.内存域struct zone以及页帧(物理页):struct page ,以及该结构相关的一些基本概念. 1. 概述 内存划分为接点,每个结点关联到系统中的一个处理器,在内核中表示为pg_data_t. 各个结点又划分为内存域,比如DMA内存域,高端内存域,普通内存域. 内核内存域的宏: enum zone_type { #ifdef CONF