用于多节点集群的事务管理的制作方法

文档序号:14036430阅读:269来源:国知局
用于多节点集群的事务管理的制作方法



背景技术:

集群可以涉及作为单个系统一起工作以执行应用或实行各种功能的多个节点(例如,计算机、服务器)。在一些示例中,集群可以提供比单个节点可以提供的更好的速度、可用性和容错性。集群中的节点可以利用处理和/或存储中的冗余来提供高可用性系统,其中单个节点的故障可以以最小限度的中断或延迟来允许继续服务。然而,冗余可以导致更大的等待时间和/或资源使用。

附图说明

以下详细描述参考附图,其中:

图1a是用于多节点集群的示例事务管理系统的框图,其中使用已请求标签和已服务标签中的至少一个来恢复节点;

图1b是多节点集群的示例恢复引擎的框图,其中已经确定所有者节点并未故障并且服务节点已经故障;

图1c是多节点集群的示例恢复引擎的框图,其中已经确定所有者节点已经故障并且服务节点并未故障;

图2a是用于多节点集群的示例事务管理系统的框图,其中所有者节点和服务节点是相同节点;

图2b是多节点集群的示例恢复引擎的框图,其中已经确定所有者节点和服务节点已经故障,其中所有者节点和服务节点是相同节点;

图3是用于多节点集群的示例事务管理系统的框图,其中重复数据位置与预先分配的存储器块相关联;

图4a是管理多节点集群的事务的示例方法的流程图,其包括接收请求、在所有者节点处存储数据以及将数据复制在重复数据位置处;

图4b是管理多节点集群的事务的示例方法的流程图,其包括确定所有者节点和服务节点已经故障(其中所有者节点和服务节点是相同节点)、恢复数据以及重新发布零拷贝请求;

图4c是管理多节点集群的事务的示例方法的流程图,其包括确定所有者节点并未故障、确定服务节点已经故障以及重新发布零拷贝请求;

图4d是管理多节点集群的事务的示例方法的流程图,其包括确定所有者节点已经故障、确定服务节点并未故障、恢复数据以及重新发布零拷贝请求;

图5a是包括指令的示例机器可读存储介质的框图,所述指令用于用已请求标签和已服务标签来标记预先分配的存储器块中的重复数据位置并使用已请求标签和已服务标签中的至少一个来经由多节点集群中的事务管理系统来恢复故障节点;以及

图5b是用于基于所有者节点和服务节点是相同节点并且已经故障的确定来恢复多节点集群中的故障节点的示例指令的框图。

具体实施方式

当发生故障或错误时,高可用性集群可以允许更好的速度和可靠性。与其中错误可以导致关机或服务中断直至管理员介入的单节点系统不同,高可用性集群允许不同的节点继续进行可能由于第一节点上的错误而中断的服务。在第一节点故障时,高可用性集群可以依赖能够接管故障节点的操作的冗余节点。在一些示例中,冗余节点可以具有位于第一节点上的任何数据的拷贝。在其它示例中,冗余节点可以影随(shadow)第一节点的操作,或者可以对第一节点进行的操作的处理做出贡献。

在一些示例中,为了实现高可用性,集群内的节点可以共享存储器。例如,集群中的所有节点可以共享所有存储器,这允许每个节点访问共享存储器。在另一示例中,一些或所有的节点可以共享一些存储器。在这样的示例中,节点可以参与零拷贝操作。

零拷贝操作尝试最小化处理器必须将数据从一个存储器拷贝到另一存储器的次数。例如,非零拷贝读取或写入操作可以涉及若干拷贝操作,包括由中央处理单元(cpu)或处理资源进行的拷贝。在一个示例中,从一个存储器位置读取数据并将其写入另一存储器位置可以涉及由cpu或处理资源进行的至少两次拷贝。例如,可以首先经由例如基于直接存储器访问(dma)的拷贝操作将数据从硬盘或其它持久性存储区域拷贝到操作系统缓冲器。然后,中央处理单元(cpu)或其它处理资源可以将数据从操作系统缓冲器拷贝到cpu或处理资源高速缓存缓冲器以利用该数据。为了将数据写入另一存储器位置,cpu或处理资源可以将数据从高速缓存缓冲器拷贝到另一操作系统缓冲器。基于dma的拷贝操作可以最终将数据从操作系统缓冲器拷贝到例如持久性存储中的它的最终位置。在一些示例中,零拷贝操作可以通过使用基于dma的拷贝、经由存储器管理单元(mmu)的存储器映射、共享存储器和/或其它技术来使cpu或处理资源拷贝最小化。

虽然在集群中的节点之间共享的存储器在一些示例中可以促进零拷贝操作,但共享存储器所需的复杂度和连接可能是成本过高的、低效的且计算密集的。在要将附加节点添加到系统时,节点间共享的存储器也可能难以扩缩。此外,跨节点共享存储器可能使可能需要将数据同步配设纳入考虑的容错方法过载或者可能阻碍这样的容错方法,并且可以导致过度繁重的容错方案。

本文描述的示例可以经由与零拷贝请求相关联的存储器的标记来改进多节点集群中的容错和事务管理。在一些示例中,可以在节点或节点上的进程之间预先分配存储器。接收请求的所有者节点可以针对所述请求在请求日志中生成标识重复数据位置的请求日志条目,用已请求标签标记重复数据位置,并且发布标识重复数据位置的零拷贝请求。服务节点可以接收零拷贝请求以进行处理,并且可以用已服务标签标记重复数据位置。在这样的示例中,当在节点处发生故障时,恢复引擎可以利用重复数据位置的已请求标签和/或已服务标签来恢复数据并完成事务。

在本文描述的一些示例中,用于多节点集群的事务管理系统可以涉及多节点集群的所有者节点的请求引擎。请求引擎可以针对请求在请求日志中生成标识重复数据位置的请求日志条目,用已请求标签标记重复数据位置,并发布标识重复数据位置的零拷贝请求。多节点集群的服务引擎的服务引擎可以基于零拷贝请求在服务日志中生成标识重复数据位置的服务日志条目,处理零拷贝请求,并用已服务标签标记重复数据位置,其中已服务标签替换已请求标签。确定引擎可以确定所有者节点或服务节点是否已经故障,并且基于所有者节点和服务节点中的至少一个已经故障的确定,恢复引擎可以经由重复数据位置的已请求标签和已服务标签中的至少一个来恢复故障节点。在本文描述的示例中,被说成是基于给定条件的确定、动作等可以是单独基于该条件或是基于该条件和(一个或多个)其它条件。

在本文描述的一些示例中,管理多节点集群的事务的方法可以涉及在多节点集群的所有者节点的请求引擎处接收包含数据的请求,将数据存储在所有者节点处,将数据复制在重复数据位置处,针对该请求在请求日志中生成标识重复数据位置的请求日志条目,以及向多节点集群的服务节点的服务引擎发布标识重复数据位置的零拷贝请求。基于零拷贝请求,可以在服务日志中生成标识重复数据位置的服务日志条目。方法还可以涉及确定所有者节点和服务节点是否已经故障,并且基于确定了所有者节点和服务节点中的至少一个已经故障,经由重复数据位置的已请求标签和已服务标签中的至少一个来恢复故障节点。

在本文描述的一些示例中,用于多节点集群的事务管理系统中的处理资源可以执行机器可读存储介质上的指令以在多节点集群的所有者节点处接收包含数据的请求。处理资源还可以执行指令以针对该请求在请求日志中生成标识预先分配的存储器块中的重复数据位置的请求日志条目,用已请求标签标记重复数据位置,并向多节点集群的服务节点发布标识重复数据位置的零拷贝请求。指令可以基于零拷贝请求在服务日志中生成标识重复数据位置的服务日志条目,处理零拷贝请求,并且用已服务标签来标记重复数据位置,其中已服务标签替换已请求标签。处理资源也可以执行指令以确定所有者节点和服务节点是否已经故障,并且基于所有者节点和服务节点中的至少一个已经故障的确定,经由重复数据位置的已请求标签和已服务标签中的至少一个来恢复故障节点。

现在参照附图,图1a是用于多节点集群100的示例事务管理系统的框图。如本文所述,多节点集群可以指代作为单个系统一起工作的多个节点。在一些示例中,多节点集群的每个节点可以利用相同的操作系统配置以及相同或相似的硬件配置。在其它示例中,多节点集群的节点可以利用相异的操作系统配置或相异的硬件配置。节点可以是适合于执行下面描述的功能性的任何联网设备或计算设备。如本文所使用的,节点可以是台式计算机、膝上型(或笔记本)计算机、工作站、平板计算机、移动电话、智能设备、交换机、路由器、服务器、刀片机箱或包括处理资源的任何其它处理设备或装备。

多节点集群100可以包括所有者节点110和服务节点120。如本文所述,所有者节点110可以指代多节点集群100内拥有或管理特定请求(即,请求102)的节点。如本文所述,服务节点120可以指代多节点集群100内服务或处理特定请求的节点。在一些示例中,多节点集群100内的节点110和120可以经由计算机网络(例如,互联网、局域网(lan)、广域网(wan)等)进行通信。尽管图1a中例示了两个节点110和120,但是在本文描述的示例中,多节点集群可以涉及多于一个的任何合适数量的节点。

