来自论文Rex: Replication at the Speed of Multi-core

对一系列请求的串行执行已经跟不上多核服务器的脚步了,但又不能直接并行化,因为并行会带来线程调度和锁竞争的不确定性,这就使得状态机复制的前提得不到满足,即要保持确定性。有一点要注意:全序的请求序列并不是保证一致性的必须,也就是说我们完全可以在并行化和一致性之间建立起双赢。本文旨在研究如何在多核机器上实现并行化,同时保证一致性,这样我们就会获得比一般状态机复制更高的吞吐率。那如何去实现这种并行化呢?

对于标准的复制状态机,是通过从一个相同的初始状态开始,以全序的顺序确定性地执行相同的请求集,从而保证一致性。而一旦并行,确定性就难以得到保证,所以这是我们的挑战。所以确定性的并行化就成了一个很热的研究方向,但是目前所采取的手段都是以牺牲性能为代价,还没有从架构上提供硬件支持的方法。Eve是通过mixer来实现了确定性的并行化,mixer会将请求划分成互相没有冲突的组,这样在不同机器上并行去执行这些组就有可能达到确定性和一致性。本文中我们提出Rex,一个execute-agree-follow模型,实现一致性。这个模型中有一个primary机器,一开始它会自由地去并行执行请求,在这个过程中会将不确定性的决定记录在一个偏序的trace中,之后其它的机器运行Paxos来对trace达成一致,最后secondary机器根据这个trace并行执行同样的不确定性选择,这样就跟primary机器保持了同样的一致性状态。进过实验,Rex会获得16倍于标准状态机复制的吞吐率。接下来让我们详细了解Rex。

Rex中有request handler,这个handler会通过标准的同步原语来控制线程对共享数据的访问,进而达到并行执行的目的。因为同步事件的次序是不确定性的唯一来源,所以这些handler会实现确定性。

1. Rex vs. State-Machine Replication

State-Machine Replication, 状态机复制使用consensus-execution模型,即首先会形成一个一致的请求序列ri(consensus阶段),然后根据这个顺序来执行请求(execution阶段)。这应该是最基本的想法了,要想保证在多个机器上执行同样的请求序列,首先要统一这个序列。但Rex却正好相反,它用的是execute-agree-follow模型,首先让primary去并行执行请求,同时把这些请求之间的细粒度的因果依赖关系记录在一个trace tri中(execute阶段),primary会定期地将最新的trace作为value发给下一个consensus instance。之后各个机器会对一系列的trace达成一致(agree阶段)。一旦提交,secondary会根据这些trace来复制在primary上的执行(follow阶段)。也就是说Rex会在达成一之前在primary上去执行。在state-machine replication中,会在请求达成一直后处理请求,处理完后primary会给client一个回复。而在Rex中,在处理完请求后,primary不能去回复client,而是要等到一个包含请求处理的trace,并且这个请求所有的依赖事件都已经提交给一个consensus instance。不过,primary不用去等在secondary上的重新执行完成。接下来详细了解一下Rex的各个阶段。

►Execute阶段

首先在Primary上执行请求,在执行过程中primary上的request handler会记录同步事件集中的因果依赖关系。

Figure 2 是一个例子,两个线程在处理两条不同的请求,锁L被用来控制对共享数据的访问,Lock和Unlock会在两个线程间引起因果依赖关系,如图中的edge,Lock(L)要在Unlock(L)之后。我们之前说的trace中有同步事件,这个同步事件由线程的id和本地时钟来确定,而两个同步事件之间的因果顺序由一条有向边来表示,如在Figure 2中,Unlock(t1,3)到Lock(t2,2)是一条因果边。随着primary继续处理到来的请求,trace会一直增加。这里引入一个概念:cut point,即在一个线程中选出一个事件。来自每个线程的cut point会形成一个cut。一个cut包含了线程在这些cut point之前所有的事件,包括线程间的因果顺序。一个cut是一致的,是指在trace中从事件e1到e2的任何因果边,如果e2在cut中,那么e1也在cut中。如,在Figure2中c1是一致的,而c2是不一致的,因为对于c2,(t1,4)在cut中,而(t2,3)不在cut中。

►Agree阶段

