1Pipe: 数据中心网络中可扩展的全序通信方式 1Pipe: Scalable Total Order Communication in Data Center Networks 论文阅读

《1Pipe: 数据中心网络中可扩展的全序通信方式》

华为分布式方面的成果https://dl.acm.org/doi/10.1145/3452296.3472909

Ordered Communication能够解决许多分布式系统问题(replication,transaction)

之前UW一群人用“中心化”的programmable switch去提供有序多播(OSDI16的NoPaxos【通过网络层保证消息的有序传递,而消息的可靠性交由协议层来保证https://www.usenix.org/conference/osdi16/technical-sessions/presentation/li】和SOSP18的Eris【将并发控制功能的核心部分移至数据中心网络本身。该网络原语负责一致地对事务进行排序,并且新的轻量级事务协议可确保原子性https://dl.acm.org/doi/10.1145/3132747.3132751】),但存在单点容错和规模受限的问题。

论文分类:网络→在网络处理中;数据中心网络

计算机系统组织→可靠性

关键词:Total Order Communication, CATOCS, Data Center Networks, In-

Network Processing

摘要

1Pipe,a novel communication abstraction,a communication primitive

 

图表 1

  1. 使不同的接收方能够以一致的全序方式[1](或是说一致的总顺序consistent total order)处理来自发送者的消息。
  2. 以因果和完全有序的方式提供单播和scattering(“分散”即,一组到不同目的地的消息)。
  3. 提供了一个尽力而为的服务,最多一次传递一条消息,以及一个可靠的服务,可以保证传递,并为每个消息提供受限的原子传递。
  4. 可以简化和加速许多分布式应用程序,例如事务性键值存储、日志复制和分布式数据结构。

提出了一种在数据中心内部实现1Pipe的可扩展且高效的方法。

  1. 为了以可扩展的方式实现全序分发,1Pipe将顺序信息的记录(bookkeeping)与消息转发分离,并将工作分配给每个交换机和主机。
  2. 1Pipe聚合顺序信息,用于交换机的在网计算。这形成了系统的“控制平面”。
  3. 在“数据平面”上,1Pipe按因果关系在网络中转发消息,并在接收方根据顺序信息对消息进行重新排序。

在32服务器测试台上的评估表明,1Pipe实现了可扩展的吞吐量(每台主机每秒8000万条消息)和低延迟(10us),具有很少的CPU和网络开销。1Pipe在事务性key-value存储、TPC-C、远程数据结构和复制方面实现了线性可扩展的吞吐量和低延迟,其性能比传统设计高出220倍。

结论

  1. 我们提出了一个因果和全序通信抽象概念,1Pipe。
  2. 它以发送方的时钟时间顺序传递消息,并限制了故障原子性。
  3. 1Pipe利用可编程数据中心网络将聚合顺序信息与转发数据包分离,从而实现可扩展性和效率。
  4. 1Pipe可以简化和加速许多应用程序,我们希望未来的工作能够探索更多。
  5. 1Pipe的一个限制是它没有考虑Byzantine failure(拜占庭故障)

引言

缺少全序通信常常使分布式系统设计复杂化

 

图表 2

DCN中提供“一个大管道”抽象。如图1所示,消息分组发送并在虚拟管道中序列化,这使不同的接收方进程能够以一致的顺序从发送方进程传递消息。1Pipe类似于因果和全序的通信支持(CATOCS,Causally and Totally Ordered Communication Support):

(1)消息完全有序,确保以相同的顺序传递给所有接收方;

(2)按照Lamport逻辑时钟感知[2]中的因果序传递消息。

1Pipe还支持scattering,将多条消息分组以全序的方式发送给的不同接收方。与传统的多播不同,一个scattering消息中的每个消息都有不同的内容和目的地。用户不需要定义多播频道或组,因为网络是一个大型CATOCS信道。

1Pipe可以通过一次scattering实现分布式原子多对象读写,因为它们是在同一逻辑时间交付(发送)的。1Pipe中的复制需要一个往返时间(RTT)。1Pipe还提供了通信事件的全局顺序(全序),从而减少了隔离(fences),提高了分布式系统的并发性。

1Pipe似乎需要一个不可扩展的中央序列化点(central serialization point)。在这项工作中,我们提出了DCN中1Pipe的一种可扩展且高效的实现,其中拓扑结构是规则的(regular),交换机通常具有良好的可编程性。我们的原则是与底层DCN共同设计终端主机。我们同步主机上的时钟并确保它们非递减(non-decreasing)。发送方将相同的时间戳附加到单播消息或scattering消息中的每个数据包上。每个接收方以非递减的时间戳顺序传递消息

作为其核心,1Pipe将顺序信息的记录与消息转发分离开来。1Pipe像往常一样在网络中转发带时间戳的数据包,并在接收方对其进行缓冲。关键的挑战是让接收方知道低于某个时间戳的所有数据包都已到达。为此,我们在每个链路上引入一个屏障时间戳(barrier timestamp),它本质上是所有未来到达数据包的时间戳的下限。每个交换机聚合所有入口链路的屏障信息,以导出所有出口链路的屏障。通过这种方式,屏障在DAG(有向无环图)网络中随着分组转发而传播,并且接收方可以按顺序传递时间戳低于屏障的消息。如果某些主机或链路暂时空闲,我们会定期生成带有屏障信息的逐跳信标数据包(beacon packet)。

关于数据包丢失和故障,1Pipe提供了一种尽力而为的服务,其中丢失的消息不会被重新传输或者提供一种可靠的服务,在这种服务中,如果发送方和所有接收方都没有出现故障,则可以保证消息的传递。当主机或交换机发生故障时,可靠的1Pipe可确保有限的故障原子性(restricted failure atomicity):除非接收方发生永久性故障或网络分区发生故障,否则将发送scattering中的所有或none消息【理解成要不全传,要不全不传】。可靠的1Pipe使用两阶段提交(2PC)方法,第一阶段是端到端数据包丢失恢复,第二阶段通过网络聚合提交屏障(commit barrier)。它依靠高可用性网络控制器来协调故障处理,并允许应用程序通过回调自定义故障处理。可靠的1Pipe比尽力而为的1Pipe增加了一个往返时间(RTT)。我们将在第2.2节中展示,尽力而为的1Pipe可以实现复制和只读分布式原子操作,而无需可靠1Pipe的额外的RTT。

我们在具有不同编程功能的网络设备上实现了三种形式的1Pipe:可编程交换芯片(可支持灵活的有状态每包处理)、交换机CPU和主机CPU,以防交换机供应商不公开对交换机CPU的访问。

我们评估了32个服务器集群中的1Pipe,该集群有10个交换机和3层胖树拓扑。1Pipe实现了512个进程的线性可扩展吞吐量,每个进程每秒可发送500万条消息(每个主机每秒发送8000万条消息)。尽力而为的1Pipe总计10us消息传递延迟,而可靠的1Pipe总计为21us。1Pipe在丢包情况下具有强健的性能,并可在50~500us内从故障中恢复。1Pipe只需要0.3%的网络带宽开销和每个交换机一个CPU核心,用于周期性信标处理。

作为案例研究,首先,1Pipe在统一(uniform)和YCSB工作负载中对事务性键值存储(KVS)进行线性扩展,其吞吐量为非事务性系统(硬件限制)的90%,比FaRM高2~20倍,尤其是在高竞争条件下。1Pipe的延迟始终较低。第二,1Pipe在TPC-C基准中线性扩展,其性能比Lock和OCC高10倍。1Pipe的性能能够抵御数据包丢失。第三,通过移除围栏(fences)并使副本能够为读取服务,1Pipe将远程数据结构性能提高到2~4倍。最后,1Pipe将Ceph复制延迟降低了64%。

总之,本文的贡献是:

  1. 一个新的抽象1Pipe,它提供了因果和完全有序的单播和scattering,并提供了尽力而为和可靠的语义;
  2. 在DCN中设计和实现可扩展且高效的1Pipe;
  3. 1Pipe应用程序的设计和评估:事务性KVS、独立事务、远程数据结构和复制。

研究动机

Pipe的抽象模型

1Pipe在具有多个主机的分布式系统中提供了因果和完全有序(causally and totally ordered)的通信抽象,其中每个主机有多个进程。每个进程有两个角色:发送方和接收方。每个主机维护一个单调递增的时间戳,它表示时钟,并且在所有主机之间同步。消息由一个或多个数据包组成。当一个进程向不同的目标进程发送一组消息(即,scattering消息)时,所有消息包都用发送方主机的相同时间戳进行标记。与多播不同的是,目的地列表对于每个scattering都可能不同,其中发送给不同接收方的消息可以具有不同的内容。total order属性是:每个进程以非递减的时间戳顺序传递来自不同进程的消息。因果关系属性是:当接收方传递时间戳为T的消息时,主机的时间戳必须高于T。

 

图表 3

如表1所示,1Pipe提供了两种具有不同可靠性保证的服务:首先,onepipe_unreliable_send/recv是一种尽力而为的服务,其中可能存在数据包丢失。1Pipe通过在接收方缓冲消息并仅在接收到从网络聚合的屏障时间戳时发送消息来保证因果和全序属性。因此,尽力而为的1Pipe以0.5 RTT加上屏障等待时间传递消息。尽力而为的1Pipe通过端到端ACK检测丢失的数据包,但不重新传输数据包。现代数据中心通常具有较低的网络利用率,并部署高级拥塞控制机制。测量结果表明,pod内丢包率约为10E-5。在具有PFC的RDMA网络中,由于消除了拥塞丢包,数据包损坏率应低于10E-8符合IEEE 802.3标准,且链路损坏率高于10E-6被认为有故障。因此,数据中心应用程序可以假设尽力而为的1Pipe几乎是可靠的,但应该使用onepipe_send_fail_callback来检测由于数据包损坏或网络或远程进程故障而丢失的数据包。在这种情况下,丢包恢复取决于应用程序。【这里意思就是尽力而为的1pipe丢包率也可保证OK的丢包率】

第二,onepipe_reliable_send/recv是一种可靠的服务,除了排序之外,它还保证了可靠性:如果发送方进程、接收方进程和网络没有出现故障,则保证传递消息。它在数据包丢失的情况下重新传输数据包。在本文中,我们只考虑崩溃故障。当进程或网络出现故障时,消息传递会暂停。1Pipe从失败的进程中删除正在运行的消息。如果无法传递消息,则会对发送方调用发送失败回调。此外,每个进程可以通过onepipe_proc_fail_callback注册回调函数,以获取失败进程的通知。消息传递在所有非失败进程完成其回调函数后恢复。

可靠的1Pipe还提供了受限的故障原子性[3],这意味着scattering消息的全部或全部不传递,例外情况是,如果一个接收方在做出传递决定后永久性地发生故障或网络分区发生故障,则接收方永远无法传递该消息。如果一个接收方从故障中恢复,它可以与同一时间段内的其他接收方一致地传递或丢弃消息。事实上,在非复制故障停止模型中,完全故障原子性是不可能的,因为接收方或其网络链路在交付之前可能会永久故障,几乎与另一个接收方同时发送T。可靠的1Pipe通过两阶段提交和网络屏障聚合实现原子性,因此消息传递需要1.5 RTT加屏障等待时间。

在容错应用程序中,1Pipe在正常情况下提供了一条快速路径,并返回应用程序进行自定义故障处理。更具体地说,应用程序可以使用状态机复制来复制其状态,并注册一个调用传统一致性算法的onepipe_proc_fail_callback。每条消息scattering到所有副本。发生故障时,消息传递将暂停,1Pipe将在所有非故障进程中调用回调。受限故障原子性可确保所有正确的副本提供相同的消息序列。如果正确的副本达到仲裁,则回调将返回,并恢复消息传递。否则,会有太多失败的副本,应用程序可以在一致性和可用性之间进行选择。如果它选择一致性并等待某些副本恢复,则恢复的副本可以提供相同的消息序列。

1Pipe的使用案例

通信事件的全局顺序(全序)【消除了WAW和IRIW问题】

生产数据中心在两个节点之间提供多条路径。由于不同路径的不同延迟,可能会发生几类排序危害(图2)。

      

 

图表 4

写后写(WAW,write after write)。主机A将数据写入另一台主机O,然后向主机B发送通知。可以将发送视为写入操作。当B接收到通知后,它会向O发出一个“读取”命令,但由于A的写入操作延迟,可能无法获取数据。

独立读,独立写(IRIW)。主机A首先写入数据O1,然后写入元数据O2。同时主机B读取元数据O2,然后读取数据O1。有可能主机B从A中读取元数据但数据尚未更新。

排序危害(Ordering hazards)会影响系统性能。为避免WAW危害,在发送到B之前,A需要等待第一次写入操作完成(一个RTT到O,称为隔离/fence),从而增加了延迟。为了避免IRIW的危险,A需要等待写入O1在开始写入O2之前完成,及B需要等待在开始读取O2之前完成O1的读取。当需要按顺序访问更多远程对象时,围栏延迟将被放大。

由于因果关系和总体顺序,1Pipe可以消除WAW和IRW危害。在WAW情况下,通过主机时间戳的单调性,A->O排在A->B之前。由于因果关系,A->B排在B->O之前。因此A->O排在B->O之前。因此,写入操作在主机O上的读取操作之前进行处理,从而避免WAW危害。通过拆除A->0A->B之间的fence, 1Pipe在没有数据包丢失的情况下,将端到端延迟从2.5 RTT减少到1.5 RTT。

如果一个应用程序需要按顺序处理多个WAW任务,则1Pipe的功能会被放大。使用传统方法,应用程序在每个WAW任务期间需要1RTT的空闲等待,因此吞吐量限制为1/RTT。相反,使用1Pipe,应用程序可以在管道中发送相关消息。

上面的论点忽略了可能的数据包丢失。尽力而为的1Pipe,有一个小的可能性,A->0的消息在飞行中丢失,因此每个对象都需要维护一个版本,B需要检查O的版本。如果与来自A的通知消息中的版本不匹配,那么B需要等待A重传O,并重新通知B。A注册发送失败回调,并在A收到发送失败的通知情况下执行回滚恢复。

如果我们使用可靠的1Pipe,对象不再需要版本控制,但端到端延迟从2.5 RTT增加到3.5 RTT。然而,A仍然可以在管道中发送消息,并且具有比传统方式高得多的吞吐量。此外,可靠的1Pipe可以在故障情况下保持因果关系:如果A写入O失败,A->B的消息不会交付,类似于Isis。

同样,1Pipe消除了IRIW危害,并通过消除两个围栏将最小端到端延迟从3个RTT提高到1个RTT。当A和B同时启动读和写时,可获得最小时延。

1Pipe消除排序危害的能力来自其全序通信事件的能力。这种能力也与分布式共享内存(DSM)系统中的全存储顺序(TSO,total store ordering)内存模型完美匹配。在TSO中,每个处理器观察来自所有其他内核的写入的一致顺序。换句话说,处理器不会观察到WAW和IRIR危害。与较弱的内存模型相比,TSO减少了并发编程中的同步,从而简化了编程并减少了围栏开销。

RTT复制【序列号,校验和,少一个RTT】

复制对于容错至关重要。传统的多客户端复制需要2个RTT,因为客户端请求在发送到副本之前必须序列化(例如,发送到主服务器)。使用1Pipe,我们可以实现1-RTT复制,而无需假设日志内容,因为网络会序列化消息。客户机可以直接向具有scattering性的所有复制副本发送日志消息,每个复制副本根据时间戳排序日志(客户机ID会断开连接)。因为可靠的1Pipe有一个额外的RTT,所以我们使用可靠的1Pipe,并以更聪明的方式处理数据包丢失和故障。首先,为了确保在每对客户端和副本之间有序地传递日志,它们维护一个序列号。复制副本拒绝具有非连续序列号的消息。其次,为了检测由于数据包丢失而导致的不一致日志,每个复制副本维护来自所有客户端的所有以前日志消息的校验和。当复制副本接收到消息时,它会将消息时间戳添加到校验和中,并将校验和返回给客户端响应消息不需要由1Pipe排序。如果客户端从响应中看到所有校验和相等,则复制副本的日志至少在客户端的日志消息之前是一致的,并且客户端知道复制成功。否则,到某个复制副本的消息一定会丢失,或者客户端或复制副本出现故障。在数据包丢失的情况下,客户机只需重新传输第一条被拒绝的消息。在怀疑副本出现故障的情况下,客户端通知所有副本(或群集管理器)启动故障恢复协议,该协议使用传统的一致协议删除不一致的日志条目并使校验和匹配。当没有数据包丢失和失败时,复制只需要1个RTT。

与复制类似,1Pipe可以实现状态机复制(SMR)或虚拟同步。在基于SMR的分布式系统中,每个消息都广播到所有进程,每个进程使用相同的输入消息序列。SMR可以解决任意同步问题。互斥就是一个例子,它要求按照发出请求的顺序授予资源。通过可靠的1Pipe,使用SMR实现锁管理器可以解决互斥问题

分布式原子操作(DAO)【保持故障前状态?】

DAO是一个事务,它以原子方式读取或更新多个主机中的对象。DAO广泛用于事务性键值存储、web服务中的缓存、分布式内存计算和分布式存储的索引缓存。传统上,DAO需要3个RTT:(1)锁定对象;(2) 如果所有锁定成功,则向参与者发送操作;(3)解锁对象。使用可靠的1Pipe,DAO只是来自启动器的具有相同时间戳的scattering。每个接收进场按时间戳顺序处理来自所有DAO的消息。因此,DAO是可序列化的。如果接收方或网络永久失败,则无法观察到原子性冲突,因为任何后续操作都无法访问对象。

作为一种优化,我们可以对只读DAO使用不可靠的1Pipe,因为如果由于数据包丢失而失败,启动器可以重试。根据SNOW和NOCS定理,1Pipe提供了1-RTT只读DAO,具有严格的可串行性,无存储开销,接近最佳吞吐量,但在接收到屏障时间戳之前以阻塞操作为代价。

其他情况【全局同步可以使用本地时间】

在具有不透明性的一般事务中,为了获得读写时间戳,事务需要查询不可扩展的集中式定序器或等待时钟不确定性(例如,Spanner等待~10ms,FaRMv2等待~20us)。1Pipe可以直接使用本地时间作为事务时间戳,而无需等待,因为以前事务的锁消息必须在当前事务的数据访问之前传递到碎片/shards。

1Pipe时间戳也是一个全局同步点。例如,为了获取一致的分布式快照,启动器广播带有时间戳T的消息到所有进程,指示所有进程以高于T的时间戳记录其本地状态和正在发送的消息。

背景        

数据中心网络

数据中心网络(DCN)的独特特性使1Pipe的可扩展和高效实现成为可能

现代数据中心通常采用多根树拓扑来互连数十万台主机。在多根树拓扑中,两台主机之间的最短路径首先到达最低的公共祖先交换机之一,然后到达目标。因此,路由拓扑形成一个有向无环图(DAG),如图3所示。这种无环拓扑支持屏障时间戳的分层聚合

 

图表 5

高可用性SDN控制器在管理平面上运行,以检测交换机和链路的故障,然后在故障时重新配置路由表。

可编程交换机

数据中心交换机由一个交换芯片和一个CPU组成(图4)。交换机操作系统在CPU上运行,以重新配置交换机芯片。交换芯片通过虚拟NIC将所选流量(通常是控制平面流量,例如DHCP和BGP)转发给CPU。

 

图表 6

交换芯片由一个入口管道、多个FIFO队列和一个出口管道组成。当从输入链路接收到数据包时,它首先通过入口管道确定输出链路和排队优先级,然后放入相应的FIFO队列。出口管道根据优先级从队列中提取数据包,应用报头修改并将其发送到输出链路。交换机的一个关键特性是,排队模型确保具有相同优先级、入口端口和出口端口的数据包具有FIFO特性。

该交换机具有良好的可编程性。首先,CPU可用于处理(少量)数据包。其次,近年来,交换机芯片越来越可编程。例如,Tofino芯片支持灵活的数据包解析器和有状态寄存器。用户可以使用P4对Tofino进行编程,以实现定制的每包有状态处理。

尽管具有良好的可编程性,交换机通常具有有限的缓冲区资源来容纳数据包。每个端口数据包缓冲区的平均大小通常为数百KB。因此,在数据中心的交换机上缓冲许多数据包是一项挑战

尽力而为的1Pipe【提供全局顺序(全序)、因果和FIFO消息传递

消息和屏障时间戳【本文核心工作原理】

但不重新传输丢失的数据包,也不提供原子性。实现这一点的一种简单方法是使用一个集中式定序器对所有消息进行排序,这将是一个瓶颈。相反,我们将介绍如何在常规DCN拓扑中实现可扩展排序。

消息时间戳。1Pipe发送方为每条消息分配一个非递减时间戳。scattering中的消息具有相同的时间戳。鉴于最近在这方面的努力数据中心的us级精确时钟同步,我们同步主机的单调时间,并使用本地时钟时间作为消息时间戳。时钟偏移会减慢交付速度,但不会影响正确性。消息时间戳确定接收方的分发顺序。接收方按照时间戳的升序分发到达消息(通过发送方ID断开联系)。

屏障时间戳/Barrier timestamp当接收方传递带有时间戳T的消息时,它必须确保它已经接收并发送了时间戳小于T的所有消息。一种简单的方法是只传递具有非递减时间戳的消息,并丢弃所有无序消息。然而,由于不同的网络路径具有不同的传播和排队延迟,这种方法将丢弃太多的消息,例如,在我们的实验中,有57%的接收消息是无序的,其中8个主机向一个接收方发送消息。为此,我们引入了屏障时间戳的概念。屏障时间戳与路由图中的链路或节点(即交换机或终端主机)相关联。屏障时间戳是来自链路或节点的所有未来到达消息的消息时间戳的下限。每个接收方维护自己的屏障时间戳,并传递时间戳小于屏障时间戳的消息。

如果发送方和接收方之间的传输是FIFO,那么接收方可以很容易地找出来自所有发送方的消息的屏障:屏障是来自所有发送方的最新消息的最小时间戳。因此,一个简单的解决方案是每个发送者向每个接收方发送带有时间戳的消息,以便接收方能够找出屏障并传递消息。不幸的是,此解决方案需要向不在scattering组中的接收方发送消息,因为scattering组不可扩展。

分层屏障时间戳聚合。1Pipe利用了网络排队结构的知识,使得下限聚合比仅在逻辑级别实现时更具可扩展性和效率。1Pipe利用可编程交换机聚合屏障时间戳信息。由于交换机缓冲区资源有限,1Pipe不会对网络中的消息重新排序。相反,1Pipe会像往常一样在网络中转发消息,但会根据交换机提供的屏障时间戳信息在接收方对消息进行重新排序

在1Pipe中,我们为每个消息包附加两个时间戳字段。第一个是消息时间戳字段,由发送方设置,不会修改。第二个字段是屏障时间戳,它由发送方初始化,但将由网络路径上的交换机修改

屏障时间戳字段的属性为:

当交换机或主机从网络链接L收到带有屏障时间戳B的数据包时,它表明来自链路L的未来到达数据包的消息时间戳和屏障时间戳将大于B。

为了推导屏障,发送方使用非递减消息时间戳初始化消息中所有数据包的两个字段。

 

使用(4.1),每个交换机根据所有输入链路独立地导出屏障时间戳。如图5所示,屏障时间戳通过交换机逐跳分层聚合,最终接收方获得网络中所有可访问主机和链路的屏障。鉴于每个网络链路的FIFO特性,该算法保持了屏障时间戳的特性。

 

图表 7

当接收方接收到带有屏障时间戳B的数据包时, 它首先在优先级队列中缓冲数据包,该队列根据消息时间戳对数据包进行排序。接收方知道所有未来到达数据包的消息时间戳将大于B. 因此,它交付了所有带有低于消息时间戳B的缓冲数据包给应用进行处理。如果一个进程收到一条时间戳在B上面的消息, 它将被丢弃,并将NAK消息返回给发送方。因此,如果链路或交换机不是严格意义上的FIFO,无序消息将不会违反正确性。请注意,屏障聚合仅依赖于逐跳FIFO链接,而不是FIFO端到端传输。因此,1Pipe可以与多种多路径路由方案配合使用。

因果关系。为了在Lamport逻辑时钟检测中保持因果序,本地时钟时间应高于交付的时间戳。时间戳聚合暗示了这一点,因为每个进程都有两个发送方S和接收方R角色和屏障T被R收到,并从所有发送方聚合,包括S。因为本地时钟是单调的,当R收到屏障时间T时,S的时间戳大于T.

空闲链路上的信标【发送信标来更新时间戳】

如前所示,在每一跳,每个分组屏障时间戳被更新为所有可能输入链路的最小屏障时间戳值。因此,空闲链路会暂停屏障时间戳,从而限制整个系统。为了避免空闲链接,我们定期在每个链接上发送信标

什么是信标?与消息包不同,信标包只携带屏障时间戳字段,没有有效载荷数据。

如何发送信标?我们在每个空闲链路的基础上发送信标数据包。信标数据包可以由主机和交换机发送,但目的地必须是其单跳邻居。此逐跳属性确保信标开销与网络规模无关。对于主机生成的信标,屏障时间戳是主机时钟时间。对于交换机生成的信标,屏障时间戳根据(第4.1节)进行初始化。

何时发送信标?我们引入一个信标间隔Tbeacon.

当主机或交换机输出链路Tbeacon时间未观察到任何消息包时,然后,它生成一个信标数据包。我们应该选择一个合适的Tbeacon以平衡带宽开销和系统延迟。信标在不同主机上同步发送,因此当网络延迟相同时,交换机几乎同时接收信标。如果信标是随机发送的,交换机必须等待最后一个信标的到来,这将使消息的预期延迟增加近一个信标间隔。对于同步信标,预期的延迟开销仅为信标间隔的一半。

处理故障。当主机、链路或交换机发生故障时,其邻居的屏障时间戳停止增加。为了检测故障,每个交换机在每个输入链路上都有一个超时计时器。如果超时(例如10个信标间隔)未收到信标或数据包,则输入链路被视为已失效,并从输入链路列表中删除。移除故障链路后,屏障时间戳恢复增加。这种故障处理机制是分布式的。

添加新主机和链接。对于新主机,它将时钟与时间主机同步。在主机和交换机之间或两个交换机之间添加链路时,因为交换机必须保持Bnew的单调性,它将暂停对Bnew的更新,直到从新链路接收到的屏障大于Bnew.

可靠的1Pipe【处理数据包丢失和故障】

处理数据包丢失【两阶段提交,时间戳聚合】

当接收方发送带有时间戳T的消息时, 它必须确保低于T的所有消息我们已经传递了。因此,如果接收方不知道数据包丢失,它就不能根据屏障时间戳可靠地传递消息。即使交换机能够检测丢失的数据包,仍然存在问题。例如,主机A发送到B,然后通过不同的路径发送到C。三个事件按照以下顺序发生:A->B丢包了;A->C到达;A故障了。在这种情况下,A->C交付,而A->B无法恢复。未能交付A->B以及A->C违反可靠的排序属性。

 

图表 8

我们处理数据包丢失的关键思想是两阶段提交(2PC)方法:

准备阶段:发送方将消息放入发送缓冲区,并使用时间戳进行传输。路径上的交换机不会聚合数据包的时间戳屏障。接收方将消息存储在接收缓冲区中,并使用ACK进行回复。发送方使用ACK来检测和恢复数据包丢失

提交阶段:发送方收集时间戳小于或等于T的数据包的ACK报文,它发送一个带有提交屏障(commit barrier)T的提交消息(commit message)。提交消息被发送到邻居交换机而不是接收方,如图6中的红色箭头所示。每个交换机聚合输入链接上的最小提交屏障,并生成传播到输出链接的提交屏障。此时间戳聚合过程与第4.1节完全相同。当接收到提交屏障T时接收方在接收缓冲区中传递的消息低于或等于T.与尽力而为的1Pipe类似,提交消息也需要在空闲链路上定期发送信标。

处理故障【故障时间戳,丢弃,召回】

与第4.2节类似,组件的崩溃故障由其邻居使用超时检测出来。但是,不能简单地删除故障组件,否则,无法一致地传递或丢弃故障组件发送的传送中消息。

为了在第2.1节中实现受限故障原子性,我们使用数据中心的网络控制器通过信标超时检测故障。控制器本身是使用Paxos或Raft复制的,因此,它是高度可用的,并且在任何时候只有一个控制器处于活动状态。控制器需要确定哪些进程失败以及何时失败。前一个问题更容易回答。在路由图中与控制器断开连接的进程被视为失败。例如,如果主机出现故障,则该主机上的所有进程都将被视为失败。如果机架顶部(ToR)交换机出现故障,并且机架中的主机仅连接到一个交换机,则机架中的所有进程都会出现故障。

当进程失败时,后一个问题更难回答。挑战在于我们无法可靠地确定处理的最后提交和最后交付的时间戳。因为从提交时间戳到将时间戳交付给接收方存在传播延迟,所以可以找到时间戳T是由失败的进程P提交的,但不会传播到任何接收方,因此所有接收方都已从P收到T之前的在接收缓冲区中(因此可以传递它们)的消息,但T之后没有消息被交付,因此可以丢弃。P的故障时间戳(Failure timestamp)是这样定义的,它被计算为P的所有邻居报告的最大最后提交时间戳。如果同时发生多个故障,我们将尝试在路由图中找到一组正确的节点,将故障节点和所有正确的接收方分开。如果由于网络划分而找不到这样一个集合,那么我们使用贪婪算法来找到一个集合,以尽可能多地分离接收方。不可分离的接收方牺牲原子性,因为一些消息可能在T之后已经交付了。

 

处理故障的过程如下,如图7所示:(正确性分析见附录)

  1. 检测/Detect:故障组件的邻居通知控制器及其最后提交时间戳T.
  2. 确定/Determine:控制器根据路由图确定故障进程及其故障时间戳。
  3. 广播/Broadcast:控制器广播失败的进程P以及它的失败时间戳T给所有正确的过程。
  4. 丢弃/Discard:每个正确的进程丢弃从P在接收缓冲区中收到的高于T时间戳的消息。
  5. 召回/Recall:每个正确的流程都会丢弃在发送缓冲区中发送给P的消息,这些消息正在等待来自P的ACK。如果丢弃的消息处于scattering状态,则根据故障原子性,需要中止scattering,即需要召回发送给同一scattering状态中其他接收方的消息。发送方向此类接收方发送召回消息,然后每个接收方丢弃接收缓冲区中的消息并向发送方响应ACK。发送方在收集确认后完成召回。
  6. 回调/Callback:每个正确的进程执行表1中注册的进程故障回调,这使应用程序能够自定义故障处理。然后,它用完成消息响应控制器。
  7. 恢复/Resume:控制器从所有正确的进程收集完成,然后通知网络组件从故障组件移除输入链路,从而恢复屏障传播(barrier propagation)。

控制器转发。如果网络故障影响到S及R之间的连接性, 2PC中的提交阶段和故障处理中的召回步骤可能会暂停,因为S会重复重新传输消息,但无法从R接收ACK。在这种情况下,,S要求控制器将消息转发到R, 并等待来自控制器的确认。如果控制器也无法传递消息,R将被宣布为失败,并记录无法送达的召回消息。如果控制器收到召回消息的确认,但无法将其转发给S, S将被宣布为失败。总之,若进程在超时时间内未响应控制器,则视为失败。

接收方恢复。如果进程从故障中恢复,例如网络链路或交换机恢复,则该进程需要一致地在接收缓冲区中传递或丢弃消息。控制器将自己的故障通知进程。然后,进程与控制器联系以获取主机故障通知,因为它有故障和无法传递的回调消息。传递缓冲消息后,恢复的进程需要将1Pipe作为新进程加入。这是因为如果一个进程可以多次失败和恢复,控制器将需要记录所有失败和恢复时间戳,从而增加复杂性。

局限性:如果某个进程永久失败,则无法确切知道它所传递的最后一个时间戳,因此,1Pipe只能确保所有正确的接收方和恢复的接收方一致地传递消息。此外,当发生网络分区时,分离的接收方可能会在故障时间戳之后发送消息。1Pipe依赖应用程序来协调此类故障。

实现

终端主机上的处理【lib1pipe,报文设置,轮询机制】

我们在终端主机上实现了一个1Pipe库lib1pipe。该库构建在RDMA verbs API之上。1Pipe从CPU周期计数器获取时间戳,并将其分配给软件中的消息。由于RDMA RC在不同的QP中缓冲消息,我们无法确保NIC到ToR链路上的时间戳单调性。理想情况下,我们希望使用SmartNIC并在数据包出口到端口时将时间戳附加到数据包。然而,因为我们只能访问标准的RDMA NIC,所以我们使用RDMA UD【面向连接 不可靠服务】。每个1Pipe消息被分割成一个或多个UD数据包

1Pipe在软件中实现端到端流量和拥塞控制。当第一次访问目标进程时,它与源进程建立连接,并为其提供接收缓冲区,其大小为接收窗口。数据包序列号(PSN)用于丢包检测和碎片整理。拥塞控制使用DCTCP,其中ECN标记位于UD报头中。当应用程序发送scattering时,它存储在发送缓冲区中。如果发送缓冲区已满,则发送API返回失败。每个目的地都维护一个发送窗口,该窗口是接收窗口和拥塞窗口中的最小窗口。当发送缓冲区中scattering的所有消息都在相应目的地的发送窗口内时,它们将附加当前时间戳并发送出去。这意味着,当scattering的某些目的地或网络路径拥挤时,它会被保留在发送缓冲区中,而不是降低整个网络的速度。为了避免活锁,scattering从发送窗口获取“信用/credit”。如果目的地的发送窗口不足,则在等待队列中保留scattering,而不释放信用。这确保了最终可以发送大量scattering,但代价是浪费了可用于发送其他无序scattering的信用。信标数据包被发送到ToR交换机,并且它们不会被流量控制阻塞。

1Pipe中的UD数据包添加24字节的头:3个时间戳,包括消息、最大努力屏障(best-effort barrier)和提交屏障;PSN;一个操作码和一个标记消息结束的标志。时间戳是48位整数,指示主机上传递的纳秒数。我们使用PAWS来处理时间戳环绕。

lib1pipe初始化时,它向控制器注册并生成一个轮询线程:(1)生成周期性信标数据包; (2)轮询RDMA完成队列并处理接收到的数据包,包括生成端到端ACK和重新传输丢失的数据包; (3)对接收缓冲区中的消息重新排序,并将其传递给应用程序线程。lib1pipe使用轮询而不是中断,因为RDMA RTT仅为1~2us,而中断会增加~10us延迟时间。

主机内的进程直接暴露于机架顶部(ToR)交换机,ToR聚合机架中所有进程的时间戳。在未来的工作中,可以将lib1pipe的软件过程卸载到可编程NIC,该NIC为出口管道上的消息分配时间戳。

控制器是一个复制服务,它将路由图、进程信息、故障通知和无法送达的回调消息存储在etcd中。在大型网络中,未来的工作可以将控制器分配到集群,每个集群都服务于网络的一部分。

网内处理(In-Network Processing)【三种应用环境】

我们在三种具有不同编程能力的网络交换机上实现网内处理。

可编程交换机芯片。我们使用P4实现了网内处理,并将其编译为Tofino。由于Tofino交换机有4条管道,因此它被视为4个入口和4个出口交换机,通过16条all-to-all链路连接。8个“交换机”中的每一个都独立地引出屏障/barriers。1Pipe每个输入链路需要2个状态寄存器分别存储两个屏障,以实现尽力而为和可靠的1Pipe。对于每个数据包,在交换机的第一个有状态管道阶段更新输入链路的屏障寄存器。

因为每个阶段只能计算两个屏障中的最小值,所以交换机使用具有O(log N)管道阶段的寄存器二叉树(binary tree)来计算最小连接屏障B_{new},这里N是端口数。对于一个典型的32端口交换机,16个入口阶段中需要5个阶段。在最后的管道阶段,数据包中的屏障字段更新为B_{new}。控制平面软件定期检查链路屏障,如果链路屏障明显落后,则报告故障。当链路被充分利用时,尽力而为的1Pipe的预期延迟为(基本延迟+时钟偏移),或当大多数链路空闲时(基本延迟+信标间隔/2+时钟偏移)。

交换机CPU。对于没有可编程交换芯片的交换机,例如使用Broadcom Tomahawk芯片的Arista 7060,我们在交换机CPU上实现网络处理。尽管商品交换机不能在数据平面处理数据包,但它们有一个CPU来处理控制平面数据包,这类似于将服务器直接连接到交换机的端口。与服务器CPU和NIC相比,交换机CPU的功能通常较低(例如,1 GHz的4核),带宽较低(例如,1 Gbps)。由于交换CPU不能处理每个数据包,因此数据包直接由交换芯片转发。CPU在每个输出链路上周期性地发送信标,而不管链路是空闲的还是繁忙的。信标中接收到的屏障存储在每个输入链路的寄存器中。CPU上的线程定期计算链路屏障的最小值,并向所有输出链路广播新的信标。计算最小屏障需要数百个周期,与广播成本相比,这不是一个瓶颈。因为数据和信标数据包在交换机队列和网络链路上是FIFO,所以屏障属性被保留。在接收方上,根据信标数据包中的屏障将缓冲数据包传送到应用程序。与可编程芯片相比,由于CPU的处理,交换机CPU具有更高的延迟。因此,预期延迟为基本延迟+(交换机CPU处理延迟×跳数+信标间隔/2+时钟偏移)。

将交换机处理委托给主机。如果交换机供应商不向交换机CPU公开访问接口,我们可以将信标处理卸载到终端主机。我们为每个网络交换机指定一个终端主机代表。挑战在于尽力而为的1Pipe要求屏障时间戳是网络链路L上未来消息时间戳的下限。所以,L上带有屏障时间戳的信标必须通过L。也就是说,对于两个直接连接的交换机S1,S2及其代表H1,H2,来自H1至H2的信标数据包需要通过链接  。如果两名代表之间的路由路径未通过  ,信标数据包需要绕道:它们以三层IP报头发送:  ,  及  。我们在每个网络交换机中安装隧道终止规则,以对一层IP报头进行解封,从而信标数据包将穿越  。

信标数据包使用单边RDMA写入来更新代表主机上的屏障。与第6.2.2节类似,定期计算最小屏障并向下游代表广播。预期延迟为基本延迟+((交换机和主机之间的RTT+主机处理延迟)×跳数+信标间隔/2+时钟偏移)。由于终端主机上的CPU的处理延迟(通过RDMA)可能比交换机CPU的处理延迟(通过OS IP堆栈)更短,因此主机委派的总延迟可能更短。这就是为什么我们在第7节中使用主机委托进行评估。


评价

方法【实验配置】

我们的测试平台有10台Arista 7060CX-32S 100G交换机和32台服务器,形成了一个类似于图3的3层胖树拓扑(4个ToR、4个Spine和2个Core)。

 

网络没有过度订阅,因为我们的流量模式是all-to-all的。每台服务器都有2个Xeon E5-2650 v2 CPU和一个运行RoCEv2的Mellanox ConnectX-4 NIC。我们专门使用一个CPU内核作为每个交换机和NIC的代表来处理信标(第6.2.3节)。主机代表直接连接到交换机,因此信标数据包不需要绕道。对于第7.2节中的微基准,我们使用Tofino交换机代替Arista交换机。在小规模实验中(1~32个进程),每个进程在不同的服务器上运行。每个进程分别使用一对线程进行发送和接收。对于少于或等于8台服务器,它们在一个机架中共存。有16台服务器,它们位于一排两个机架中。用于64的实验~512个进程,每个服务器承载相同数量的进程。时钟通过PTP每125毫秒同步一次,平均时钟偏差为0.3us(95分位为1.0us),这与Mellanox的白皮书一致。我们选择信标间隔为3us

微基准【可扩展性,消息传递延迟,故障恢复,CPU开销,网络开销,可扩展到更大的网络】

可扩展性。1Pipe可实现全序广播。图8a将1Pipe的可扩展性与使用令牌、Lamport时间戳和主机NIC上的集中式定序器或可编程交换机的其他全序广播方法进行了比较。我们测试了一种all-to-all流量模式,其中每个进程向所有进程广播64字节的消息。1Pipe可线性扩展到512个进程,每个进程每秒可发送500万条消息(即每个主机每秒发送8000万条消息)。1Pipe的吞吐量受CPU处理和RDMA消息传递速率的限制。由于2PC开销,可靠的1Pipe(1Pipe/R)的吞吐量比尽力而为的1Pipe(1Pipe/BE)低25%。可编程芯片和主机代表(未显示)提供相同的高吞吐量,因为1Pipe将消息转发与屏障传播分离。

 

相比之下,定序器是一个中心瓶颈,它为绕行数据包引入了额外的网络延迟(图8b)。当定序器的吞吐量达到饱和并出现拥塞时,延迟会急剧上升。令牌的吞吐量较低,因为在任何时候只有一个进程可以发送。我们对Lamport时间戳应用了一个常见的优化,它按间隔而不是按消息交换接收到的时间戳。它在延迟和吞吐量之间进行权衡,例如,对于512个进程,即使50%的吞吐量用于时间戳交换,广播消息也需要200us。

 

消息传递延迟。图9a显示了系统空闲时1Pipe的消息传递延迟,因此排队延迟为零。与无序基线相比,带有可编程芯片的1Pipe/BE提供了最低的延迟开销。平均开销(1.7~2.3us)对于不同的网络层和进程数几乎是常数,即信标间隔的一半加上平均时钟偏移。尾部延迟开销(1.7~3.3us),是信标间隔的一半加上最大时钟偏移。终端主机代表引入了从交换机到终端主机的额外转发延迟,即~2us和贡献10us的5-hop拓扑。在我们的试验台上,≤8、16和≥32个进程分别有1、3和5跳。可靠的1Pipe增加了一个RTT(2~10us),这是由于2PC中尽力而为的准备阶段。RTT和主机转发延迟与网络跳数成正比。

如第2.1节所述,链路的丢包率通常低于10E-8,但故障链路的丢包率可能高于10E-6。在图9b中,我们模拟了lib1pipe接收方中的随机消息丢弃,以评估数据包丢失对512个进程的测试台延迟的影响。当损失率大于10E-5,1Pipe的延迟开始增长。在BE-1Pipe和R-1Pipe中,任何链路上丢失的信标数据包将暂停屏障的传送,直到下一个信标,所有接收方都需要等待最差链路。在R-1Pipe中,准备阶段丢失的消息将触发重新传输,这将使网络暂停一个RTT(如果重新传输丢失,可能会有多个RTT)。因此,R-1Pipe对数据包丢失更为敏感。数据包丢失对吞吐量几乎没有影响,因为1Pipe可以在重新传输丢失数据包的同时传输新消息。

 

 

除了数据包丢失,后台流量引起的排队延迟也会增加1Pipe延迟。如图12a所示,对于每个主机10个后台TCP流,BE-1Pipe和R-1Pipe的延迟膨胀分别为30和50us。更高的超额订阅率也会由于网络核心的缓冲增加而增加延迟。在图12b中,我们增加了网络的超额预订率,并且由于核心网络中的拥塞和PFC暂停,延迟增加。我们相信更先进的拥塞控制机制可以缓解这个问题。

比MTU大得多的消息将暂停其他消息,例如,1 MB的消息将增加80us其他消息的延迟。

 

故障恢复。在大多数应用程序中,1Pipe中的故障检测通常比心跳超时快,因为1Pipe中的信标间隔非常低。图10描述了故障恢复时间,它测量了正确进程的屏障时间戳暂停的平均时间。在我们的测试平台中,如果10个信标间隔(30us)内未接收到信标,则会检测到故障)。除了故障检测时间外,第5节中的恢复过程还需要6个网络直径加上传输和处理消息的时间。核心链路和交换机故障不会影响连接性,因此,只需涉及控制器,不认为任何流程发生故障。主机、NIC、主机链路和ToR交换机故障会导致进程断开与系统的连接,因此恢复需要更长的时间,因为每个正确的进程都需要丢弃来自或发往它们的消息。ToR交换机有一个显著的跳跃,因为机架中的所有进程都发生故障,导致更多的故障恢复消息。

 

 