所有者节点110可以包括请求引擎112,其可以接收请求102并且在请求日志114中生成请求日志条目116。在本文描述的示例中,请求可以表示要由多节点集群100执行的事务或操作。作为示例,请求102可以是要执行写入操作的请求。在本文描述的示例中,请求日志可以指代与请求引擎相关联的事务的日志。在一些示例中,请求日志114可以记录在所有者节点110处接收的、由所有者节点110发起的、或以其它方式与所有者节点110相关联的所有请求。在其它示例中,请求日志114可以记录与所有者节点110相关联的所有事务。在又其它的示例中,请求日志114可以记录与请求引擎112相关联的所有请求或事务。如图1a所示,请求日志114可以位于所有者节点110处。也可以在多节点集群100的另一节点(诸如服务节点120)处创建请求日志114的冗余拷贝。在一些示例中,可以在多节点集群100的每个节点处创建请求日志114的冗余拷贝。在其它示例中,可以在多节点集群100中的多个(但不是全部)节点处创建请求日志114的冗余拷贝。在一些这样的示例中,请求日志114可以被镜像到另一节点。请求日志114也可以位于与多节点集群100分离或远离但可由多节点集群100访问。

如图1a所示,请求日志114可以包括众多请求日志条目116。如本文所述,请求日志条目指代请求日志内的每个条目。每个请求日志条目116可以表示与请求引擎112相关联的特定请求或事务。在其它示例中,每个请求日志条目116可以表示与所有者节点110相关联的请求或事务。请求日志条目116还可以标识重复数据位置。如本文所述,重复数据位置可以指代可以由所有者节点110上的请求引擎112、服务节点120上的服务引擎122和恢复引擎132(在必要时)访问的、用于数据的重复或第二存储区域位置。在一些示例中,请求日志条目116可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。

在请求日志114中生成请求日志条目116之后,请求引擎112可以用已请求标签来标记重复数据位置。如本文所使用的,标签可以指代与存储器位置相关联的、指示具体动作的位或一串位。例如,已请求标签可以指示请求引擎已接收到与所标记的重复数据位置有关的请求,即请求102。请求引擎112然后可以发布(例如,生成、发送)标识重复数据位置的零拷贝请求130。在一些示例中,请求引擎112可以向服务节点120和/或位于服务节点120上的服务引擎122发布零拷贝请求130。在其它示例中,所有者节点110可以从请求引擎112接收零拷贝请求130,并且向服务节点120和/或服务引擎122发布零拷贝请求。如本文所述,零拷贝请求可以指代在中央处理单元(cpu)或处理资源不将数据从一个存储器位置拷贝到另一存储器位置的情况下执行的事务或操作。在一些示例中,零拷贝请求130可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。零拷贝请求130可以是(至少部分地)基于请求引擎112针对其在请求日志114中生成了请求日志条目116的请求102的。

在一些示例中,可以在不使用基于cpu或基于处理资源的数据拷贝的情况下经由基于直接存储器访问(dma)的拷贝和/或存储器管理单元(mmu)来执行零拷贝请求130。在这样的示例中,由零拷贝请求130标识的重复数据位置可以在可以由所有者节点110上的请求引擎112、服务节点120上的服务引擎122以及恢复引擎132(在必要时)访问的存储器区域中。

服务节点120可以包括服务引擎122以获得或接收零拷贝请求130。(至少部分地)基于零拷贝请求130,服务引擎122可以在服务日志124中生成服务日志条目126。在本文描述的示例中,服务日志可以指代与服务引擎相关联的事务的日志。在一些示例中,服务日志124可以记录与服务引擎122相关联的所有请求或事务。在其它示例中,服务日志124可以记录在服务节点120处接收到的、由服务节点120发起的或者以其它方式与服务节点120相关联的所有请求。在又其它的示例中,服务日志122可以记录与服务节点120相关联的所有事务。如图1a所示,服务日志124可以位于服务节点120处。也可以在多节点集群100的另一节点(诸如所有者节点110)处创建服务日志124的冗余拷贝。在一些示例中,可以在多节点集群100的每个节点处创建服务日志124的冗余拷贝。在其它示例中,可以在多节点集群100的多个(但不是全部)节点处创建服务日志124的冗余拷贝。在一些这样的示例中,服务日志124可以被镜像到另一节点。服务日志124也可以位于与多节点集群100分离或远离但可由多节点集群100访问。

如图1a所示,服务日志124可以包括众多服务日志条目126。如本文所述,服务日志条目指代服务日志内的每个条目。每个服务日志条目126可以表示与服务引擎122相关联的特定请求或事务。在其它示例中,每个服务日志条目126可以表示与服务节点120相关联的请求或事务。服务日志条目126还可以标识重复数据位置。如上文所讨论的,重复数据位置可以指代可以由所有者节点110上的请求引擎112和服务节点120上的服务引擎122两者访问的用于数据的重复或第二存储区域位置。在一些示例中,服务日志条目126可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。

在一些示例中,服务引擎122可以处理零拷贝请求130。在一些这样的示例中,处理零拷贝请求130可以涉及执行所请求的操作。在其它这样的示例中,例如在其中零拷贝请求130可以涉及写入操作的示例中,服务引擎122可以通过将零拷贝请求130和/或要写入的数据传递给队列(例如,先进先出队列或优先级队列,其中分别按照数据在队列中的放置或按照数据的优先级来写入数据)来处理零拷贝请求130。在一些示例中,服务引擎122然后可以用已服务标签来标记重复数据位置。如本文所使用的,标签可以指代与存储器位置相关联的、指示具体动作的位或一串位。例如,已服务标签可以指示服务引擎已经处理了与所标记的重复数据位置相关的零拷贝请求。在一些示例中,已服务标签可以替换较早的标签——已请求标签。在其它示例中,可以添加已服务标签而不更改、清除或移除已请求标签。

确定引擎132可以确定所有者节点110和服务节点120是否已经故障。在一些示例中,确定引擎132可以接收或监控故障或错误消息以确定所有者节点110或服务节点120是否已经故障。在其它示例中,确定引擎132可以查询所有者节点110和/或服务节点120以确定任一者是否已经故障。确定引擎132可以位于多节点集群100中的任何存活节点上。在一些示例中,确定引擎132可以位于多节点集群100中的每个节点上或者多节点集群100内的多个(但不是全部)节点上。确定引擎132也可以位于多节点集群100中的任何节点上,包括所有者节点110和服务节点120二者或者不包括所有者节点110和服务节点120中的任一者。在其它示例中,确定引擎132可以与多节点集群100分离或远离,但能够与多节点集群100通信并且可由多节点集群100访问。

(至少部分地)基于所有者节点110和服务节点120中的至少一个已经故障的确定,恢复引擎142可以经由重复数据位置的已请求标签和已服务标签中的至少一个来恢复故障节点。恢复引擎142可以请求、接收或以其它方式从确定引擎132获得关于所有者节点110和/或服务节点120的故障的信息。在一些示例中,恢复可以涉及在故障或错误的时候检查、重放和/或分析请求日志条目116和/或服务日志条目126,以确保所请求的操作或事务(即,请求102和零拷贝请求130)的效果在存储器中持续存在。在一些这样的示例中,恢复可以涉及撤消未完成的已请求操作或事务的效果,以确保未完成的已请求操作或事务的效果不会在存储器中持续存在。

恢复引擎142可以位于多节点集群100中的任何存活节点上。在一些示例中,恢复引擎142可以位于多节点集群100中的每个节点上,或者位于多节点集群100内的多个(但不是全部)节点上。恢复引擎142也可以位于多节点集群100中的任何节点上,包括所有者节点110和服务节点120二者,或者不包括所有者节点110和服务节点120中的任一者。在其它示例中,恢复引擎142可以与多节点集群100分离或远离,但能够与多节点集群100通信并且可由多节点集群100访问。在又其它的示例中,恢复引擎142可以与确定引擎132位于同一节点上。

图1b进一步例示了多节点集群100的示例恢复引擎142,其中确定引擎132已经确定了所有者节点110没有故障并且服务节点120已经故障。(至少部分地)基于所有者节点110没有故障但服务节点120已经故障的确定,恢复引擎142可以在144处扫描服务日志124并用已服务标签重新标记在服务日志中标识的每个重复数据位置。在一些示例中,恢复引擎142可以通过检查每个服务日志条目126并分析每个服务日志条目126中标识的每个重复数据位置来扫描服务日志124。在一些示例中,恢复引擎142可以通过移除或清除重复数据位置处的任何现有标签并用已服务标签替换它来重新标记每个重复数据位置。在其它示例中,恢复引擎142可以通过添加已服务标签而不移除任何先前的标签来重新标记每个重复数据位置。在又其它的示例中,恢复引擎142可以通过分析重复数据位置处的任何现有标签、确定现有标签是否是已服务标签以及如果不是则用已服务标签替换该标签来重新标记每个重复数据位置。

在145处,恢复引擎142可以确定任何重复数据位置是否依然标记有已请求标签。在一些示例中,恢复引擎142可以检查每个重复数据位置以确定任何重复数据位置是否具有已请求标签。在其它示例中,在每个重复数据位置可以具有若干标签的情况下,恢复引擎142可以确定任何重复数据位置的最新或最后标签是否是已请求标签。

(至少部分地)基于重复数据位置被标记有已请求标签的确定,在146处,恢复引擎142可以识别标识了该重复数据位置的请求日志条目116。在一些示例中,恢复引擎142可以将该重复数据位置与在请求日志114中标识的重复数据位置进行比较以识别请求日志条目116。然后,恢复引擎142可以重新发布零拷贝请求130。在一些示例中,恢复引擎142可以向新服务节点和/或新服务节点上的新服务引擎重新发布零拷贝请求130。在一些示例中,恢复引擎142可以通过(至少部分地)基于请求日志条目116重新构建或重新生成零拷贝请求来重新发布零拷贝请求130。重新发布的零拷贝请求130可以标识该重复数据位置。