Rex的replicas用多实例的Paxos协议在一系列的traces上达成一致。trace存的是并行执行请求过程中出现的不确定性的决定,在instance i提交的trace是在instance i+1提交的trace的前缀,实际上这是一个在不断增长的trace。当发生primary change时,在创建更长的trace作为提议给随后的consensus instance之前,新的primary必须首先learn前面consensus instance中提交的,并且重新执行(replay)上一个完成的consensus instance中的trace。

►Follow阶段

在follow阶段,secondary根据replicas已经达成一致的trace来执行。设想一下,如果线程t中的事件e必须要等到线程t’中的事件e’的执行,那么Rex会在执行线程t中的事件e之前暂停,并让线程t’中的事件e’执行完后唤醒线程t。这样,在每一个secondary机器上,线程的执行都会遵循一样的因果顺序。但是因为线程交错的不同,有可能会出现刚才例子中的线程等待。再来个例子,primary机器上有两个线程t1和t2,线程t1要在t2之前获得lock,但是在replay,t2首先被调度并先于t1达到了请求锁的点,在这种情况下,t2就要等待t1。实际上我们可以察觉到由因果边所反映的因果依赖决定了follow阶段的并行程度。对于依赖少的,就会获得高的并行性,对于依赖复杂的,就会因为线程等待而增加运行时间。其实能记录线程间的依赖,并能根据这些记录来约束线程的interleaving本身就很了不起,这避免了人工干预,实现了多请求并行处理的确定性,但能否去降低依赖的复杂度,从而提高并行性?比如去掉不必要的因果依赖。还有一个疑问:如果client提出来三个request,但这三个request之间相互独立,是不是直接并行处理就可以?如果是,能否在执行它们之前就知道它们相互独立,这样就省去了在执行过程中去记录它们的因果关系,这样其他机器就跟primary一样直接并行处理,就不必再根据得到的因果关系去处理三个请求。

2. Correctness and Concurrency

Correctness体现在三个方面:(i)一致性:所有的replica机器在一系列trace上达成一致,(ii)确定性:相同trace可以使得replica达到一个相同的状态,(iii)前缀:较早consensus instance中提交的trace是任何之后consensus instance中提交的trace的前缀。在状态机复制(state-machine replication)中,请求都是串行执行的,而在Rex则是并行执行:primary用Rex的同步原语去并行处理请求(为什么请求之间会有因果依赖顺序?),同时记录执行中的因果顺序。之后secondary机器会根据所记录的因果顺序去再一次处理这些请求。其实我们可以看到Rex的一个limitation:在primary执行过程中记录causal order和secondary根据之前记录的order执行都会增加Rex的overhead。然而论文中是这样来回答这个limitation:这个overhead是易控制的,而且在多核机器上带来的很高的并行性会对性能有很大提升。后面我们会详细了解这些理由。

3. Agreeing on Traces

Rex使用Paxos来确保一致性(consensus)和前缀(prefix)。Rex用Paxos来管理一系列的consensus instances,这样replicas就会在trace达成一致。

►Consensus in Rex

Rex使用的多实例Paxos可以检测出replica failures,也能选出一个新的leader(当现在的leader出错时)。其实这就从多核性能问题转向了容错问题,要考虑万一leader出错了,要能选出新的leader,这就要靠Paxos的第一阶段。投票数多的replica成为新的leader。在这个阶段,新的leader必须学习已经提交的proposal,并提出一样的value来确保一致性。在Paxos的第二阶段,leader得到在consensus instance中提交的提议。其实这里并没有详细说明Paxos到底是如何运作的。而Rex本身又在Paxos的基础上提出了两个值得注意的设计决定(design decision):

首先,Rex在任何时刻至多有一个处于活动的consensus instance。Primary只有在了解到每一个earlier instance有一个提交的提议(proposal)后才提出一个instance。这个设计会在三个方面简化Rex的设计:首先,Rex不必管理多个处于活动的instances;第二,这很容易保证前缀,因为当发生primary change时,新的primary只是简单地学习上一次instance中提交的trace,然后replay这个trace;第三,在新instance中一个提议可以不用包含全部的trace,只需包含比上一次instance中提交的trace多出的信息。

(Primary会把前面instances中还没提交的提议都放在新instance的提议中。)

第二个设计,Rex中的Paxos的leader与primary共存(co-located)。Propose(i, p) 是向instance i 提出提议p。

这里再明确一下, Rex的primary与leader共存,处理客户端请求,定期创建traces作为为了一致性的提议。那些traces自然地满足前缀(prefix)的条件,因为它们是统一执行的cuts。