CPU开销。1Pipe的CPU开销分为两部分:接收方处的重新排序和交换机处的信标处理。随着需要重新排序的消息增多,消息传递吞吐量略有下降。如图11所示,最大发送和接收缓冲区大小随延迟线性增加,但在100 Gbps链路上只需要几兆字节。

 

 

图13a显示了32端口交换机信标处理所需的内核数量。一个主机CPU核心可以支持3us交换机的信标间隔,这是我们的测试台设置。如果改用交换机CPU,交换机CPU的原始数据包处理能力约为主机CPU内核的1/3。如果我们能够绕过内核网络堆栈,在Arista交换机上高效地处理数据包,那么一个交换机CPU内核就可以支持10us信标间隔。

网络开销。如图13b所示,具有高链路带宽和合理的信标间隔(例如,3us),信标流量是链路带宽的一小部分(例如,0.3%)。因为信标是逐跳的,所以开销由信标间隔决定,并且不会随着系统规模的增加而增加

可扩展到更大的网络。从延迟角度来看,基本和信标处理延迟与网络中的跳数成正比,通常与主机数成对数关系。由于主时钟和主机之间的延迟更高,以及高漂移率下坏时钟的概率更高,因此时钟偏移增加。我们还没有定量分析时钟偏差。对于可靠的1Pipe,RTT中预期的数据包丢失数与主机数乘以跳数成正比。对于32K主机,如果所有链路都正常(丢包率为  ),延迟与无损失相比增加0~3us;如果所有链路都处于亚健康状态(丢包率为  ),潜伏期增加3~17us从吞吐量的角度来看,信标开销与网络规模无关,而主机将使用更大的内存和更多的CPU周期来重新排序消息。内存大小是BDP(带宽延迟积),重排序时间是BDP的对数。