图1c进一步例示了多节点集群100的示例恢复引擎142,其中确定引擎132已经确定了所有者节点110已经故障并且服务节点120没有故障。(至少部分地)基于所有者节点110已经故障并且服务节点120没有故障的确定,恢复引擎142可以在148处确定是否有任何重复数据位置被标记有已请求标签。在一些示例中,恢复引擎142可以检查每个重复数据位置以确定任何重复数据位置是否具有已请求标签。在其它示例中,在每个重复数据位置可以具有若干标签的情况下,恢复引擎142可以确定任何重复数据位置的最新或最后标签是否是已请求标签。

(至少部分地)基于重复数据位置被标记有已请求标签的确定,在149处,恢复引擎142可以识别标识了该重复数据位置的请求日志条目116。在一些示例中,恢复引擎142可以将该重复数据位置与在请求日志114中标识的重复数据位置进行比较以识别请求日志条目116。在150处,恢复引擎142可以从重复数据位置恢复数据。在一些示例中,恢复引擎142可以通过拷贝数据并将数据存储在另一存储位置处来恢复数据。然后,恢复引擎142可以重新发布零拷贝请求130。在一些示例中,恢复引擎142可以向服务节点120和/或服务节点120上的服务引擎122重新发布零拷贝请求130。在一些示例中,恢复引擎142可以通过(至少部分地)基于请求日志条目116和/或恢复的数据而重新构建或重新生成零拷贝请求来重新发布零拷贝请求130。在一些示例中,重新发布的零拷贝请求标识该重复数据位置。在其它示例中,重新发布的零拷贝请求130可以标识在其新位置中的恢复数据。

多节点集群100可以由至少两个节点实现,并且可以至少包括引擎112、122、132和142,引擎112、122、132和142可以是用以实现本文描述的引擎的功能性的硬件和编程的任何组合。在本文描述的示例中,硬件和编程的这种组合可以以许多不同的方式来实现。例如,引擎的编程可以是存储在至少一个非暂时性机器可读存储介质上的处理器可执行指令,并且引擎的硬件可以包括用以执行那些指令的至少一个处理资源。在一些示例中,硬件也可以包括用以至少部分地实现多节点集群100的至少一个引擎的其它电子电路。在一些示例中,所述至少一个机器可读存储介质可以存储指令,所述指令在由所述至少一个处理资源执行时至少部分地实现多节点集群100的一些或全部引擎。在这样的示例中,多节点集群100可以包括存储所述指令的所述至少一个机器可读存储介质和用以执行所述指令的所述至少一个处理资源。

在一些示例中,指令可以是安装包的一部分,该安装包在被安装时可以被所述至少一个处理资源执行以至少部分地实现多节点集群100的引擎中的至少一些。在这样的示例中,机器可读存储介质可以是便携式介质(诸如cd、dvd或闪速驱动)或者由服务器维持的存储器,可以从该服务器下载和安装安装包。在其它示例中,指令可以是已经安装在包括处理资源的节点110和120上的应用、多个应用或组件的一部分。在这样的示例中,机器可读存储介质可以包括诸如硬驱动、固态驱动等的存储器。在其它示例中,多节点集群100的任何引擎的功能性可以至少部分地以电子电路的形式实现。在一些示例中,本文关于图1a、1b和1c描述的功能性可以结合本文关于图2-5中的任何描述的功能性来提供。

本文关于图2a描述了另外的示例,图2a是用于多节点集群200的示例事务管理系统的框图。如上所述,多节点集群可以指代作为单个系统一起工作的多个节点。在一些示例中,多节点集群的每个节点可以利用相同的操作系统配置以及相同或相似的硬件配置。在其它示例中,多节点集群的节点可以利用相异的操作系统配置或相异的硬件配置。节点可以是适合于执行下面描述的功能性的任何联网设备或计算设备。如本文所使用的,节点可以是台式计算机、膝上型(或笔记本)计算机、工作站、平板计算机、移动电话、智能设备、交换机、路由器、服务器、刀片机箱、或包括处理资源的任何其它处理设备或装备。

多节点集群200包括所有者节点/服务节点210和节点220。如图2a所示,由单个或同一节点——所有者节点/服务节点210,该节点既拥有并管理特定的请求又服务并处理所述请求——来执行所有者节点和服务节点的功能性。节点210和220可以是适合执行下面描述的功能性的任何联网设备或计算设备。多节点集群200和节点210和220可以至少部分地由引擎212、222、232和242来实现,引擎212、222、232和242可以是用以实现本文所述的引擎的功能性的硬件和编程的任何组合。尽管图2a中例示了两个节点210和220,但是在本文描述的示例中多节点集群可以涉及多于一个的任何合适数量的节点。

所有者节点/服务节点210可以包括请求引擎212,其可以接收请求202并且在请求日志214中生成请求日志条目216。如上文讨论的,请求可以表示要由多节点集群200执行的事务或操作。作为示例,请求202可以是要执行写入操作的请求。在本文描述的示例中,请求日志可以指代与请求日志相关联的事务的日志。在一些示例中,请求日志214可以记录与请求引擎212相关联的所有请求或事务。如图2a所示,请求日志214可以位于所有者节点/服务节点210处。也可以在多节点集群200的诸如节点120之类的另一节点处创建请求日志214的冗余拷贝。在一些示例中,可以在多节点集群200的每个节点处创建请求日志214的冗余拷贝。在其它示例中,可以在多节点集群200的多个(但不是全部)节点处创建请求日志214的冗余拷贝。在一些这样的示例中,请求日志214可以被镜像到另一节点。请求日志214也可以与多节点集群200分离或者远离,但是可由多节点集群200访问。

如图2a所示,请求日志214可以包括众多请求日志条目216。如本文所述,请求日志条目指代请求日志内的每个条目。每个请求日志条目216可以表示与请求引擎212相关联的特定请求或事务。请求日志条目216还可以标识重复数据位置。如上文讨论的,重复数据位置可以指代可以由请求引擎212和服务引擎222两者访问的用于数据的重复或第二存储区域位置。在一些示例中,请求日志条目216可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。

在请求日志214中生成请求日志条目216之后,请求引擎212可以用已请求标签来标记重复数据位置。如本文所使用的,标签可以指代与存储器位置相关联的、指示具体动作的位或一串位。例如,已请求标签可以指示请求引擎已经接收到与所标记的重复数据位置有关的请求,即请求202。请求引擎212然后可以向服务引擎222发布(例如,生成、发送)标识重复数据位置的零拷贝请求230。如上文讨论的,零拷贝请求可以指代在没有中央处理单元(cpu)或处理资源将数据从一个存储器位置拷贝到另一存储器位置的情况下执行的事务或操作。在一些示例中,零拷贝请求230可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。零拷贝请求230可以是(至少部分地)基于请求引擎212针对其在请求日志214中生成了请求日志条目216的请求202的。

在一些示例中,可以在不使用基于cpu或基于处理资源的数据拷贝的情况下经由基于直接存储器访问(dma)的拷贝和/或存储器管理单元(mmu)来执行零拷贝请求230。在这样的示例中,由零拷贝请求230标识的重复数据位置可以在可以由请求引擎212和服务引擎222二者访问的存储器区域中。

所有者节点/服务节点120也可以包括服务引擎222以获得或接收零拷贝请求230。(至少部分地)基于零拷贝请求230,服务引擎222可以在服务日志224中生成服务日志条目226。在本文描述的示例中,服务日志可以指代与服务引擎相关联的事务的日志。在一些示例中,服务日志224可以记录与服务引擎222相关联的所有请求或事务。如图2a所示,服务日志224可以位于所有者节点/服务节点210处。也可以在多节点集群200的诸如节点220之类的另一节点处创建服务日志224的冗余拷贝。在一些示例中,可以在多节点集群200的每个节点处创建服务日志224的冗余拷贝。在其它示例中,可以在多节点集群200的多个(但不是全部)节点处创建服务日志224的冗余拷贝。在一些这样的示例中,服务日志224可以被镜像到另一节点。服务日志224也可以位于与多节点集群200分离或者远离,但可由多节点集群200访问。

如图2a所示,服务日志224可以包括众多服务日志条目226。如上所述,服务日志条目指代服务日志内的每个条目。每个服务日志条目226可以表示与服务引擎222相关联的特定请求或事务。服务日志条目226还可以标识重复数据位置。在一些示例中,服务日志条目226可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。

在一些示例中,服务引擎222可以处理零拷贝请求230。在一些这样的示例中,处理零拷贝请求230可以涉及执行所请求的操作。在其它这样的示例中,例如在其中零拷贝请求230可以涉及写入操作的示例中,服务引擎222可以通过将零拷贝请求230和/或要写入的数据传递给队列(例如,先进先出队列或优先级队列,其中分别按照数据在队列中的放置或按照数据的优先级来写入数据)来处理零拷贝请求230。在一些示例中,服务引擎222然后可以用已服务标签来标记重复数据位置。例如,已服务标签可以指示服务引擎已经处理了与所标记的重复数据位置相关的零拷贝请求。在一些示例中,已服务标签可以替换较早的标签——已请求标签。在其它示例中,可以添加已服务标签而不更改、清除或移除已请求标签。