►Reconfiguration

当一个新的leader出现时,它会变成新的primary,而旧的primary则会变成secondary。

►Checkpointing

Rex通过checkpointing来让一个replica从错误中恢复过来。让primary在执行过程中定期地checkpoint是不好的。

4. Execute and Follow

Rex利用record进行replay,从而实现determinism的属性。在replay时也要有并行性。

►Wrapping Synchronization Primitives

如何保证各台机器上多线程同步操作具有相同的顺序,这是很关键的问题。Rex在通用的同步原语上加了wrapper。我们所说的记录因果依赖,实际上就是集成在这些wrapper中。

►Tradeoff between record overhead and replay parallelism

只有Lock和Unlock,记录中的因果关系式同一个lock上所有事件的全序。

在Figure 4 的右图中,在replay过程中,t3和t2不相互等待。右图要比左图记录更多的因果边,并且更多的共享资源信息。也就是说为了获得较高的并行性,Rex就要增加record的overhead,它们之间的tradeoff问题是Rex要把握的关键。

►Remove unnecessary causal edges

通过去除不必要的因果边(causal edges)可以减小trace的大小,并且也可以减少因为要检查因果边是否满足(satisfied)而带来的replay cost。所谓的不必要的因果边指的是这条边可以通过其他的边间接得到,例如Figure 4中的因果边X可以由A和t2内部的1->2边来代替,同理Y也是如此。这样之前我们所说的record的overhead就会减少,同时还保证了较高的并行性。

5. Discussion

Rex使用的是execute-agree-follow模型,Eve使用的是execute-verify模型,State-Machine Replication使用的是consensus-execution模型。Rex和Eve是应用在多核服务器上的两种不同的方法,尤其体现在在replicas间实现一致性的前提和性能机制。

►Consistency

Eve在verify阶段通过比较application states来检测出是否有divergence,从而保证consistency。Eve的这种做法很好:(i)verification可以很好得保证consistency,能检测出各种divergence, 如Byzantine faults和 concurrency bugs;(ii)replicas可以独立执行。然而在Rex中,replicas不再独立执行,因为他们要做出相同的non-deterministic决定才能保证consistency。再来比较二者的correctness,Eve的correctness取决于正确mark机器的states,而Rex的correctness取决于完全捕获到所有non-determinism的来源。Eve是事后检测,而Rex是提前检测。那究竟二者谁更胜一筹?

当然本文还是更倾向于Rex,理由是Rex中可以很容易发现locks和non-deterministic functions,因为之前我们提到Rex使用了自己的synchronization primitives,这样用Rex的同步原语来替换原程序中的接口,便很容易捕获到所有的locks和non-deterministic functions,这种替换是否类似LD_PRELOAD的机制?尽管如此,数据竞争还是很难去发现。但论文却说越来越多的人意识到数据竞争的危险,并在用数据竞争做同步时开始采取防范措施。

Eve中的状态标记本质上是将程序状态划分成两部分,没有做标记的状态称作context。

这里文章点出了Eve的execute-verify的一个limitation:We have found that handling on-disk state is tricky in the execute-verify model.意思是处理记录在磁盘的状态比较棘手。

Rex继承了Eve中verification的优点,如Result checking,用primary上的返回值来检查secondary上的结果。为了检测数据竞争,可以再trace中记录更多的状态和返回值,但是这回明显增加overhead,但是Rex通过resource-version checking的手段可以有效的找到数据竞争的根源。

►Performance

Eve和Rex都是为多核处理所做的努力,为了实现并行处理,Eve采用了mixer,mixer会将请求分成没有冲突的batches,这些batches就可以并行执行。但是对于Eve来说,如果要增加并行性,需要大的batches,但同时等待大的batches又会带来更长的latency,也就是说Eve会在latency和throughput之间有个tradeoff。

Rex不会去了解请求之间的冲突,文章说Rex将faithfulness作为重要的设计目标,因为faithfulness对性能有重要影响。

正常情况下,Eve的overhead主要是由运行mixer,追踪state改变和检测divergence引起的。而Rex的overhead则是由捕获不确定性decisions(它们包含同步原语)和在secondary机器上follow这些decisions引起的。到底谁的overhead更多呢?而且当检测出divergence时,Eve要roll back去串行重新执行,不过Eve认为这种divergence不是经常发生的。其实对于Eve来说,最重要的是mixer的使用,如果mixer不好,对性能会有很大影响。mixer要捕捉到当处理两个请求什么时候会出现conflicts,这时误报和漏报都会降低性能,所以降低mixer的误报率和漏报率是关键。而对于Rex,rollback只发生在primary出错和被替换,对Rex来说rollback就要比Eve的简单不少(是这样吗?)。