主要的可扩展性挑战是故障处理。任何组件的故障都会使整个网络停止运行。尽力而为1Pipe,故障处理是本地化的,因为故障组件在30us内与超时一样被邻近区域移除,网络的其余部分也会经历传递延迟膨胀。虽然这种膨胀的延迟是固定的,但发生频率与网络规模成正比。在可靠的1Pipe中,故障处理由一个集中控制器协调,该控制器需要联系系统中的所有进程,因此,故障恢复延迟随系统规模成比例增加,即每个主机3~15us。

应用

事务性键值存储。

我们评估了一个分布式事务键值存储,每个服务器进程使用不复制的C++ std::unordered_map,将一部分KVS存储在内存中。事务(TXN)由多个独立的KV读或写操作组成。TXN启动器通过key哈希将KV操作分派给服务器进程。只读(RO)TXN由尽力1Pipe提供服务,而读写(WR)和写式(WO)TXN使用可靠的1Pipe。为了进行比较,我们实现了非复制和非持久FaRM,它通过读取KV并检查锁和版本,在1个RTT中为RO TXN提供服务。FaRM使用的WR和WO TXN OCC和两阶段提交。作为一个理论性能上限,我们还与非事务系统进行了比较。

默认情况下,每个TXN都有2个KV ops,其中每个ops随机选择读写。Key是统一随机或通过YCSB中的Zipf分布生成的64位整数。YCSB有热键。值大小是根据Facebook的ETC工作负载随机生成的。我们记录了95%峰值吞吐量时的平均TXN延迟。

 

