基于状态机方法构建高容错性服务

摘要:
本文讨论了一种基于状态机方法的分布式容错服务。我们可以使用状态机的一些方法来构建状态一致的多系统服务副本。将这套状态机理论应用到高容错服务的设计中,我们可以转换以下概念:当每个服务的复制状态不一致时,意味着某些系统存在错误。步骤3是上述六个步骤中最关键的步骤。对于输入排序,它需要每个状态机之间的投票协议来实现一致性。

文章目录

前言

当今技术进步更新十分的块,外界环境的变化对系统服务提出了更高的要求。传统中心集中式的系统服务管理模式越来越暴露出其不足之处,诸如单点瓶颈问题,不可容错等等。因此分布式的且具有高容错性的服务设计理念应运而生。分布式的服务设计意味着其中会涉及到不同服务之间的通信协调,但同时分布式的服务部署在一定层面带来了更高的系统容错度。本文笔者来讨论一种基于状态机方法构建的分布式容错服务。当今许多成熟的分布式系统都带有部分其中的设计理念。

状态机理论和系统容错性的关联

粗一看文章标题,可能有同学会比较好奇,状态机理论和系统容错性设计到底有哪些关联之处呢?

简单地来做个解释,系统容错性的一个关键点在于说系统服务要具有多个状态完全一致的服务copy。当当前的系统服务出错了,可以随时从备选的copy服务中挑选一个继续提供服务。概括地来说,系统容错性的核心点在于系统具有多实例备份的设计,而多实例服务的核心点又在于各个服务拷贝之间状态的一致性。而这个一致性要求,就和我们本文所提到的状态机理论就有相关性了。

我们可以运用状态机的一些方法,来构建状态一致性的多系统服务拷贝。下面我们来了解了解状态机理论的一些内容。

状态机理论

状态机,英文名称为State Machine,在状态机理论中,有以下一些概念的定义:

  • State,状态
  • Input,输入
  • Output,输出
  • 状态转化方法,Input × State → State
  • 输出方法,Input × State → Output
  • 初始State状态

从上面的概念定义中,我们可以看到里面出现频率最高的词是State,一切都是围绕State展开进行的。在状态机中,一个初始状态经过一次输入转变为下一个状态,同时产生了一个输出内容。当多份初始状态一致的状态机,在经过完全相同、顺序也相同的的Input处理后,将会转变到最终一致的状态,同时将会产生相同的Output内容。

将这套状态机理论应用到高容错性服务设计之中,我们可以以下一些概念转换:

当各服务拷贝状态出现不一致情况时,意味着部分系统发生了错误的情况。这个不一致指某服务状态与大多数其它服务State不一致的时候。

这里我们通常说的“大多数”指的是半数以上。

状态机方法论的实际应用

下面我们来聊聊状态机方法论的实际应用,看看它是如何应用在独立,多服务容错性系统设计之中的。在这个方法论里,总共可分为6个子步骤:

  • 1)布置初始状态一致的状态机在各个独立的服务拷贝中
  • 2)服务接受客户端请求,将其解析为状态机的Input
  • 3)定义上述Input的执行顺序
  • 4)按照步骤3)定好的顺序,让服务中的状态机执行Input
  • 5)返回客户端状态机执行的Output内容作为response
  • 6)监控检测服务拷贝间的状态的差异

下面我们一一来对上述部分子步骤进行分析。
步骤3在上述6个步骤中是最为关键的步骤,对于Input排序来说,这里面要求各个状态机之间进行投票协议约定,来达成一致性。

状态机的错误恢复

在上述过程中,有时难免会发生部分状态机实例发生错误现象,为了能够让此状态机能再次恢复到最新状态,我们需要保存历史Input Log作为恢复时使用。如上文所提到的,初始状态一致的状态机在经过相同顺序,相同的Input处理后,会达到最终一致的状态。

但是保存历史所有的Input Log会导致消耗大量的存储空间以及可能的长时间恢复耗时,这里我们会有checkpoint的操作,来定期保存当前状态以及移除掉过去无效的Input Log数据。HDFS的checkpoint机值本质上也是此方法的一个理论实现。

以下是基于状态机的流程处理过程图:
在这里插入图片描述

其实回过头来看状态机理论,在当前很多成熟的分布式系统内部或多或少都有其理论原理的体现,比如请求一致性处理,状态一致性检测等等。

引用

[1].https://en.wikipedia.org/wiki/State_machine_replication

免责声明:文章转载自《基于状态机方法构建高容错性服务》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Raft一致性协议的投票选举数据库期末下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用 pt-online-schema-change 实现在线DDL

问题背景 平时进行修改表的结构,更改字段,新增字段,更改字段名称一般都是通过ALTER TABLE 语法进行修改的。对于小表或者并发访问不是很大的情况是OK。但是如果是在线大表,那就很麻烦。由于表数据量大,复制表需要比较长的时间,在这个时间段里面,表是被加了锁的(写锁),加写锁时其他用户只能select表不能update、insert表。表数据量越大,耗时...

浅拷贝与深拷贝

浅拷贝与深拷贝 一、数据类型 数据分为基本数据类型(String, Number, boolean, Null, Undefined,Symbol)和对象数据类型。 基本数据类型的特点:直接存储在栈(stack)中的数据 对象数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里 二、浅拷贝与深拷贝 深拷贝和浅拷贝是只针对Ob...

std::thread函数传参拷贝次数

c++11的thread库大大方便了开发,但是目前网络上少有深入分析的资料和使用例程。特别是在线程函数传参这一块,一般止步于使用std::ref传引用。 这次写服务器遇到个BUG,线程函数参数是智能指针,传递方式是pass by value, 设想的是引用计数+1,但是实质上是引用计数+2。一个在于内部tuple存储是用的拷贝构造,然后函数调用的时候也是用的...

vector的push_back对于拷贝构造和赋值操作的调用

http://blog.csdn.net/silyvin/article/details/8985323 对应与CArray,补充一个vector的测试。 class A { int *m_a; int bb; private: A(); public: A(int n) { m_a = new int; *m_a = n; }...

装箱和拆箱

在C#中的有两种类型的变量:值类型和引用类型。当值类型和引用类型相互转化时,会发生装箱和拆箱的过程。这里有一点要声明:经过拆箱或装箱的对象会多出它自己一份拷贝,如图所示: 从图可以看出它和它的拷贝不在一个存储区域。这也是值类型和引用类型的区别所在。值类型总是在栈中,而引用类型总是在托管堆中。(目前J2SE5.0也支持了装箱和拆箱,但是我目前不知道是否和C#一...

Python 关于拷贝(copy)汇总(列表拷贝 // 字典拷贝 // 自定义对象拷贝)

1.列表拷贝 引用是指保存的值为对象的地址。在Python语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些。下面举个例子: 问题描述:已知一个列表,求生成一个新的列表,列表元素是原列表的复制 a=[1,2]b=a 这种做法其实并未真正生成一个新的列表,b指向的仍然是a所指向的对象。这样,如果对a或b...