确定引擎232可以确定所有者节点/服务节点210是否已经故障。确定引擎232也可以确定节点220是否已经故障。在一些示例中,确定引擎232可以接收或监控故障或错误消息以确定所有者节点/服务节点210和/或节点220是否已经故障。在其它示例中,确定引擎232可以查询所有者节点/服务节点210和/或节点220以确定任一者是否已经故障。确定引擎232可以位于多节点集群200中的任何存活节点上。在一些示例中,确定引擎232可以位于多节点集群200中的每个节点上,或者多节点集群200内的多个(但不是全部)节点上。确定引擎232也可以位于多节点集群200中的任何节点上,包括所有者节点/服务节点210和节点220二者,或者不包括所有者节点/服务节点210与节点220中的任一者。在其它示例中,确定引擎232可以与多节点集群200分离或者远离,但是能够与多节点集群200通信并且可由多节点集群200访问。

(至少部分地)基于所有者节点/服务节点210已经故障的确定,恢复引擎242可以经由重复数据位置的已请求标签和已服务标签中的至少一个来恢复故障节点。恢复引擎242可以请求、接收或以其它方式从确定引擎232获得关于所有者节点/服务节点210和/或节点220的故障的信息。在一些示例中,恢复可以涉及在故障或错误的时候检查、重放和/或分析请求日志条目216和/或服务日志条目226,以确保所请求的操作或事务(即,请求202和零拷贝请求230)的效果在存储器中持续存在。在一些这样的示例中,恢复可以涉及撤消未完成的已请求操作或事务的效果,以确保未完成的已请求操作或事务的效果不会在存储器中持续存在。

恢复引擎242可以位于多节点集群200中的任何存活节点上。在一些示例中,恢复引擎242可以位于多节点集群200中的每个节点上,或者位于多节点集群200内的多个(但不是全部)节点上。恢复引擎242也可以位于多节点集群200中的任何节点上,包括所有者节点/服务节点210和节点220二者,或者不包括所有者节点/服务节点210与节点220中的任一者。在其它示例中,恢复引擎242可以与多节点集群200分离或者远离,但是能够与多节点集群200通信并且可由多节点集群200访问。在又其它的示例中,恢复引擎242可以与确定引擎232位于同一节点上。

图2b进一步例示了多节点集群200的示例恢复引擎242,其中确定引擎232已经确定了所有者节点和服务节点(即,所有者节点/服务节点210)已经故障。(至少部分地)基于所有者节点/服务节点210已经故障的确定,恢复引擎242可以在244处扫描请求日志214并且用已请求标签重新标记在请求日志中标识的每个重复数据位置。在一些示例中,恢复引擎242可以通过访问和检查每个请求日志条目216并分析每个请求日志条目216中标识的每个重复数据位置来扫描请求日志214。在一些示例中,恢复引擎242可以通过移除或清除重复数据位置处的任何现有标签并用已请求标签替换它来重新标记每个重复数据位置。在其它示例中,恢复引擎242可以通过添加已请求标签而不移除任何先前的标签来重新标记每个重复数据位置。在又其它的示例中,恢复引擎242可以通过分析重复数据位置处的任何现有标签、确定现有标签是否是已请求标签以及如果不是则用已请求标签替换该标签来重新标记每个重复数据位置。

在245处,恢复引擎242也可以扫描服务日志224并用已服务标签重新标记在服务日志中标识的每个重复数据位置。在一些示例中,恢复引擎242可以通过检查每个服务日志条目226并分析在每个服务日志条目226中标识的每个重复数据位置来扫描服务日志224。在一些示例中,恢复引擎242可以通过移除或清除重复数据位置处的任何现有标签并用已服务标签替换它来重新标记每个重复数据位置。在其它示例中,恢复引擎242可以通过添加已服务标签而不移除任何先前的标签来重新标记每个重复数据位置。在又其它的示例中,恢复引擎242可以通过分析重复数据位置处的任何现有标签、确定现有标签是否是已服务标签以及如果不是则用已服务标签替换该标签来重新标记每个重复数据位置。

在246处,恢复引擎242可以确定任何重复数据位置是否依然标记有已请求标签。在一些示例中,恢复引擎242可以检查每个重复数据位置以确定任何重复数据位置是否具有已请求标签。在其它示例中,在每个重复数据位置可以具有若干标签的情况下,恢复引擎242可以确定任何重复数据位置的最新或最后标签是否是已请求标签。

(至少部分地)基于重复数据位置被标记有已请求标签的确定,在247处,恢复引擎242可以识别标识了该重复数据位置的请求日志条目216。在一些示例中,恢复引擎242可以将该重复数据位置与请求日志214中标识的重复数据位置进行比较以识别请求日志条目216。

在248处,恢复引擎242可以从重复数据位置中恢复数据。在一些示例中,恢复引擎242可以通过拷贝数据并将数据存储在另一存储位置处来恢复数据。然后,恢复引擎242可以重新发布零拷贝请求230。在一些示例中,恢复引擎242可以将零拷贝请求230重新发布到新的、存活的节点(诸如节点220)上的新服务引擎。在一些示例中,恢复引擎242可以通过(至少部分地)基于请求日志条目216和/或恢复的数据而重新构建或重新生成零拷贝请求来重新发布零拷贝请求230。在一些示例中,重新发布的零拷贝请求标识该重复数据位置。在其它示例中,重新发布的零拷贝请求230可以标识在其新位置中的恢复数据。

多节点集群200可以由至少两个节点来实现,并且可以至少包括引擎212、222、232和242,引擎212、222、232和242可以是用以实现本文描述的引擎的功能性的硬件和编程的任何组合。在本文描述的示例中,硬件和编程的这种组合可以以许多不同的方式来实现。例如,引擎的编程可以是存储在至少一个非暂时性机器可读存储介质上的处理器可执行指令,并且引擎的硬件可以包括用以执行那些指令的至少一个处理资源。在一些示例中,硬件也可以包括用以至少部分地实现多节点集群200的至少一个引擎的其它电子电路。在一些示例中,所述至少一个机器可读存储介质可以存储指令,所述指令在由所述至少一个处理资源执行时至少部分地实现多节点集群200的一些或全部引擎。在这样的示例中,多节点集群200可以包括存储所述指令的所述至少一个机器可读存储介质和用以执行所述指令的所述至少一个处理资源。

在一些示例中,指令可以是安装包的一部分,该安装包在被安装时可以被所述至少一个处理资源执行以至少部分地实现多节点集群200的引擎中的至少一些。在这样的示例中,机器可读存储介质可以是便携式介质(诸如cd、dvd或闪速驱动)或者由服务器维持的存储器,可以从该服务器下载和安装安装包。在其它示例中,指令可以是已经安装在包括处理资源的节点210和220上的应用、多个应用或组件的一部分。在这样的示例中,机器可读存储介质可以包括诸如硬驱动、固态驱动等的存储器。在其它示例中,多节点集群200的任何引擎的功能性可以至少部分地以电子电路的形式实现。在一些示例中,本文关于图2a和2b描述的功能性可以结合本文关于图1和图3-5中的任何所描述的功能性来提供。

本文关于图3描述另外的示例,图3是用于多节点集群300的示例事务管理系统的框图。如上所述,多节点集群可以指代作为单个系统一起工作的多个节点。在一些示例中,多节点集群的每个节点可以利用相同的操作系统配置以及相同或相似的硬件配置。在其它示例中,多节点集群的节点可以利用相异的操作系统配置或相异的硬件配置。节点可以是适合于执行下面描述的功能性的任何联网设备或计算设备。如本文所使用的,节点可以是台式计算机、膝上型(或笔记本)计算机、工作站、平板计算机、移动电话、智能设备、交换机、路由器、服务器、刀片机箱、或包括处理资源的任何其它处理设备或装备。

多节点集群300可以包括所有者节点310和服务节点320。所有者节点310可以指代多节点集群300内的拥有或管理特定请求(即,请求302)的节点。服务节点320可以指代多节点集群300内的服务或处理特定请求的节点。在一些示例中,多节点集群300内的节点310和320可以经由计算机网络(例如,互联网、局域网(lan)、广域网(wan)等)进行通信。尽管在图3中例示了两个节点310和320,但是在本文描述的示例中,多节点集群可以涉及多于一个的任何合适数量的节点。尽管未示出,但所有者节点310和服务节点320也可以位于单个或同一节点上。在这样的示例中,所有者节点310和服务节点320的功能性由同一节点执行,该节点既拥有并管理特定的请求又服务并处理所述请求。

所有者节点310可以包括请求引擎312,其可以接收请求302。在本文描述的示例中,请求可以表示要由多节点集群300执行的事务或操作。在一些示例中,请求302可以包含数据。例如,请求302可以包含数据并且是要执行涉及所述数据的写入操作的请求。在一些示例中,请求引擎312可以将包含在请求302中的数据存储在所有者节点310处。请求引擎312还可以将数据复制在重复数据位置处。如本文所述,重复数据位置可以指代可以由所有者节点310上的请求引擎312、服务节点320上的服务引擎322二者和恢复引擎332(在必要时)访问的用于数据的重复或第二存储区域位置。在一些示例中,请求引擎312可以通过向服务节点320发送数据304以存储在服务节点320内的重复数据位置308处来复制数据。在其它示例中,请求引擎312可以经由镜像来复制数据。