在图14a中,50%的TXN是只读的。在均匀分布和YCSB分布中,1Pipe提供可扩展的吞吐量(每个进程的吞吐量不会降低),这是非事务性键值存储(NonTX)的90%。随着进程数量的增加,YCSB的扩展并不像均匀分布的那样线性,因为热键上的争用导致不同服务器的负载不平衡。对于512个进程,YCSB在1Pipe和NonTX上都有70%的统一吞吐量。在无争用的统一工作负载中,FaRM提供1Pipe50%的吞吐量,因为WR和WO TXN需要3或4个RTT。在YCSB工作负载中,FaRM不能扩展,因为它在WO/WR TXN提交期间锁定2个RTT的key,并且热键会阻止所有冲突的TXN。相反,1Pipe不会锁定钥匙。每台服务器按顺序处理同一key上的TXN。

在图14b中,我们调整了写入操作的百分比,并测量了带有512个进程的RO、WO和WR TXN的延迟。1Pipe的延迟几乎是恒定的,因为服务器按顺序处理同一key上的读写操作。WO和WR使用可靠的1Pipe,比使用尽力1Pipe的RO慢。对于纯RO工作负载,FaRM的延迟低于1Pipe,因为它在1RTT中完成,并且不等待网络范围的重新排序。非竞争FaRM WO和WR分别消耗3个和4个RTT,略低于1Pipe。然而,由于写入百分比较高,FaRM延迟会因热键上的锁争用而急剧上升,而TXN会因读取版本不一致而中止。