Rex: Replication at the Speed of Multi-core相关推荐

  1. make though multi core

    make -j$(sysctl -n hw.ncpu) similar to command make -j $(nproc)  under ubuntu

  2. solr多core的处理

    有2中配置方式,一是从Solr Admin进行multi core的配置. 在Solr Admin控制台里面选择:Core Admin 选择Add Core 然后把你准备好的路径写到里面去. name ...

  3. vvvvvvvvvvvvvvvvvvvvvvvvv

    Java Concurrency In Practice Brian Göetz Tim Peierls Joshua Bloch Joseph Bowbeer David Holmes Doug L ...

  4. dma工作时cpu工不工作_CPU如何工作?

    dma工作时cpu工不工作 CPU, also known as the microprocessor is the heart and/or brain of a computer. Lets De ...

  5. Intel® Performance Counter Monitor - A Better Way to Measure CPU Utilization

    https://software.intel.com/content/www/us/en/develop/articles/intel-performance-counter-monitor.html ...

  6. 中英数据库专家谈:数据库的过去、未来和现在

    简介:数据库是什么?未来的数据会被存在DNA里?数据库里的数据湖是什么? 1月16日,扫地僧做了一场直播,请到我的同事--数据库资深专家封神,和来自帝国理工的高级讲师Thomas Heinis(托马斯 ...

  7. DeepFaceLab: 更新记录以及版本说明!

    DeepFaceLab更新记录以及版本说明 DeepFaceLab 从2018年开始,进入快速迭代更新,所以版本非常多.我们追随这个项目许久,保存了一些有价值的历史版本,并且对软件的更新做一个记录,方 ...

  8. 干货分享: 服务器处理器基础知识

    戳蓝字"CSDN云计算"关注我们哦! CPU(中央处理器)是一台计算机的运算核心和控制核心.CPU主要功能是解释计算机指令以及处理计算机软件中的数据.CPU由运算器.控制器和寄存器 ...

  9. 多核处理器与向量处理器

    转自: http://www.vonwei.com/post/2outof52.html 52 Things: Number 2: What is the difference between a m ...

最新文章

  1. 独家 | 三种使用AI攻击网络安全的方法
  2. 机器人动力学简化模型(Euler-Lagrange equation)
  3. 全链路监控方案概述与比较
  4. Maven报错Missing artifact jdk.tools:jdk.tools:jar:1.7--转
  5. oracle时间用法
  6. Servlet上传文件和下载文件示例
  7. Javascript设计模式之发布-订阅模式
  8. Codeforces 52C
  9. 二代征信|番茄风控全网最全
  10. Eigen教程(5)之块操作
  11. [转载] python文件操作--写入文件
  12. Linux的学习之路grep命令
  13. docker基础4--docker的命令
  14. Google Code Review代码审查标准
  15. 计算机软件 退货,如何在在电脑收银系统中实现商品退货
  16. Chrome 离线下载最佳方法
  17. MENTOR PADS软件菜单显示不完整?这里有妙招
  18. 同一局域网内怎样获取新来美眉QQ号码!((*^__^*) 嘻嘻……)
  19. 数学建模竞赛国赛模板latex
  20. python爬虫-urllib-handler和代理

热门文章

  1. tigase集群配置搭建官方方法-xmpp通讯协议配备tigase集群开发简单省事-哇谷即时通讯IM源码服务-哇谷即时通讯源码
  2. [AHK]一键发送选中的文件给微信好友
  3. Redis 6.2.6(NoSQL简介/redis介绍及安装/数据类型/配置文件)
  4. 【ElementUI】使用VNode调整Message消息提示
  5. php如何调用api接口简单,在PHP中调用API接口|Post数据的方法
  6. OSChina 周四乱弹 —— 如何正确殴打男友
  7. 【每日早报】2019/09/23
  8. 程序员小志偷偷用30招惊艳公司所有人,迎娶小师姐(第6招)
  9. 第01课:生活中的监听模式——一坑爹的热水器
  10. C++程序设计-第15周数组上机实践项目