如图3所示,重复数据位置308可以位于请求引擎312和服务引擎322二者都可以访问的服务节点320处的预先分配的存储器块306内。如本文的示例中所使用的,预先分配的存储器块可以指代在其使用之前被分配了、并且可以由请求引擎、服务引擎和恢复引擎(在必要时)访问的存储器块。预先分配的存储器块可以是临时分配的或者被分配达固定的时间量。在一些示例中,重复数据位置308可以位于多节点集群300内的另一节点(例如,除了服务节点320之外的节点)处的预先分配的存储器块中。例如,在所有者节点310和服务节点320可以是同一节点的情况下,重复数据位置308可以位于多节点集群300内的另一节点中。

请求引擎312可以在请求日志314中生成请求日志条目316。在本文描述的示例中,请求日志可以指代与请求引擎相关联的事务的日志。在一些示例中,请求日志314可以记录在所有者节点310处接收到的、由所有者节点310发起的或以其它方式与所有者节点310相关联的所有请求。在其它示例中,请求日志314可以记录与所有者节点310相关联的所有事务。在又其它的示例中,请求日志314可以记录与请求引擎312相关联的所有请求或事务。如图3所示,请求日志314可以位于所有者节点310处。也可以在多节点集群300的另一节点(诸如服务节点320)处创建请求日志314的冗余拷贝。在一些示例中,可以在多节点集群300的每个节点处创建请求日志314的冗余拷贝。在其它示例中,可以在多节点集群300的多个(但不是全部)节点处创建请求日志314的冗余拷贝。在一些这样的示例中,请求日志314可以被镜像到另一节点。请求日志314也可以位于与多节点集群300分离或远离,但可由多节点集群300访问。

如图3所示,请求日志314可以包括众多请求日志条目316。每个请求日志条目316可以表示与请求引擎312相关联的特定请求或事务。在其它示例中,每个请求日志条目316可以表示与所有者节点310相关联的请求或事务。请求日志条目316还可以标识重复数据位置308。在一些示例中,请求日志条目316可以用指针、地址、或足以标识重复数据位置的其它机制来标识重复数据位置308。

在请求日志314中生成请求日志条目316之后,请求引擎312可以用已请求标签来标记重复数据位置308。例如,已请求标签可以指示请求引擎已经接收到与所标记的重复数据位置有关的请求,即请求302。请求引擎312然后可以发布(例如,生成、发送)标识重复数据位置308的零拷贝请求330。在一些示例中,请求引擎312可以向服务节点320和/或位于服务节点320上的服务引擎322发布零拷贝请求330。在其它示例中,所有者节点310可以从请求引擎312接收零拷贝请求330,并向服务节点320和/或服务引擎322发布零拷贝请求。如本文所述,零拷贝请求可以指代在没有中央处理单元(cpu)或处理资源将数据从一个存储器位置拷贝到另一存储器位置的情况下执行的事务或操作。在一些示例中,零拷贝请求330可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置308。零拷贝请求330可以是(至少部分地)基于请求引擎312针对其在请求日志314中生成了请求日志条目316的请求302的。

在一些示例中,可以在不使用基于cpu或基于处理资源的数据拷贝的情况下经由基于直接存储器访问(dma)的拷贝和/或存储器管理单元(mmu)来执行零拷贝请求330。在这样的示例中,由零拷贝请求330标识的重复数据位置308可以是在诸如预先分配的存储器块306之类的可以由所有者节点310上的请求引擎312、服务节点320上的服务引擎322以及恢复引擎342(在必要时)访问的存储器区域中。

服务节点320可以包括服务引擎322以获得或接收零拷贝请求330。(至少部分地)基于零拷贝请求330,服务引擎322可以在服务日志324中生成服务日志条目326。在本文描述的示例中,服务日志可以指代与服务引擎相关联的事务的日志。在一些示例中,服务日志324可以记录与服务引擎322相关联的所有请求或事务。在其它示例中,服务日志324可以记录在服务节点320处接收到的、由服务节点320发起的或者以其它方式与服务节点320相关联的所有请求。在有其它的示例中,服务日志322可以记录与服务节点320相关联的所有事务。如图3所示,服务日志324可以位于服务节点320处。也可以在多节点集群300的另一节点(诸如所有者节点310)处创建服务日志324的冗余拷贝。在一些示例中,可以在多节点集群300的每个节点处创建服务日志324的冗余拷贝。在其它示例中,可以在多节点集群300的多个(但不是全部)节点处创建服务日志324的冗余拷贝。在一些这样的示例中,服务日志324可以被镜像到另一节点。服务日志324也可以位于与多节点集群300分离或远离,但可由多节点集群300访问。

如图3所示,服务日志324可以包括众多服务日志条目326。如本文所述,服务日志条目指代服务日志内的每个条目。每个服务日志条目326可以表示与服务引擎322相关联的特定请求或事务。在其它示例中,每个服务日志条目326可以表示与服务节点320相关联的请求或事务。服务日志条目326还可以标识重复数据位置308。如上文讨论的,重复数据位置可以指代可以由所有者节点310上的请求引擎312、服务节点320上的服务引擎322和恢复引擎332(在必要时)访问的用于数据的重复或第二存储区域位置。在一些示例中,服务日志条目326可以用指针、地址、或足以标识重复数据位置的其它机制来标识重复数据位置308。

在一些示例中,服务引擎322可以处理零拷贝请求330。在一些这样的示例中,处理零拷贝请求330可以涉及执行所请求的操作。在其它这样的示例中,例如在其中零拷贝请求330可以涉及写入操作的示例中,服务引擎322可以通过将零拷贝请求330和/或要写入的数据传递给队列(例如,先进先出队列或优先级队列,其中分别按照数据在队列中的放置或按照数据的优先级来写入数据)来处理零拷贝请求330。在一些示例中,服务引擎322然后可以用已服务标签来标记重复数据位置308。如本文所使用的,标签可以指代与存储器位置相关联的、指示具体动作的位或一串位。例如,已服务标签可以指示服务引擎已经处理了与所标记的重复数据位置相关的零拷贝请求。在一些示例中,已服务标签可以替换较早的标签——已请求标签。在其它示例中,可以添加已服务标签而不更改、清除或移除已请求标签。

确定引擎332可以确定所有者节点310和服务节点320是否已经故障。在一些示例中,确定引擎332可以接收或监控故障或错误消息以确定所有者节点310或服务节点320是否已经故障。在其它示例中,确定引擎332可以查询所有者节点310和/或服务节点320以确定任一者是否已经故障。确定引擎332可以位于多节点集群300中的任何存活节点上。在一些示例中,确定引擎332可以位于多节点集群300中的每个节点上或者多节点集群300内的多个(但不是全部)节点上。确定引擎332也可以位于多节点集群300中的任何节点上,包括所有者节点310和服务节点320二者或者不包括所有者节点310和服务节点320中的任一者。在其它示例中,确定引擎332可以与多节点集群300分离或远离,但能够与多节点集群300通信并且可由多节点集群300访问。

(至少部分地)基于所有者节点310和服务节点320中的至少一个已经故障的确定,恢复引擎342可以经由重复数据位置的已请求标签和已服务标签中的至少一个来恢复故障节点。恢复引擎342可以请求、接收或以其它方式从确定引擎332获得关于所有者节点310和/或服务节点320的故障的信息。在一些示例中,恢复可以涉及在故障或错误的时候检查、重放、和/或分析请求日志条目316和/或服务日志条目326,以确保已请求操作或事务(即,请求302和零拷贝请求330)的效果在存储器中持续存在。在一些这样的示例中,恢复可以涉及撤消未完成的已请求操作或事务的效果,以确保未完成的已请求操作或事务的效果不会在存储器中持续存在。

恢复引擎342可以位于多节点集群300中的任何存活节点上。在一些示例中,恢复引擎342可以位于多节点集群300中的每个节点上,或者位于多节点集群300内的多个(但不是全部)节点上。恢复引擎342也可以位于多节点集群300中的任何节点上,包括所有者节点310和服务节点320二者,或者不包括所有者节点310和服务节点320中的任一者。在其它示例中,恢复引擎342可以与多节点集群300分离或远离,但能够与多节点集群300通信并且可由多节点集群100访问。在又其它的示例中,恢复引擎342可以与确定引擎332位于同一节点上。

多节点集群300可以由至少两个节点来实现,并且可以至少包括引擎312、322、332和342,引擎312、322、332和342可以是用以实现本文描述的引擎的功能性的硬件和编程的任何组合。在本文描述的示例中,硬件和编程的这种组合可以以许多不同的方式来实现。例如,引擎的编程可以是存储在至少一个非暂时性机器可读存储介质上的处理器可执行指令,并且引擎的硬件可以包括用以执行那些指令的至少一个处理资源。在一些示例中,硬件也可以包括用以至少部分地实现多节点集群300的至少一个引擎的其它电子电路。在一些示例中,所述至少一个机器可读存储介质可以存储指令,所述指令在由所述至少一个处理资源执行时至少部分地实现多节点集群300的一些或全部引擎。在这样的示例中,多节点集群300可以包括存储所述指令的所述至少一个机器可读存储介质和用以执行所述指令的所述至少一个处理资源。