在图14c中,我们改变了每个TXN的key数,并测量了512个进程的总KV op/s。95%的TXN是只读的。1Pipe和NonTX与TXN大小无关,因为它们的吞吐量仅受CPU处理和网络消息传递速率的限制。在写入百分比较低(5%)的情况下,FaRM/YCSB提供了40%的1Pipe吞吐量,每个TXN具有2 KV ops,但随着TXN大小的增大,性能会急剧下降,因为TXN中止率会随着TXN中的key数的增加而增加。

独立的一般事务。

现在,我们将分布式原子操作(DAO,第2.2.3节)扩展到两类重要的分布式事务:只读快照事务和独立事务(或称为一次性事务),它们涉及多个主机,但每个主机的输入不依赖于其他主机的输出。TPC-C基准(新订单和支付)中最频繁的两个交易是独立交易。DAO和独立事务之间的主要区别在于后者通常需要复制以确保持久性和容错性。TXN启动器使用Eris的方法,该方法在一次可靠scattering中将操作scattering到所有碎片的所有副本。因此,每个TXN可以在一个往返过程中完成(实际上,由于准备阶段,有两个RTT)。如果一台主机出现故障,同一碎片的其他副本将通过传统协商一致方式达到仲裁。

 

我们在TPC-C中对新订单和付款TXN进行了基准测试,这占TPC-C工作量的90%。为了简单起见,我们没有在TPC-C中实现非独立TXN,这应该回到传统的并发控制机制。我们使用4个仓库,存储在内存中,其中包含3个副本。并发控制和复制是通过scattering发送到所有碎片和副本的命令来实现的,类似于Eris,但用时间戳替换了它的中央定序器。我们假设TXN从未中止。如图15a所示,两阶段锁定(2PL)和OCC不可扩展,因为每个付款TXN更新其相应的仓库条目,并且每个新订单读取该条目,导致4个热条目(hot entries)。OCC和2PL的吞吐量分别在256和64个进程时达到峰值。进程越多,吞吐量就越低。相反,1Pipe与进程数成线性比例。通过512个进程,1Pipe每秒可实现1035万个TXN,相当于非事务基线系统的71%,10倍的锁和17倍的OCC。