在一些示例中,指令可以是安装包的一部分,该安装包在被安装时可以被所述至少一个处理资源执行以至少部分地实现多节点集群300的引擎中的至少一些。在这样的示例中,机器可读存储介质可以是便携式介质(诸如cd、dvd或闪速驱动)或者由服务器维持的存储器,可以从该服务器下载和安装安装包。在其它示例中,指令可以是已经安装在包括处理资源的节点310和320上的应用、多个应用或组件的一部分。在这样的示例中,机器可读存储介质可以包括诸如硬驱动、固态驱动等的存储器。在其它示例中,多节点集群300的任何引擎的功能性可以至少部分地以电子电路的形式实现。在一些示例中,本文关于图3描述的功能性可以结合本文关于图1-2和图4-5中的任何所描述的功能性来提供。

图4a是管理多节点集群的事务的示例方法400的流程图,该方法包括接收请求、在所有者节点处存储数据以及将数据复制在重复数据位置处。在下面分别参考图3的多节点集群300的各种特征来描述方法400的执行,但是也可以利用其它合适的系统(例如,图1的多节点集群100、图2的多节点集群200)来用于方法400的执行。另外,方法400的实现不限于这样的示例。

在图4a的示例中,方法400可以是多节点集群300的方法。在402处,请求引擎312可以在所有者节点310处接收包含数据的请求302。可以如上文关于图3的请求引擎312所描述的那样执行此接收。在404处,请求引擎312可以将数据存储在所有者节点310处。在406处,请求引擎312可以将数据复制在重复数据位置308处。可以如上文关于图3的请求引擎312所描述的那样执行此存储和复制。在408处,请求引擎312可以在请求日志314中生成标识重复数据位置308的请求日志条目316。可以如上文关于图3的请求引擎213所描述的那样执行此生成。在410处,请求引擎312可以向位于服务节点320上的服务引擎322发布标识重复数据位置308的零拷贝请求330。可以如上文关于图3的请求引擎312所描述的那样执行此零拷贝请求的发布。

在方法400的412处,服务引擎322可以接收零拷贝请求330并且在服务日志324中生成标识重复数据位置308的服务日志条目326。可以如上文关于图3的服务引擎322所描述的那样执行服务日志条目的此生成。在414和416处,确定引擎332可以确定所有者节点310是否已经故障以及服务节点320是否已经故障。可以如上文关于图3的确定引擎332所描述的那样执行这些确定。如果确定了所有者节点310和服务节点320都没有故障,则方法400可以返回到414并且确定引擎332可以继续针对任何错误或故障来监控或查询节点,如上文关于图3的确定引擎332所述的那样。如果确定了所有者节点310和320中的至少一个已经故障,则方法400可以前进到418,其中恢复引擎342可以经由重复数据位置308的已请求标签和已服务标签中的至少一个来恢复故障节点。可以如上文关于图3的恢复引擎342所描述的那样执行恢复。

尽管图4a的流程图示出了某些功能性的执行的具体顺序,但是方法400可以不限于该顺序。例如,流程图中连续示出的功能性可以以不同的顺序执行,可以同时执行或者部分同时执行,或者其组合。在一些示例中,本文关于图4a描述的功能性可以结合本文关于图1-2、图4b-4d和图5中的任何所描述的功能性来提供。

图4b是管理多节点集群的事务的示例方法420的流程图,该方法包括确定所有者节点和服务节点已经故障(其中所有者节点和服务节点是同一节点)、恢复数据以及重新发布零拷贝请求。在下面分别参考图2和图3的多节点集群200和300的各种特征来描述方法420的执行。可以如方法420中所描述的那样一起利用多节点集群200和300的这些特征。也可以利用其它合适的系统(例如,图1的多节点集群100)来用于方法420的执行。另外,方法420的实现不限于这样的示例。

在图4b的示例中,方法420可以是多节点集群200和300的方法。在422处,请求引擎212可以在所有者节点/服务节点210处接收包含数据的请求202。可以类似于如上所述的在图3的所有者节点310处的请求引擎312处的请求302的接收地执行此接收。也可以如上文关于图2a的请求引擎212所描述的那样执行此接收。

在424处,请求引擎212可以将数据存储在所有者节点/服务节点210处,这类似于如上文关于图3的请求引擎312所述的请求引擎312可以将数据存储在所有者节点310处的方式。在426处,请求引擎212可以将数据复制在另一节点(诸如节点220)上的重复数据位置处,这类似于如上文关于图3的请求引擎312所述的请求引擎312可以将数据复制在服务节点320上的重复数据位置308处的方式。

在428处,请求引擎212可以在请求日志214中生成标识重复数据位置的请求日志条目216。可以与如上文关于图3的请求引擎312所描述的在请求日志314中生成标识重复数据位置308的请求日志条目316类似地执行此生成。也可以如上文关于图2a的请求引擎212所描述的那样执行此生成。在430处,请求引擎212可以向所有者节点/服务节点210上的服务引擎222发布标识重复数据位置的零拷贝请求230。可以与如上文关于图3的请求引擎312所描述的向服务节点320上的服务引擎322发布标识重复数据位置308的零拷贝请求330类似地执行此发布。也可以如上文关于图2a的请求引擎212所描述的那样执行此发布。

在方法420的432处,服务引擎222可以接收零拷贝请求230并且在服务日志224中生成标识重复数据位置的服务日志条目226。可以与如上文关于图3的服务引擎322所描述的接收零拷贝请求330并且在服务日志324中生成标识重复数据位置308的服务日志条目326类似地执行此接收和生成。也可以如上文关于图2a的服务引擎222所描述的那样执行服务日志条目的此生成。

在434处,确定引擎232可以确定所有者节点/服务节点210已经故障。可以与如上文关于图3的确定引擎322所描述的确定所有者节点310和服务节点320已经故障类似地执行此确定。也可以如上文关于图2a的确定引擎232所描述的那样执行此确定。基于所有者节点/服务节点210已经故障的确定,在436处,恢复引擎242可以扫描请求日志214并且用已请求标签重新标记每个重复数据位置。可以如上文关于图2b的244所描述的那样执行此扫描和重新标记。在438处,恢复引擎242可以扫描服务日志224并用已服务标签重新标记每个重复数据位置。可以如上文关于图2b的245所描述的那样执行此扫描和重新标记。在440处,恢复引擎242可以确定重复数据位置具有已请求标签。可以如上文关于图2b的246所描述的那样执行此确定。在442处,恢复引擎242可以识别请求日志214中标识该重复数据位置的请求日志条目216,从该重复数据位置恢复数据,并重新发布零拷贝请求230。可以如上文关于图2b的247所描述的那样执行请求日志条目216的识别。可以如上文关于图2b的248所描述的那样执行数据自重复数据位置的恢复。可以如上文关于图2b所描述的那样执行零拷贝请求230的重新发布。

尽管图4b的流程图示出了某些功能性的执行的具体顺序,但是方法420可以不限于该顺序。例如,流程图中连续示出的功能性可以以不同的顺序执行,可以同时执行或者部分同时执行,或者其组合。在一些示例中,本文关于图4b描述的功能性可以结合本文关于图1、图4a、图4c-4d和图5中的任何所描述的功能性来提供。

图4c是管理多节点集群的事务的示例方法450的流程图,该方法包括确定所有者节点没有故障、确定服务节点已经故障以及重新发布零拷贝请求。在下面分别参照图1和图3的多节点集群100和300的各种特征来描述方法450的执行。可以如方法450中所描述的那样一起利用多节点集群100和300的这些特征。也可以利用其它合适的系统(例如,图2的多节点集群200)来用于方法450的执行。另外,方法450的实现不限于这样的示例。

在图4c的示例中,方法450可以是多节点集群100和300的方法。在452处,请求引擎112可以在所有者节点110处接收包含数据的请求102。可以与如上所述的在图3的所有者节点310处的请求引擎312处接收请求302类似地执行此接收。也可以如上文关于图1a的请求引擎112所描述的那样执行此接收。

在454处,请求引擎112可以将数据存储在所有者节点110处,这类似于如上文关于图3的请求引擎312所述的请求引擎312可以将数据存储在所有者节点310处的方式。在456处,请求引擎112可以将数据复制在例如服务节点120上的重复数据位置处,这类似于如上文关于图3的请求引擎312所述的请求引擎312可以将数据复制在服务节点320上的重复数据位置308处的方式。

在458处,请求引擎112可以在请求日志114中生成标识重复数据位置的请求日志条目116。可以与如上文关于图3的请求引擎312所描述的在请求日志314中生成标识重复数据位置308的请求日志条目316类似地执行此生成。也可以如上文关于图1a的请求引擎112所描述的那样执行此生成。在460处,请求引擎112可以向服务节点120上的服务引擎122发布标识重复数据位置的零拷贝请求130。可以与如上文关于图3的请求引擎312所描述的向服务节点320上的服务引擎322发布标识重复数据位置308的零拷贝请求330类似地执行此发布。也可以如上文关于图1a的请求引擎112所描述的那样执行此发布。

在方法450的462处,服务引擎122可以接收零拷贝请求130并且在服务日志124中生成标识重复数据位置的服务日志条目126。可以与如上文关于图3的服务引擎322所描述的接收零拷贝请求330并且在服务日志324中生成标识重复数据位置308的服务日志条目326类似地执行此接收和生成。也可以如上文关于图1a的服务引擎122所描述的那样执行服务日志条目的此生成。

在464处,确定引擎132可以确定所有者节点110没有故障,并且可以确定服务节点120已经故障。可以与如上文关于图3的确定引擎322所描述的确定所有者节点310没有故障但服务节点320已经故障类似地执行此确定。也可以如上文关于图1a的确定引擎132所描述的那样执行此确定。基于所述确定,在466处,恢复引擎142可以扫描服务日志124并且用已服务标签重新标记每个重复数据位置。可以如上文关于图1b的144所描述的那样执行此扫描和重新标记。在468处,恢复引擎142可以确定重复数据位置具有已请求标签。可以如上文关于图1b的145所描述的那样执行此确定。在470处,恢复引擎142可以识别请求日志114中标识了该重复数据位置的请求日志条目116,并重新发布零拷贝请求130。可以如上文关于图1b的146所描述的那样执行请求日志条目116的识别。可以如上文关于图1b所描述的那样执行零拷贝请求130的重新发布。

尽管图4c的流程图示出了某些功能性的执行的具体顺序,但是方法450可以不限于该顺序。例如,流程图中连续示出的功能性可以以不同的顺序执行,可以同时执行或者部分同时执行,或者其组合。在一些示例中,本文关于图4c描述的功能性可以结合本文关于图1c、图2a-b、图4a-b、图4d和图5中的任何所描述的功能性来提供。

图4d是管理多节点集群的事务的示例方法480的流程图,该方法包括确定所有者节点已经故障、确定服务节点没有故障、恢复数据以及重新发布零拷贝请求。在下面分别参考图1和图3的多节点集群100和300的各种特征来描述方法480的执行。可以如方法480中所描述的那样一起利用多节点集群100和300的这些特征。也可以利用其它合适的系统(例如,图2的多节点集群200)来用于方法450的执行。另外,方法480的实现不限于这样的示例。

在图4d的示例中,方法480可以是多节点集群100和300的方法。在482处,请求引擎112可以在所有者节点110处接收包含数据的请求102。可以与如上所述的在图3的所有者节点310处的请求引擎312处接收请求302类似地执行此接收。也可以如上文关于图1a的请求引擎112所描述的那样执行此接收。

在484处,请求引擎112可以将数据存储在所有者节点110处,这类似于如上文关于图3的请求引擎312所述的请求引擎312可以将数据存储在所有者节点310处的方式。在486处,请求引擎112可以将数据复制在例如服务节点120上的重复数据位置处,这类似于如上文关于图3的请求引擎312所述的请求引擎312可以将数据复制在服务节点320上的重复数据位置308处的方式。

在488处,请求引擎112可以在请求日志114中生成标识重复数据位置的请求日志条目116。可以与如上文关于图3的请求引擎312所描述的在请求日志314中生成标识重复数据位置308的请求日志条目316类似地执行此生成。也可以如上文关于图1a的请求引擎112所描述的那样执行此生成。在490处,请求引擎112可以向服务节点120上的服务引擎122发布标识重复数据位置的零拷贝请求130。可以与如上文关于图3的请求引擎312所描述的向服务节点320上的服务引擎322发布标识重复数据位置308的零拷贝请求330类似地执行此发布。也可以如上文关于图1a的请求引擎112所描述的那样执行此发布。

在方法480的492处,服务引擎122可以接收零拷贝请求130并且在服务日志124中生成标识重复数据位置的服务日志条目126。可以与如上文关于图3的服务引擎322所描述的接收零拷贝请求330并且在服务日志324中生成标识重复数据位置308的服务日志条目326类似地执行此接收和生成。也可以如上文关于图1a的服务引擎122所描述的那样执行服务日志条目的此生成。

在494处,确定引擎132可以确定所有者节点110已经故障,并且可以确定服务节点120没有故障。可以与如上文关于图3的确定引擎322所描述的确定所有者节点310已经故障但服务节点320没有故障类似地执行此确定。也可以如上文关于图1a的确定引擎132所描述的那样执行此确定。基于所述确定,在496处,恢复引擎142可以确定重复数据位置具有已请求标签。可以如上文关于图1c的148所描述的那样执行此确定。在498处,恢复引擎142可以识别请求日志114中标识了该重复数据位置的请求日志条目116、从该重复数据位置恢复数据并且重新发布零拷贝请求130。可以如上文关于图1c的149所描述的那样执行请求日志条目116的识别。可以如上文关于图1c的150所描述的那样执行数据自重复数据位置的恢复。可以如上文关于图1c所描述的那样执行零拷贝请求130的重新发布。

尽管图4d的流程图示出了某些功能性的执行的具体顺序,但是方法480可以不限于该顺序。例如,流程图中连续示出的功能性可以以不同的顺序执行,可以同时执行或者部分同时执行,或者其组合。在一些示例中,本文关于图4d描述的功能性可以结合本文关于图1b、图2a-b、图4a-c和图5中的任何所描述的功能性来提供。

图5a是包括指令的示例机器可读存储介质的框图,所述指令用于用已请求标签和已服务标签来标记预先分配的存储器块中的重复数据位置,以及使用已请求标签和已服务标签中的至少一个来经由多节点集群中的事务管理系统恢复故障节点。

多节点集群500包括处理资源505和机器可读存储介质510,其包括(例如,编码有)可由处理资源505执行以实现本文关于图5a所描述的功能性的指令512、514、516、518、520、522、524、526、528和530。在一些示例中,存储介质510可以包括附加的指令。在其它示例中,本文关于指令512、514、516、518、520、522、524、526、528、530以及本文关于存储介质510所描述的任何附加的指令而描述的功能性可以至少部分地在电子电路(例如,经由包括用以实现如上所述的引擎的功能性的硬件和编程的任何组合的引擎)中实现。

如本文所描述的,多节点集群可以指代作为单个系统一起工作的多个节点。在一些示例中,多节点集群的每个节点可以利用相同的操作系统配置以及相同或相似的硬件配置。在其它示例中,多节点集群的节点可以利用相异的操作系统配置或相异的硬件配置。节点可以是适合于执行下面描述的功能性的任何联网设备或计算设备。如本文所使用的,节点可以是台式计算机、膝上型(或笔记本)计算机、工作站、平板计算机、移动电话、智能设备、交换机、路由器、服务器、刀片机箱、或包括处理资源的任何其它处理设备或装备。

多节点集群500可以包括所有者节点和服务节点。所有者节点可以指代多节点集群500内拥有或管理特定请求的节点。服务节点可以指代多节点集群500内服务或处理特定请求的节点。在一些示例中,多节点集群100内的节点可以经由计算机网络(例如,互联网、局域网(lan)、广域网(wan)等)进行通信。尽管本文描述了两个节点,但是多节点集群可以涉及多于一个的任何合适数量的节点。所有者节点和服务节点也可以位于单个节点或同一节点上。在这样的示例中,所有者节点和服务节点的功能性由同一节点执行,该节点既拥有并管理特定的请求又服务并处理所述请求。

指令512可以在所有者节点处接收请求。在本文描述的示例中,请求可以表示要由多节点集群500执行的事务或操作。在一些示例中,请求可以包含数据。例如,请求可以包含数据并且是要执行涉及所述数据的写入操作的请求。在一些示例中,指令512可以实现上文分别关于图1、图2和图3中的请求引擎112、请求引擎212和/或请求引擎312所讨论的功能性。

指令514可以在请求日志中生成请求日志条目。请求日志可以位于所有者节点处。也可以在多节点集群500的诸如服务节点之类的另一节点处创建请求日志的冗余拷贝。在一些示例中,可以在多节点集群500的每个节点处创建请求日志的冗余拷贝。在其它示例中,可以在多节点集群500的多个(但不是全部)节点处创建请求日志的冗余拷贝。在一些这样的示例中,请求日志可以被镜像到另一节点。请求日志也可以位于与多节点集群500分离或远离,但可由多节点集群500访问。

请求日志条目可以标识重复数据位置。在一些示例中,请求日志条目可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。如本文所述,重复数据位置可以指代可以由所有者节点、服务节点和恢复引擎(在必要时)访问的用于数据的重复或第二存储区域位置。重复数据位置可以位于所有者节点和服务节点二者能够访问的预先分配的存储器块内。如本文的示例中所使用的,预先分配的存储器块可以指代在其使用之前被分配了、并且可以由请求引擎、服务引擎和恢复引擎(在必要时)进行访问的存储器块。预先分配的存储器块可以是临时分配的或者被分配达固定的时间量。在一些示例中,重复数据位置可以位于服务节点处的预先分配的存储器块中。在其它示例中,重复数据位置可以位于多节点集群500内的另一节点(例如,除了服务节点之外的节点)处的预先分配的存储器块中。例如,在所有者节点和服务节点是同一节点的情况下,重复数据位置可以位于多节点集群500内的另一节点中。在一些示例中,指令514可以实现上文分别关于图1、图2和图3中的请求引擎112、请求引擎212和/或请求引擎312所讨论的功能性。

指令516可以用已请求标签来标记重复数据位置。已请求标签可以指示已经接收到与所标记的重复数据位置相关的请求。在一些示例中,指令516可以实现上文分别关于图1、图2和图3中的请求引擎112、请求引擎212和/或请求引擎312所讨论的功能性。指令518然后可以发布(例如,生成、发送)标识重复数据位置的零拷贝请求。如本文所述,零拷贝请求可以指代在没有中央处理单元(cpu)或处理资源将数据从一个存储器位置复制到另一存储器位置的情况下执行的事务或操作。在一些示例中,零拷贝请求可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。零拷贝请求可以是(至少部分地)基于针对其在请求日志中生成了请求日志条目的请求。在一些示例中,指令518可以实现上文分别关于图1、图2和图3中的请求引擎112、请求引擎212和/或请求引擎312所讨论的功能性。