图15b显示了不同模拟丢包率下的TXN吞吐量。我们将进程号固定为64。对于1Pipe,尽管数据包丢失会影响TXN延迟(在TPC-C中未测量,但应类似于图9b),但对吞吐量的影响是微不足道的。然而,在2PL和OCC提交中,锁定对象在TXN完成之前无法释放,因此,争用下的TXN吞吐量与TXN延迟成反比。TXN延迟随着数据包丢包率的增加而增加,因为副本会等待最后一个重新传输的数据包来维持顺序日志顺序。

最后,我们通过断开主机的物理链路来评估副本的故障恢复。1Pipe检测到故障并在181±21us内删除副本。受影响的TXN被中止并重试,平均延迟为308±122us,它比使用应用程序心跳检测故障要快得多,这需要毫秒。链路重新连接后,副本将在25毫秒内同步来自其他副本的日志。

远程数据结构。

1Pipe可以消除远程数据结构访问中的排序危害(第2.2.1节)。我们实现了一个分布式并发哈希表,它使用链表将键值对(kv)存储在同一个哈希桶中。哈希表在16台服务器上分片。与服务器处理KV ops的第7.3.1节不同,在本节中,客户端使用RDMA单边读、写和CAS访问远程哈希表。基线系统使用引导-跟随复制(leader-follower replication)。该工作负载有16个并行客户端和统一密钥/keys。

 