指令520可以接收零拷贝请求并且可以(至少部分地)基于零拷贝请求来在服务日志中生成服务日志条目。服务日志可以位于服务节点处。也可以在多节点集群500的诸如所有者节点之类的另一节点上创建服务日志的冗余拷贝。在一些示例中,可以在多节点集群500的每个节点处创建服务日志的冗余拷贝。在其它示例中,可以在多节点集群500的多个(但不是全部)节点处创建服务日志的冗余拷贝。在一些这样的示例中,服务日志可以被镜像到另一节点。服务日志也可以位于与多节点集群500分离或远离,但可由多节点集群500访问。

服务日志条目可以标识重复数据位置。在一些示例中,服务日志条目可以用指针、地址或足以标识重复数据位置的其它机制来标识重复数据位置。在一些示例中,指令520可以实现上文分别关于图1、图2和图3中的服务引擎122、服务引擎222和/或服务引擎322所讨论的功能性。

指令522可以处理零拷贝请求。在一些这样的示例中,处理零拷贝请求可以涉及执行所请求的操作。在其它这样的示例中,例如在其中零拷贝请求可以涉及写入操作的示例中,指令522可以通过将零拷贝请求和/或要写入的数据传递给队列(例如,先进先出队列或优先级队列,其中分别按照数据在队列中的放置或按照数据的优先级来写入数据)来处理零拷贝请求。在一些示例中,指令522可以实现上文分别关于图1、图2和图3中的服务引擎122、服务引擎222和/或服务引擎322所讨论的功能性。

指令524然后可以用已服务标签来标记重复数据位置。已服务标签可以指示已经处理了与所标记的重复数据位置相关的零拷贝请求。在一些示例中,已服务标签可以替换较早的标签——已请求标签。在其它示例中,可以添加已服务标签而不更改、清除或移除已请求标签。指令524可以实现上文分别关于图1、图2和图3中的服务引擎122、服务引擎222和/或服务引擎322所讨论的功能性。

指令526可以确定所有者节点是否已经故障。在一些示例中,确定所有者节点是否已经故障可以涉及接收或监控错误或出错消息。在其它示例中,确定所有者节点是否已经故障可以涉及查询所有者节点。在一些示例中,指令526可以实现上文分别关于图1、图2和图3中的确定引擎132、确定引擎232和/或服务引擎332所讨论的功能性。

指令528可以确定服务节点是否已经故障,在一些示例中,确定服务节点是否已经故障可以涉及接收或监控错误或出错消息。在其它示例中,确定服务节点是否已经故障可以涉及查询服务节点。在一些示例中,指令528可以实现上文分别关于图1、图2和图3中的确定引擎132、确定引擎232和/或服务引擎332所讨论的功能性。

(至少部分地)基于所有者节点和服务节点中的至少一个已经故障的确定,指令530可以经由重复数据位置的已请求标签和已服务标签中的至少一个来恢复故障节点。在一些示例中,恢复可以涉及在故障或错误的时候检查、重放和/或分析请求日志条目和/或服务日志条目,以确保已请求操作或事务的效果在存储器中持续存在。在一些这样的示例中,恢复可以涉及撤消未完成的已请求操作或事务的效果,以确保未完成的已请求操作或事务的效果不会在存储器中持续存在。在一些示例中,指令530可以实现上文分别关于图1、图2和图3中的恢复引擎142、恢复引擎242和/或恢复引擎342所讨论的功能性。

图5b是当所有者节点和服务节点位于单个、故障节点上时用于恢复故障节点的示例指令的框图。基于所有者节点和服务节点是同一节点并且已经故障的确定,指令532可以扫描请求日志并且用已请求标签重新标记在请求日志中标识的每个重复数据位置。在一些示例中,扫描请求日志可以涉及访问和检查每个请求日志条目并分析每个请求日志条目中标识的每个重复数据位置。重新标记每个重复数据位置可以涉及移除或清除重复数据位置处的任何现有标记并用已请求标签替换它。在其它示例中,重新标记每个重复数据位置可以涉及添加已请求标签而不移除任何先前的标签。在又其它的示例中,重新标记每个重复数据位置可以涉及分析重复数据位置处的任何现有标签、确定现有标签是否是已请求标签并且如果不是则用已请求标签替换该标签。在一些示例中,指令532可以实现上文关于图2a和2b中的244处的恢复引擎242所讨论的功能性。

指令534可以扫描服务日志并用已服务标签重新标记在服务日志中标识的每个重复数据位置。在一些示例中,扫描服务日志涉及检查每个服务日志条目并分析每个服务日志条目中标识的每个重复数据位置。重新标记每个重复数据位置可以涉及移除或清除重复数据位置处的任何现有标记并用已服务标签替换它。在其它示例中,重新标记每个重复数据位置涉及添加已服务标签而不移除任何先前的标签。在又其它的示例中,重新标记每个重复数据位置包括分析重复数据位置处的任何现有标记、确定现有标记是否是已服务标签并且如果不是则用已服务标签替换该标签。在一些示例中,指令534可以实现上文关于图2a和图2b中的245处的恢复引擎242所讨论的功能性。

指令536可以确定任何重复数据位置是否依然标记有已请求标签。在一些示例中,可以检查每个重复数据位置以确定是否有任何重复数据位置具有已请求标签。在其它示例中,在每个重复数据位置可以具有若干标签的情况下,可以检查每个重复数据位置的最新或最后标签以确定它是否是已请求标签。在一些示例中,指令536可以实现上文关于图2a和图2b中的246处的恢复引擎242所讨论的功能性。

基于重复数据位置依然标记有已请求标签的确定,指令538可以识别标识了该重复数据位置的请求日志条目、从该重复数据位置恢复数据并且重新发布零拷贝请求。在一些示例中,识别重复数据位置可以涉及将该重复数据位置与请求日志中标识的重复数据位置进行比较。恢复数据可以涉及从该重复数据位置拷贝数据并将其存储到另一存储位置。重新发布零拷贝请求可以涉及(至少部分地)基于请求日志条目和恢复的数据来重新构建或重新生成零拷贝请求。在一些示例中,重新发布的零拷贝请求标识所述重复数据位置。在其它示例中,重新发布的零拷贝请求230可以标识在其新位置中的恢复数据。在一些示例中,指令538可以实现上文关于图2a和图2b中的247和248处的恢复引擎242所讨论的功能性。

在本文描述的示例中,处理资源可以包括例如被包括在单个设备中或跨多个设备分布的一个处理器或多个处理器。如本文所使用的,处理器可以是中央处理单元(cpu)、基于半导体的微处理器、图形处理单元(gpu)、被配置成检索和执行指令的现场可编程门阵列(fpga)、适用于存储在机器可读存储介质上的指令的检索和执行的其它电子电路中的至少一个,或其组合。图5a的处理资源505可以提取、解码并执行存储在存储介质510上的指令,以实行上文关于指令512、514、516、518、520、522、524、526、528和530描述的功能性。同样地,图5a的处理资源505可以提取、解码和执行存储在存储介质510上的指令,以实行上文关于图5b的指令532、534、536和538描述的附加功能性。在一些这样的示例中,存储介质510中的指令中的任何或全部可以是能够由处理资源505下载并安装的插件应用或应用的一部分。在其它示例中,可以以电子电路的形式、以编码在机器可读存储介质上的可执行指令的形式或其组合来实现存储介质510中的指令中的任何的功能性。所述存储介质可以位于执行所述机器可读指令的多节点集群中,或者位于远离所述多节点集群但可(例如,经由计算机网络)由所述多节点集群访问以供执行。在图5a和5b的示例中,存储介质510可以由一个机器可读存储介质或多个机器可读存储介质来实现。

如本文所使用的,机器可读存储介质可以是用以包含或存储诸如可执行指令、数据等的信息的任何电子、磁性、光学或其它物理存储装置。例如,本文所述的任何机器可读存储介质可以是随机存取存储器(ram)、易失性存储器、非易失性存储器、闪速存储器、存储驱动(例如,硬驱动)、固态驱动、任何类型的存储盘(例如,紧凑盘、dvd等)等中的任何,或其组合。此外,本文描述的任何机器可读存储介质可以是非暂时性的。在本文描述的示例中,一个或多个机器可读存储介质可以是物品(或制品)的一部分。物品或制品可以指代任何制造的单个组件或多个组件。

在一些示例中,图5a的指令512、514、516、518、520、522、524、526、528和530以及图5b的指令532、534、536和538可以是安装包的一部分,所述安装包在被安装时可以由处理资源505执行以实现上述功能性。在这样的示例中,存储介质510可以是诸如cd、dvd或闪速驱动之类的便携式介质,或者是由可以从其下载和安装所述安装包的服务器维持的存储器。在其它示例中,图5a的指令512、514、516、518、520、522、524、526、528和530以及图5b的指令532、534、536和538可以是插件应用或应用的一部分,所述插件应用或应用能够由处理资源505下载并安装在多节点集群500上。在又其它的示例中,图5a的指令512、514、516、518、520、522、524、526、528和530以及图5b的指令532、534、536和538可以是已经安装在包括处理资源505的多节点集群500y上的应用、多个应用或(一个或多个)组件的一部分。在这样的示例中,存储介质510可以包括诸如硬驱动、固态驱动等的存储器。在一些示例中,本文关于图5a和5b中的任一者所描述的功能性可以与本文关于图1-4中的任何所描述的功能性结合地提供。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1