如图16所示,在没有复制的情况下,1Pipe将逐客户端 KV插入吞吐量提高到1.9倍,因为1Pipe消除了写入KV对和更新哈希桶中指针之间的隔离。由于额外的重新排序延迟,KV查找吞吐量减少了10%。如果哈希表进行传统方式地复制,则会向leader发送一个write op,这涉及到要复制到follower的CPU软件。使用3个副本,1Pipe将KV插入吞吐量提高到3.4倍。在1Pipe中,所有KV操作都是按时间戳排序的,因此所有副本都可以服务于查找请求,并且吞吐量随着副本数量的增加而增加。相比之下,使用leader-follower复制,为了保持查找和更新的可序列化性,只有leader可以提供查找服务。

分布式存储中的复制

我们将1Pipe应用于分布式存储系统,Ceph。Ceph OSD使用主备复制方案,其中备份也按顺序写入。对于3个副本,客户端依次等待3次磁盘写入和6次网络消息(3个RTT)。由于1Pipe在非故障情况下支持1-RTT复制(第2.2.2节),因此客户端可以并行写入3个副本,因此端到端写入延迟减少为1个磁盘写入和1个RTT。实验表明,在采用Intel DC S3700 SSD的空闲系统中,4KB随机写入延迟从160±54us降低至58±28us(减少64%)。

 

[1] 所有成员都按照同样的顺序接收消息

[2] 逻辑时钟指的是分布式系统中用于区分事件的发生顺序的时间机制

[3] 即使在一个对象在执行操作的过程中发生了故障,抛出异常之后,通常也希望该对象仍然处于定义良好的可用状态。对于受控异常尤其如此,调用者需要从中恢复。一般来说,失败的方法调用应该使对象保持在调用之前的状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值