具体实施方式
以下的说明内容是为了介绍本发明的主要原理给出而并不意味着限制本文所主张的发明理念。而且,其中介绍的特定特征能够与其他介绍的特征在每一种不同的可行排列组合中结合使用。除非本文中另有明确定义,否则所有术语都应被赋予其最广泛的可用解释,包括由说明书暗示的含义以及由本领域技术人员理解的和/或如词典、论 文等中所定义的含义。说明内容可能公开了在信息技术(IT)系统中提供数据冗余的若干优选实施例。尽管以下的说明内容为了清楚起见而根据这样的系统进行介绍并将本发明置于这样的场景中,但是应该牢记本文中的教导可以广泛地应用于任何类型的系统、设备和应用。
大多数分布式存储系统在主机或客户端都仅执行直写或协调奇偶校验的计算。协调奇偶校验的计算使得能够以类似于直写系统的方式进行恢复和协调。直写和协调奇偶校验的计算由于要在完全完成对应用的写入之前执行更多工作而具有类似的等待时间成本。因此,在降低奇偶校验更新的复杂性方面的改进就直接提高了分布式存储系统的性能和可靠性。
提供了一种用于在回写分布式冗余数据存储系统中维持奇偶校验一致性的读取其他项RO协议。在一个实施例中,RO协议采用具有快写的数据驱动RO奇偶校验更新协议以改进对跨系统节点散布的奇偶校验更新的处理,而且还要满足客户端对高可靠性和系统设计简易性的保证。
以下的术语被提供用于帮助理解进一步向下的说明内容。
节点:在数据存储系统中装有分布式冗余模块、处理器、内存、磁盘、电源等的计算机和磁盘封装。
主磁盘:节点内保留主机数据第一副本的磁盘。
主数据节点:将主磁盘与其他磁盘一起保留的节点。
用户数据:由主机或客户端写入存储系统以备可能在今后取回的数据。
奇偶校验:通过用于恢复丢失的用户数据的方案来计算的数据冗余性。
条:用户数据或奇偶校验的包(块)。
条带:通过奇偶校验计算相关联的数据条和奇偶校验条的集合(图1中示出了在以下进一步介绍的示例)。
奇偶校验节点:包括用于条带中数据条集合的其中一个奇偶校验数据条的节点。
RO:用于计算奇偶校验的读取其他项算法
从属数据:相对于一个数据值(例如数据条),从属数据是以对应奇偶校验值(例如奇偶校验条)编码的其他数据(例如其他的数据条)。
驱动器:在其高速缓存中具有新数据的驱动或开始奇偶校验更新协议的主数据节点。
用户数据被存储为条带集合,每一个条带都包括数据条和相关奇偶校验条的集合,条带的分布跨越多个对应的数据所有者节点和多个对应的奇偶校验所有者节点。对于每一个条带,数据所有者节点维持保留数据的第一副本的相关数据条,并且奇偶校验所有者节点维持奇偶校验条,奇偶校验条保留用于数据条集合的奇偶校验,在其中维持了奇偶校验的一致性。优选地,每一个奇偶校验都根据不同的奇偶校验计算公式算出。在示例性的RAID条带中,需要有n+1个节点来存储n个独立节点的数据。
图1示出了具有节点阵列(也就是N0,…,N4)的分布式冗余存储系统的条带结构,每一个节点都具有多个磁盘驱动器(也就是HDD0,…,HDD4),将来自除一个节点以外的所有其他节点的容量有效分组,并且在其余节点或者跨多个节点(如图所示)写入该容量的奇偶校验P(例如XOR)。例如,节点N0,…,N3中HDD0内的数据条D0,…,D3分别用于用户数据,并且节点N4中HDD0内的奇偶校验条P0-3则用于对应的奇偶校验数据(例如D0,…,D3的XOR)。数据条D0,…,D3和奇偶校验条P0-3构成了条带。如图所示,跨节点散布奇偶校验数据允许将读取奇偶校验数据的任务分散在若干节点,而不是仅仅一个节点上。在条带结构中的节点上写入需要针对该新数据计算一个或多个新的奇偶校验,并且在保留奇偶校验的每一个节点内的旧奇偶校验上写入新奇偶校验。在本示例中,相对于一个数据值(例如数据条D0),从属数据是以奇偶校验值(例如奇偶校验条P0-3)编码的其他数据(例如其他数据条D1,D2,D3)。对于磁盘上的信息仅为数据或者仅为奇偶校验没有限制。其他的实施例可以使磁盘位于包含用于一个条带的主要数据和用于另一个条带的奇偶校验数据的节点内。
根据数据驱动的RO奇偶校验更新协议,每一个主数据节点即使是相同的条带也通常都独立于其他的数据节点发挥作用,以保持其相关的奇偶校验条一致和正确。例如在图1中,主数据节点N0在主磁盘HDD0上拥有数据条D0并且驱动节点N4以用于其数据或奇偶校验相对于由D0,…,D3,P0-3构成的条带其余部分的一致性和可靠性。
图2示出了根据本发明的实施例的实施数据驱动RO奇偶校验更新协议的回写分布式冗余数据存储系统10。系统10被用于存储来自主机系统11和/或客户端系统12的数据。系统10包括多个节点13。每一个节点都包括处理器14、内存15、包括分布式冗余模块16的数据管理器以及存储设备例如硬盘驱动器17(譬如HDD0,…,HDDn)的阵列。在一种实施方式中,分布式冗余模块16包括用于由处理器执行的程序代码。在另一种实施方式中,分布式冗余模块包括固件。
每一个节点内的分布式冗余模块16实施数据驱动的RO奇偶校验更新协议,以用于在数据存储系统10包括的范围内维持奇偶校验的一致性。在使用快写(回写)动作的系统10中,奇偶校验的更新在完成任何快写操作之后的时刻执行。RO奇偶校验的更新仅根据数据(也就是主数据节点处的新数据和/或来自从属数据节点的集成有奇偶校验的数据)计算新的奇偶校验,而不计算新数据和现有数据之间的差异(变化量)。主数据节点中的每一个奇偶校验节点都向其他数据节点发送用于其从属数据的读请求消息,并且根据其接收的从属数据和主数据节点中的新数据计算出新的奇偶校验。
通常,对于条来说,拥有主磁盘的每一个节点13都负责用于驱动实现其数据或奇偶校验相对于该条中其余部分的一致性和可靠性。这与其中有一个节点负责用于全局水平或在每一条带基础上的一致性的数据存储系统有所不同。根据本文中介绍的数据驱动RO奇偶校验更新协议,由于每一个主数据节点通常都独立于其他的数据节点起作用以保持其相关的奇偶校验条一致和正确,因此相同条带的各节点之间的整体显式协调得以减少,并且通过更少外显的方式(例如以下进一步介绍的协议序列化)来执行协调。
对于本文中介绍的示例性实施方式,分布式冗余存储系统10(图2)可以对两种存储设备故障(磁盘或节点)容错。本领域技术人员应该意识到推广至更高级别的容错也落在本发明的保护范围内。每一个数据条都被编码为两个奇偶校验条。这可以推广至多于两个奇偶校验条以用于更高级别的容错系统。
数据驱动的RO奇偶校验更新协议使数据节点13能够(在内存中或磁盘上)保留用于条的至少两份数据副本(新的快写数据和集成有奇偶校验的数据)。数据驱动的RO奇偶校验更新协议是数据驱动的,因为它是由主数据节点对其奇偶校验节点发起的。每一个节点13都是用于某些数据的主数据节点和用于另外某些数据的奇偶校验节点,其中每一个这样的节点都必须能够执行每一种协议功能(驱动器、第一奇偶校验、第二奇偶校验等)。奇偶校验更新协议遵循参与者之间的转发或链式消息传送协议(也就是从主数据节点按特定顺序通过其每一个奇偶校验节点,而其响应则遵循相反的顺序)。奇偶校验更新协议在图2的每一个节点13中实施。每一个节点13都用作针对某些数据的主数据节点,并且用作针对某些其他数据的奇偶校验节点,每一个节点都能够执行每一种协议功能(驱动器、第一奇偶校验、第二奇偶校验等)。拥有数据的节点在使用快写能力的分布式存储系统10上启动奇偶校验数据更新协议,以计算用于恢复丢失数据的奇偶校验数据。奇偶校验数据更新协议包括:
a.消息转发协议
b.两个阶段:准备/锁定阶段和提交/解锁阶段
c.用于每一个奇偶校验节点处的新的奇偶校验计算的RO子协议
d.用于每一个主数据节点的专用奇偶校验节点转发顺序
RO子协议是需要更少资源(特别是磁盘I/O)的用于新奇偶校验的计算,特别是在“其他项”的读取次数严格小于使用读-修改-写子协议的比较方案所需次数时(例如用于两个容错纠错编码时为三次)。RO子协议的实施可以很好地适用于短条带上的纠错编码(以下进一步 提供了两个示例)。快写数据被镜像至编码该数据副本的所有奇偶校验节点(如果不是这样,那么对协议简单修改即可在第一步骤中实现该镜像)。
图3示出了实现RO奇偶校验数据更新协议的过程20的流程图,涉及保留数据条的主数据节点以及对应的保留用于该数据条的奇偶校验条的多个(例如两个)奇偶校验节点。过程20包括:
块21:在准备阶段,所述主数据节点(根据特定顺序)向其“第一奇偶校验节点”发送准备和锁定请求消息,其中第一奇偶校验节点将该请求转发至“第二奇偶校验节点”。
块22:主数据节点中的每一个奇偶校验节点都向其他的数据节点发送用于其从属数据的读取请求消息,并且根据其接收的从属数据和主数据节点中的快写数据(也就是新数据)计算出新的奇偶校验(并不计算新数据和现有数据之间的差异)。
块23:当第二奇偶校验节点已经准备好它的新奇偶校验时,第二奇偶校验节点就向第一奇偶校验节点发回确认(ACK)答复消息以指示“就绪”。当第一奇偶校验节点从第二奇偶校验节点接收到ACK并且也已经准备好它的新的奇偶校验时,第一奇偶校验节点就向主数据节点发送ACK以指示“就绪”。这样就结束了准备阶段。
块24:在提交/解锁阶段,主数据节点向第一奇偶校验节点发送提交消息,该消息被转发至第二奇偶校验节点。
块25:第二奇偶校验节点“提交”其新的奇偶校验值,根据由另一个主数据节点的更新来解锁其奇偶校验,并且向第一奇偶校验节点发回ACK以指示“完成”。提交意味着将奇偶校验的有效副本标记为“集成有奇偶校验的值”并且弃用先前的旧值。奇偶校验的“集成有奇偶校验的值”是包含其代表的所有数据的集成有奇偶校验的版本(并由此算出)的奇偶校验值。第一奇偶校验节点提交其新的奇偶校验,根据由另一个主数据节点的更新来解锁其奇偶校验,并且向主数据节点发回ACK以指示“完成”。主数据节点在收到第一奇偶校验节点的ACK之后根据更新解锁其新数据,将其新数据标记为集成有 奇偶校验并且使其旧副本无效。这样就完成了RO奇偶校验更新协议。
消息通信可以通过实施消息转发协议的通信线路、主机、连接节点的总线等完成。如果参与RO奇偶校验更新协议的除从属数据节点以外的节点(也就是主数据节点、第一奇偶校验节点或第二奇偶校验节点)在准备阶段期间故障,那么转发序列中最低的存留节点就利用存留节点启动中止序列。如果有节点在提交阶段期间故障,那么转发序列中最低的存留节点就利用存留节点重启提交序列。如果在每一个阶段期间有两个节点故障,那么唯一的存留节点就自己异常终止或提交。中止序列是转发消息链,类似于促使每一个存留节点将其状态回滚到启动奇偶校验更新协议之前状态的提交/锁定消息链。具体地,锁定被去除并且不提交新的奇偶校验,也没有新的数据被标记为集成有奇偶校验。
用于每一个主数据节点的奇偶校验节点中具体的转发消息顺序以及锁定/解锁的步骤被设置为,使得如果由共用一个或多个奇偶校验节点的两个或多个主数据节点同时启动协议,那么协议就是死锁和无饥饿性的(starvation free)。当在RO奇偶校验更新协议期间根据一个主数据节点将其奇偶校验锁定的奇偶校验节点从另一个奇偶校验节点接收到第一奇偶校验更新协议消息时,该奇偶校验节点可以(通过“中止/稍后再试”的响应)拒绝第二奇偶校验更新请求,或者可以保留第二消息直到完成其用于第一奇偶校验更新协议的解锁步骤为止,此时即可继续执行第二奇偶校验更新协议。
如果从属数据节点未能响应来自奇偶校验节点的用于从属数据的请求,那么奇偶校验节点可能就无法完成其有效奇偶校验值的计算。在此情况下,奇偶校验节点不必再在其准备阶段期间的答复中确认“就绪”。相反,它以“故障”通知作为回应。这样的故障通知被转发给主数据节点;作为响应,主数据节点启动“中止”消息链(而不是“提交”链)从而促使协议回滚到启动协议之前的系统状态,并且放弃所有的锁定和所有的有效数据。这就等价于在协议期间的故障 (例如节点故障或者从磁盘读取数据错误等)之后由任意节点发起的任何中止序列。
本发明的实施例提供了一种数据驱动协议以及锁定/转发/恢复。显式载荷和纠错编码的计算性质可以改变,正如本领域技术人员应该意识到的那样。
恢复协议由后继驱动器(也就是转发序列中最低的存留者)驱动。主数据节点是初始驱动器。如果该驱动器故障,那么转发链中的下一个节点就承担该角色。驱动器的角色是通过由提交阶段迫使RO奇偶校验更新协议前进或者通过由显式的中止阶段迫使RO奇偶校验更新协议回滚来完成RO奇偶校验更新协议。
在有故障之后,转发消息顺序中的最靠近(并且如果生存就包括)主数据节点的存留奇偶校验节点承担起用剩余的存留奇偶校验节点来恢复驱动器并完成或退出协议的角色。
如上所述,每一个主数据节点都能够(在内存中或磁盘上或在两者中)维持用于一条的至少两个数据版本。第一副本是快写副本,包括由主机或客户端写入存储系统内但是尚未集成到奇偶校验条内的新数据。第二副本是集成有奇偶校验的副本,该副本已经被加入确定奇偶校验值的数学关系式内。快写版本在奇偶校验更新协议完成时转换为在所有相关奇偶校验节点处的集成有奇偶校验的版本(并且也可以弃用先前的集成有奇偶校验的版本)。
类似地,每一个奇偶校验节点都维持其奇偶校验条的值的有效版本,其中包含有用于计算为该奇偶校验条的每一个数据条的当前集成有奇偶校验的值(每个确定该奇偶校验值的数学关系)。每一个奇偶校验节点还管理在奇偶校验更新协议期间被计算为中间值的有效副本。在(每一个奇偶校验节点看来的)奇偶校验更新协议已结束时,奇偶校验节点将有效副本转换为集成有奇偶校验的值并弃用先前的集成有奇偶校验的值。也可以在此时弃用计算中使用的任何快写数据和任何从属数据。
对于每一个主数据节点,依次存在其奇偶校验节点的定义顺序 关系。例如,如果主数据节点具有两个奇偶校验节点P0和P1,那么顺序关系可以是P0<P1或者P1<P0。因此,每一个主数据节点都具有第一奇偶校验节点和第二奇偶校验节点。定义的顺序关系可以对每一个或者部分(例如如果主数据节点共用相同的奇偶校验节点的话)主数据节点相同。顺序关系可以针对每一个主数据节点都不同(例如如果每一个主数据节点与另外的主数据节点相比都具有不同的奇偶校验节点对)。这种顺序关系组(每一个主数据节点一组)被专门用于整个条带,以避免同时启动RO奇偶校验更新协议的死锁或饥饿状态。该顺序取决于使用的具体纠错编码。
如上所述,奇偶校验更新协议包括准备/锁定阶段和提交阶段。在一种实施方式中,用于主数据节点的快写数据在对受影响的奇偶校验节点的快写过程期间已经被镜像处理(否则,在以下的第一步骤期间,快写数据作为第一消息中的负载发送)。准备阶段的进行如下所述。首先,主数据节点锁定其快写数据以免进行进一步的更新。主数据节点随后向第一奇偶校验节点无载荷地(上述情况除外)发送准备和锁定(“准备&锁定”)消息。在准备阶段,奇偶校验节点请求来自从属数据节点的从属数据并且直接计算奇偶校验(而不是根据变量和旧的奇偶校验计算)。
然后,第一奇偶校验节点进行三个动作。第一,它锁定其集成有奇偶校验的值以免被不同的主数据节点更新(只能同时运行一个这样的协议)。第二,第一奇偶校验节点向第二奇偶校验节点(无数据载荷地)转发“准备&锁定”消息。第三,第一奇偶校验节点向从属数据节点发送读取请求(相对启动该协议的主数据节点从属),请求其数据的集成有奇偶校验的副本。在接收到请求的集成有奇偶校验的信息之后,第一奇偶校验节点就将有效奇偶校验值计算为主数据节点数据值的快写值和集成有奇偶校验的从属数据值的数学组合(不破坏或利用当前集成有奇偶校验的值)。该组合通过数学公式(例如Reed-Solomon编码)确定,由此算出奇偶校验值。这后两步动作可以并行或串行地进行。
在从第一奇偶校验节点接收到消息之后,第二奇偶校验节点锁定其集成有奇偶校验的值以免被不同的主数据节点进一步更新,向其从属数据节点发送读取请求,并且在接收到来自从属数据节点的答复之后,第二奇偶校验节点也通过主数据节点数据值和集成有奇偶校验的从属数据值的数学组合来计算其新的有效奇偶校验值(用于每一个奇偶校验节点的从属数据节点可以相同或者也可以不同)。在完成后,第二奇偶校验节点就向第一奇偶校验节点发出“就绪”的确认答复。在第一奇偶校验节点已经完成其任务并且接收到“就绪”的确认答复时,第一奇偶校验节点就将“就绪”的确认答复转发返回给主数据节点。在主数据节点处接收到“就绪”的确认答复完成了锁定/准备阶段。
在提交阶段,主数据节点向第一奇偶校验节点发送“提交”请求消息,第一奇偶校验节点依次将该请求转发至第二奇偶校验节点。在收到请求后,第二奇偶校验节点将其有效奇偶校验值转换为其集成有奇偶校验的值并且用“完成”的确认答复来响应第一奇偶校验节点。第二奇偶校验节点还根据更新解锁其集成有奇偶校验的值。第一奇偶校验节点在接收到“完成”的确认答复之后也将其有效奇偶校验值转换为集成有奇偶校验的值并且同样将其解锁。第二奇偶校验节点然后向主数据节点发送最终的“完成”确认答复。主数据节点将其数据的快写版本转换为其集成有奇偶校验的版本并将其解锁(允许其接受新的快写数据)。这样就完成了提交/解锁阶段和奇偶校验更新协议。
存在两类节点故障:在RO奇偶校验更新协议中直接涉及的节点(主数据节点及其奇偶校验节点)故障以及辅助节点(从属数据节点)故障。如果辅助节点在将请求的数据返回给奇偶校验节点之后故障,那么不需要采取任何动作。如果辅助节点在返回请求数据之前故障,那么请求的奇偶校验节点就无法完成其准备阶段,其中奇偶校验节点在准备阶段期间返回“错误”(然后是由驱动器节点执行的中止阶段)。
如果奇偶校验更新协议中的一个或两个关键参与的奇偶校验节点完全故障或因为其在奇偶校验更新协议期间不能再执行主数据节点或者第一或第二奇偶校验节点的功能而故障(其他节点的故障不会影响奇偶校验更新协议),那么后继驱动器节点就用存留节点来处理恢复。在准备/锁定(“准备&锁定”)阶段期间,节点的故障导致回滚到初始状态,其中后继驱动器节点用存留节点来启动转发的中止序列。例如,如果第一奇偶校验节点故障,那么主数据节点就是后继驱动器节点并且向第二奇偶校验节点发送中止消息。如果第二奇偶校验节点故障,那么主数据节点同样是后继驱动器节点并且向第一奇偶校验节点发送中止消息。如果主数据节点故障,那么第一奇偶校验节点就是后继驱动器节点并且用第二奇偶校验节点启动中止序列。后继驱动器节点是转发顺序中最接近(并且可能包括)主数据节点的存留者。类似地,在提交阶段期间,节点故障导致协议前滚。(如上所述的)后继驱动器节点重启提交序列。如果只有一个节点存留,那么它就自主地执行恢复(在准备/锁定阶段中止)或提交(在提交阶段)。本领域技术人员应该意识到推广至更高级别的容错也落在本发明的保护范围内。
在节点故障之后,可能有存留节点(特别是下游节点)尚未接收到开始协议的启动消息。因此它可能没有用于其接收到的中止消息的环境。这是可以接受的,原因在于该情况表明节点正处于目标状态。类似地,如果在锁定阶段期间发生节点故障,那么第二提交消息可能会到达下游的节点。这同样是可以接受的,原因在于节点已经在锁定阶段期间完成了提交并且处于期望状态。
根据奇偶校验更新协议各种情况之间的交互,奇偶校验更新协议期间在主数据节点处,没有新的快写数据可以被集成到用于计算变量值的快写版本内。存在可选的实施例,第一,附加的缓冲空间可以被用于保留供条使用的其他快写数据,实际上就有在奇偶校验更新协议中并未涉及的用于快写数据的第三缓冲空间。第二,快写版本上的锁定只需要在锁定阶段开始时设置。为了适应这一点,如果新的快写数据在准备/锁定阶段期间到达主数据节点,并且随后取代用提交阶 段来完成协议,主数据节点可以通过显式的中止阶段来中止协议。这类似于按消息排序并答复的提交阶段,但是中止指令通知奇偶校验节点弃用它们的有效奇偶校验值并且不再将它们转换为集成有奇偶校验的值(协议回滚到初始状态)。
如果(第一或第二)奇偶校验节点在处理来自第一主数据节点的奇偶校验更新协议期间接收到来自第二主数据节点的奇偶校验更新请求(“准备&锁定”),那么奇偶校验节点可以延迟对新请求的响应直到第一奇偶校验更新协议完成为止,或者也可以拒绝第二请求,表明有奇偶校验更新协议正在进行。第二主数据节点可以在晚些时候重新尝试协议。用于每一个主数据节点的奇偶校验节点的具体顺序防止了延迟情形中的饥饿和拒绝情形中的死锁。在任何一种情况下,第一奇偶校验更新协议都能够得到完成。
奇偶校验更新协议可以扩展至更高级别的容错。如果数据条被编码为三个或更多个奇偶校验节点上的三个或更多个奇偶校验值,那么奇偶校验更新协议就再次将每一个奇偶校验节点按特定方式排序。随后在每一个准备/锁定阶段和提交阶段中根据用于该主数据节点的特定顺序将协议从主数据节点转发至每一个奇偶校验节点。如果一个或多个节点在协议期间故障,那么后继存留节点(由最接近并且可能包括主数据节点的节点确定)驱动实现协议的完成(也就是在准备/锁定阶段期间中止和在提交阶段期间提交)。
以下介绍用于维持奇偶校验一致性的读-修改-写的两种示例性实施方式。
RAID6
图4示出了示例性的分布式数据存储系统30,示出了在三个数据节点(N0到N2)和两个奇偶校验节点N3,N4上用于RAID6纠错编码的数据和奇偶校验的关系,其中容错度为2。RAID6提供了具有条带组的存储系统以及对两个磁盘驱动器故障具有容错的双重分布式奇偶校验(存储系统在一个或两个磁盘驱动器故障时能够继续工作)。用 于每一个奇偶校验节点的从属数据节点是相同的,原因在于P和Q都是根据D0,D1和D2算出的。
RO奇偶校验更新协议在数据节点数量为两个或三个时可有效用于该RAID6纠错编码。图4示出了三个数据条D0到D2。根据本发明的实施例,用三个数据条D0到D2的数学公式(例如异或)来计算P奇偶校验。而且,通过不同的数学公式(例如Reed-Solomon编码)计算出用于三个数据条D0到D2的Q奇偶校验。也可以使用其他的数学公式。在该纠错编码中,共有三个主数据节点和两个奇偶校验节点。用于每一个奇偶校验节点的转发顺序都是相同的:P<Q,也就是说在转发顺序中P先于Q(替代顺序Q<P也是可行的)。也可以有对于某些主数据节点顺序为P<Q而对于另一些则为Q<P的变形。通用顺序(例如P<Q)足以避免死锁或饥饿。
图5示出了根据本发明的实施例的用于由图4中的系统30实施的奇偶校验更新协议的事件序列40(从上到下),其中主数据节点N0启动奇偶校验更新协议。表达式{d0'}表示快写数据。在该示例中,快写数据被镜像在三个不同节点上。表达式QOR代表用于计算或更新Q奇偶校验值的数学公式。节点N1和N2是提供从属读出数据的辅助节点。用于从属数据的读取请求独立地来自两个奇偶校验节点N3和N4,并且在每一个节点N1和N2处都只需要高速缓存一次磁盘读取。
表达式[d0],[d1]和[d2]表示集成到由[p0-2]和[q0-2]表示的奇偶校验中的数据版本。表达式p0-2'表示奇偶校验节点P上维持的新奇偶校验的有效副本。类似地,表达式q0-2'表示奇偶校验节点Q上维持的新奇偶校验的有效副本。DiskRead[d1]和DiskRead[d2]均表示从磁盘中读取相应的集成有奇偶校验的数据条的操作。表达式Read[d1]和Read[d2]表示从奇偶校验节点到相应从属数据节点发送从属数据的集成有奇偶校验的副本的消息请求。表达式Reply[d1]和Reply[d2]是具有包含相应从属数据的载荷的返回消息。表达式Prep&Lock表示两节点之间请求锁定奇偶校验条的消息。表达式lock[d0'],lock[p0- 2],lock[q0-2],unlock[d0'],unlock[p0-2'],unlock[q0-2']分别表示锁定和解锁指示数据条或奇偶校验条的动作。表达式p0-2'=XOR(d0',d1,d2)和q0-2'=QOR(d0',d1,d2)分别表示由此根据d0',d1和d2算出p0-2'以及根据d0',d1和d2算出q0-2'的数学关系式。表达式Ready表示对Prep&Lock的(良好)确认;表达式Done表示对Commit请求消息的(良好)确认。
减少网络流量的一种可选实施方式可以实施如下。在奇偶校验节点N3向奇偶校验节点N4转发“Prep&Lock”请求之前,奇偶校验节点N3首先向节点N1和N2发出用于从属数据的读取请求。奇偶校验节点N3随后计算新的Q奇偶校验的有效值(代表奇偶校验节点N4)以及其自己的有效值。奇偶校验节点N3随后将“Prep&Lock”请求消息转发至具有包含Q有效奇偶校验值的载荷的奇偶校验节点N4。然后奇偶校验节点N4根据指示“就绪”的确认消息立即执行锁定并对奇偶校验节点N3做出响应。奇偶校验节点N3随后转发ACK返回给主数据节点N0。这样就得到了较低的网络流量,而且在准备阶段结束时保留了与以上相同的状态。
图5表示事件序列示意图,其中每一条垂直线都表示存储系统中保留的并且对具有3个数据条以及奇偶校验P和Q(RAID6(3+P+Q))的RAID6条带中的数据负责的节点。存储系统中不涉及该条带的其他节点并未给出。标记为N0,N1和N2的竖条表示每一个节点都保留条带内三个数据条中的一条。标记为P和Q的竖条分别表示保留P奇偶校验值和Q奇偶校验值分别用于条带的节点。在标记下方是一个或两个符号表达式。表达式[d0]表示用于存储在节点N0上的条0的集成有奇偶校验的数据版本。类似地,表达式[d1]和[d2],p[0-2]和[q0-2]分别表示数据条d1和d2以及P奇偶校验条p0-2(由集成有奇偶校验的数据d0,d1,d2算出)和Q奇偶校验条q0-2(也是由集成有奇偶校验的数据d0,d1,d2算出)的集成有奇偶校验的版本。N0,P和Q下方的表达式{d0'}表示用于条0的已经复制在三个节点N0,P和Q上但是尚未集成到奇偶校验值内的新快写数据。
在图5中,箭头表示从位于箭头尾部的节点向位于箭头头部的节点发送的通信消息。厚箭头表示包含数据(更一般地是大量载荷)的消息,并且薄箭头表示没有大量载荷的控制消息或响应。横跨中间部分的虚线表示在协议的两个阶段之间的转换。在第一阶段(“准备阶段”),协议内的中断通过协议的回滚来处理。在第二阶段(“提交阶段”),中断通过协议的前滚来处理。底部的注释表示本发明实施例中用于RAID6版本协议的“转发规则”,正如指针“N0发起,N0->P->Q”所作的那样(也就是数据节点通过送往P再转发到Q的第一消息启动协议(响应遵循相反的路径))。节点N1和N2是仅为协议提供读取数据的辅助节点。时间在图5中被自上而下地表示。时间间隙的相对大小并不必然按比例代表时间。它们仅表示时间的相对顺序。
协议由节点N0发起并且如下所述地进行。在第一阶段(准备),N0锁定条0数据的{d0'}版本(“lock[d0']”)以免(例如被新的主机写入)进一步更新。这样就确保了d0'的值不会发生改变,直到协议完成将当前的d0'集成到奇偶校验中。协议的变形可以放松该要求。可以将{d0'}标记为“正在准备用于奇偶校验集成”。如果新的写入在准备阶段期间到达,那么协议可以安全地中止(回滚)。只有在提交阶段期间才需要{d0'}的绝对锁定。
一旦lock[d0']就位,N0就向P奇偶校验节点发送消息(“Prep&Lock”)。该消息表明:(a)开始准备{d0'}的奇偶校验集成,以及(b)锁定奇偶校验[p0-2]以使其他节点能够使用相同的协议继续。在该启动消息中并不发送大量数据。节点P随后进行三个动作:根据指令锁定[p0-2],向节点Q转发消息并且向辅助节点N1和N2发送读取请求(“Read[d1]”和“Read[d2]”)请求其条数据的集成有奇偶校验的版本的副本。在从P接收到“Prep&Lock”消息之后,节点Q执行以下类似于P的动作。节点Q根据更新锁定其[q0-2]并向辅助节点N1和N2发送用于其集成有奇偶校验的数据的读取请求消息。当协议的转发规则总是通过P发送第一消息时,Q处的锁定步骤并不 是必要的,原因在于P处的锁定将排除有任何冲突的消息到达Q(例如在图7中并不是这种情况)。
当Q已经接收到所有的请求读取响应时,它根据新的d0'以及接收到的d1和d2利用用于Q奇偶校验值的QOR函数计算新的q0-2'。此时,Q向节点P发送“就绪”响应。类似地,当P已经接收到其所有的请求读取响应时,它根据新的d0'以及接收到的d1和d2利用简单的XOR函数计算新的值p0-2'。在完成该计算并且从Q接收到“就绪”响应后,节点P向初始数据节点N0发送“就绪”响应。N0在从P接收到该响应之后就完成其准备阶段的部分,并且完成了准备阶段。
提交阶段以从N0到P再转发至Q的消息“Commit”开始。在到达Q时,Q提交(转换)算出的副本q0-2'作为“集成”副本,解锁其奇偶校验值(使得能够进行其他更新)并且向P发回“完成”的响应消息。Q现在就已完成了它在协议中的任务。P在从Q接收到“完成”响应后执行类似的动作:提交(转换)算出的副本p0-2'作为“集成”副本,解锁其奇偶校验值(使得能够进行其他节点的奇偶校验更新协议)并且对N0以“完成”消息作为响应。最后,N0在从P接收到该“完成”响应后就提交其d0'副本作为“集成副本”并且解锁d0',允许将新的更新写入相同的地址位置。这样就完成了提交阶段(也结束了协议)。
该协议的两种变形可以被用于降低准备阶段中的网络带宽要求。在第一种变形中,P向Q转发“Prep&Lock”消息并且Q锁定其奇偶校验q0-2和响应以“锁定就位”。Q不再发出任何用于从N1和N2中获取数据的读取指令。当P从N1和N2接收到读取的数据时,P(代表Q)计算p0-2'和q0-2'。然后P将计算出的值q0-2'发送给Q,Q响应以“就绪”消息。在第二种变形中,P不直接转发“Prep&Lock”请求。而是,它等待来自N1和N2的读取数据,(同样代表Q)计算p0-2'和q0-2'的值。P随后将q0-2'数据追加至“Prep&Lock”消息再将其转发给Q。Q的响应与前面一样是“就 绪”消息(无需再向N1和N2发送读取请求)。此时,P和Q的状态与图5中恰好在向N0发送P的“就绪”响应之前的状态相同。协议的其余部分如上所述地完成。这两种变形降低了网络带宽要求:只向Q发送一条大容量消息(q0-2'的计算值)而不是两条大容量消息([d1]和[d2])。对于更宽的RAID6条带,在这些变形中仍然只要向Q发送一条大容量消息,但是增加了来自其他辅助节点的读取响应消息。
WEAVER
图6示出了示例性的分布式冗余数据存储系统50,示出了在四个节点(N0到N3)上用于Weaver编码的数据条D0到D3和奇偶校验(P23,P03,P01,P12),容错度为2。Weaver编码的设计功能包括:(a)在相同的条上安置数据和奇偶校验块,(b)约束奇偶校验的程度以及(c)平衡和对称性。这些节点通常都不是最大可分离距离(MDS),但是在奇偶校验的程度受限的所有节点中具有最优的存储效率。在JamesLee Hafne的“WEAVER Codes:Highly Fault Tolerant Erasure Codes for Storage Systems”一书中介绍了Weaver编码,本书于2005年12月公开在:
http://www.usenix.org/cvents/fast05/fech/ful_papers/hafner_weaver/hafner_weaver.pdf,。这种纠错编码可以有效地用于RO奇偶校验更新协议,原因在于每一个奇偶校验值都被计算为仅两个数据值的XOR(异或)。
在图6中,每一个节点都在该纠错编码中扮演三个角色。每一个节点都是主数据节点并且每一个节点也是用于其他两个主数据节点的奇偶校验节点。在该纠错编码中,每一个数据节点都具有需要与之协调的两个奇偶校验节点。两个奇偶校验节点对于每一个主数据节点来说是不同的。用于每一个主数据节点的第一和第二奇偶校验节点的顺序相对于由节点保留的奇偶校验被词典式(lexicographically)地执行。相应地,由于N0保留奇偶校验P01,N1保留P03,N3保留P12且N0保留P23,因此有N2<N1<N3<N0。每一个数据节点都向该顺序中具有用于该数据节点的奇偶校验的最低奇偶校验节点发送其第一奇偶校验更新协议消息,并且最低的奇偶校验节点将该协议消息 转发至下一个具有用于该数据的奇偶校验的最低奇偶校验节点。具体地,相继进行以下的消息流通:
N0向N2发送消息再转发至N1,
N1向N2发送消息再转发至N3,
N2向N3发送消息再转发至N0,
N3向N1发送消息再转发至N0。
用于每一个奇偶校验节点的从属数据都是不同的。P01根据D0和D1算出,并且P03根据D0和D3算出。因此,对于(节点N2上的)P01,相对于D0的从属数据是D0,而对于(节点N1上的)P03,用于D0的从属数据则是D3。也就是说,每一个奇偶校验节点都可以看到用于D0的不同的从属数据段。
图7根据本发明的实施例示出了用于由图6中的系统50实施的奇偶校验更新协议的事件序列60(从上到下),其中主数据节点N0启动协议。表达式{d0'}表示快写数据。在该示例中,快写数据被镜像在三个不同节点上。
图7表示本发明用于WEAVER编码(4个节点上的两个容错)的实施例。图7中的结构与图5类似。竖条表示系统中的节点,但是在此情况下仅有标记为N0,N1,N2和N3的四个节点。时间顺序被自上而下地表示,箭头指示消息,其中双箭头指示(具有载荷的)大容量消息,而单箭头指示(没有大容量载荷的)控制消息。对于该编码,每一个节点都有既用于数据节点功能又用于奇偶校验节点功能的责任。类似于图5,对于数据节点N0,N2扮演了P的角色并且N2扮演了Q的角色。N2和N1保留根据数据d0算出的奇偶校验值(分别是p01和p03)。用于N0的转发规则是N0->N2->N1。如图7的底部所示,转发规则对于每一个数据节点都不同(这与图5形成了对比,图5中RAID6中用于每一个数据节点的顺序总是相同的)。例如,节点N1首先向N2发送其奇偶校验更新协议消息并随后再向N3发送。规则的一个实施例是通过奇偶校验标记以节点的词典式排序确定。其他的实施例也是可行的,只要没有循环即可。
在节点标记下方是表示集成有奇偶校验的数据和奇偶校验版本的符号。例如,在节点N0上,[d0,p23]表示N0负责作为用于条0上数据的主拥有者并且还作为用于奇偶校验p23=XOR(d2,d3)的奇偶校验拥有者。中括号[]表示这两个值是集成有奇偶校验的值。类似地,用于N1的表达式[d1,p03],用于N2的[d2,p01]和用于N3的[d3,p12]表示d1,d2和d3的集成有奇偶校验的值以及奇偶校验值p03=XOR(d0,d3),p01=XOR(d0,d1)和p12=XOR(d1,d2)。标记下方用于N0,N1和N2的表达式{d0'}表示这些节点中的每一个都保留了用于条0(d0')的尚未集成奇偶校验的新数据版本。
图7中序列示意图的其他说明内容类似于图5,只要用N2代替P和用N1代替Q,用p01代替p0-2和用p03代替q0-2,以及用简单的XOR代替QOR即可。只有两处明显的不同:(a)对于每一个奇偶校验节点只需要一个辅助节点读取请求;以及(b)为了效率可以合并某些消息。这是为了更加清楚起见而在以下详细介绍的内容。
在图5中,节点N0启动协议以通过首先锁定其副本{d0'}免于更新来更新其奇偶校验。然后向其第一奇偶校验节点N2发送“Prep&Lock”请求(保留p01)。节点N2锁定其奇偶校验免于更新并按照N0的转发顺序将“Prep&Lock”消息转发至第二奇偶校验节点(N1保留p03)。为了有助于更加高效,N2在“Prep&Lock”消息中包括用于它需要从N1获取的辅助数据的读取请求也就是“Read[d1]”,用于集成有奇偶校验的版本N1中的数据d1的读取请求(这可以通过单独的消息完成)。在接收到该消息后,节点N1执行三个动作(顺序并不重要):(a)锁定其奇偶校验p03免于更新,(b)执行磁盘读取(“DiskRead[d1]”)以及(c)向其辅助节点N3发送读取请求(“Read[d3]”)。节点N3从磁盘中读取数据[d3]并且作为响应将数据发送返回给请求者N1。在收到后,N1根据新数据d0'和接收到的数据d3计算新的奇偶校验值p03'。节点N1随后向节点N2发送响应以使初始的“Prep&Lock+Read[d1]”消息指示“就绪”(已经完成p03'的准备)并且在消息的读取部分中包括大容量数据d1(如果作为 单独消息发送,那么该双重响应可以作为单独的响应完成)。在根据新数据d0'和接收到的数据[d1]计算出其新的奇偶校验值p01'之后,节点N2将“就绪”响应发送返回给初始的请求者N0。这样就完成了协议中的准备阶段。协议中的提交阶段与图5中的上述内容相同,只要用N2代替P,用N1代替Q,用p01'代替p0-2'和用p03'代替q0-2'即可。
图7中的非循环顺序满足了避免死锁或饥饿的条件(使两个并发的奇偶校验更新协议中至少有一个得以继续,无论另一个是被拒绝还是暂停均可)。
返回参照图4和图6,与图4中的RAID6示例相反,对于图6中的Weaver实施方式来说,节点N1和N2(保留用于节点N0中数据的奇偶校验)具有不同的从属数据要求。另外,节点N2需要节点N1中的从属数据(节点N1需要节点N3中的从属数据)。而且,在图7中,用于从节点N2到节点N1的从属数据的读取请求被与“Prep&Lock”请求合并。这并不是必须的,但是这样做确实以将用于从属数据的读取请求串行化为代价将消息开销最小化。在一种可选的实施方式中,节点N2可以仅向节点N1转发“Prep&Lock”请求。然后每一个节点N1和节点N2可以同时发出其自身的用于从属数据的读取请求。当节点N1接收到读取响应并且算出其有效奇偶校验值时,它就能用指示“就绪”的确认消息响应来自节点N2的“Prep&Lock”请求消息。当节点N2已经从节点N1接收到“就绪”响应和从属读取响应并且也已经算出其有效奇偶校验值时,那么节点N2可以用指示“就绪”的确认消息响应节点N0,完成RO奇偶校验更新协议的准备阶段。
在表达式[d0,p23],[dl,p03],[d2,p01]和[d3,pl2]中,子表达式d0,d1,d2和d3表示集成到其相应奇偶校验版本中的数据版本。子表达式p23,p03,p01和p12是奇偶校验、用于数据的集成奇偶校验以及指示编号标签(因此p01是用于d0和d1的集成奇偶校验)。表达式p03'表示节点N1上维持的新奇偶校验的有效副本,节点N1是用于d1的 主数据节点以及用于d0的第二奇偶校验节点和用于d3的第一奇偶校验节点。
类似地,表达式p01'表示节点N2上维持的新奇偶校验的有效副本(用于d2的主数据节点以及用于d0和d1的第一奇偶校验节点)。表达式Read[d1]和Read[d3]表示从奇偶校验节点到相应从属数据节点发送从属数据的集成有奇偶校验的副本的消息请求。表达式Reply[d1]和Reply[d3]是具有包含相应从属数据的载荷的返回消息。DiskRead[d1]和DiskRead[d3]均表示从磁盘中读取相应的集成有奇偶校验的数据条的操作。表达式Prep&Lock表示两节点之间请求锁定相关数据或奇偶校验条的消息。
表达式lock[d0'],lock[p03],lock[p01],unlock[d0'],unlock[p03'],unlock[p01']分别表示锁定和解锁指示数据条或奇偶校验条的动作。表达式p03'=XOR(d0',d3)和p01'=XOR(d0',d1)分别表示由此根据d0'和d3算出p03'以及根据d0'和d1算出p01'的数学关系式。图7底部的箭头示意图指出了用于每一个主数据节点到其第一和第二奇偶校验节点的转发顺序。表达式Ready表示对Prep&Lock请求的(良好)确认;表达式Done表示对Commit请求消息的(良好)确认。
因此,用于在具有快写的分布式冗余存储系统上更新奇偶校验的数据驱动的RO协议提供了以下的特点。用于每一个主数据节点的奇偶校验顺序避免了在一个奇偶校验节点处重叠两个RO奇偶校验更新协议的并发运行,同时还允许对至少一个奇偶校验协议的转发过程。在一个示例中,启动主数据节点首先锁定用于三个节点(自身和另外两个)的奇偶校验更新协议。来自发起节点的第一消息被引导至其余节点的协议链中的节点。到达相交节点的第一组消息(也就是准备和锁定阶段中的第一组转发消息(没有确认答复))占据支配地位,而其他消息则在第一阶段(也就是准备和锁定阶段)被延迟或拒绝。在任何一个奇偶校验节点都不重叠的两个RO奇偶校验更新协议可以同时(并发)运行。在RO奇偶校验更新协议期间出现故障时,在准备阶 段,RO奇偶校验更新协议回滚,其中转发顺序中的后继节点明确地在该阶段期间中止协议(所有工作都作废并且在所有节点稳定后再重试)。而且,在提交阶段,协议通常前滚,其中转发顺序中的后继节点重新驱动提交协议以确保存留节点中的一致性。
RO奇偶校验更新协议可应用于任意的两个或多个容错纠错编码,只要合理定义用于每一个主数据节点的奇偶校验顺序即可。如上所述,由于RO奇偶校验更新协议中只有两种类型的节点(也就是主动参与节点和辅助节点),因此辅助节点在对应RO协议操作期间的故障就会导致立刻回滚。这是因为RO协议由于辅助节点中的数据不可用而无法完成。主动参与节点的故障导致回滚(在准备阶段期间)或前滚(在提交阶段期间)。
RO奇偶校验更新协议不需要对协议期间发生故障并更换的任何节点状态的相互作用或了解或恢复。原始协议中的存留节点只能是(回滚或前滚地)完成了协议的节点。
存储系统中维持的新数据快写副本的数量或者将这些副本在哪里维持并不重要,原因在于副本无需保留在奇偶校验节点处。如果一个或多个新数据的快写副本被保留在用于该数据的一个或多个奇偶校验节点中,那么在奇偶校验节点处的奇偶校验更新协议一旦完成就可以废弃这些副本。如果一个或多个新数据的快写副本被保留在存储系统中的其他地方,那么从主数据节点发送到快写容器的显式“可弃用”消息就使得能够释放这些副本所用的资源。如果新数据的快写副本没有保留在每一个奇偶校验节点处,那么从保留该副本的任何一个节点发出的准备&锁定消息即可在其载荷中包含新数据,由此将该副本提供给没有保留新快写数据的奇偶校验节点。
正如本领域技术人员所知的那样,以上根据本发明优选实施例介绍的上述示例性体系结构能够以多种方式实施为例如用于由处理器执行的程序指令、软件模块、微代码、计算机可读取介质上的计算机程序产品、逻辑电路、专用集成电路、固件等。本发明的实施例可以采用完全为硬件的实施例、完全为软件的实施例或者同时包含硬件和 元件元素的实施例的形式。在优选实施例中,本发明被以软件实施,其中包括但不限于固件、常驻软件、微代码等。
而且,本发明的实施例可以采用计算机可用或计算机可读取介质可访问的计算机程序产品的形式,提供用于由计算机、处理设备或任意指令执行系统使用或与之相结合的程序代码。对于本说明书来说,计算机可用或计算机可读取介质可以是能够包含、存储、通信或传输程序用于由指令执行系统、装置或设备使用或阈值相结合的任意装置。介质可以是电、磁、光或半导体系统(或装置或设备)。计算机可读取介质的示例包括但不限于半导体或固态存储器、磁带、可移除的计算机磁盘、RAM、只读存储器(ROM)、刚性磁盘、光盘等。光盘的现有示例包括光盘只读存储器(CD-ROM)、光盘读/写设备(CD-R/W)和DVD。
I/O设备(包括但不限于键盘、显示器、点击设备等)可以直接或通过中介I/O控制器连接至系统。网络适配器也可以被连接至系统以使数据处理系统能够通过中介的专用网络或公用网络被连接至其他的数据处理系统或远程打印机或存储设备。调制解调器、线缆调制解调器和以太网卡指示当前可用的几种网络适配器类型。在以上的说明中列举了多种具体的细节内容。但是应该理解无需这些具体细节即可实现本发明的实施例。例如,可以更换公知等价的部件和元件以取代本文中介绍的那些部件和元件,并且类似地,可以更换公知的等价技术以取代公开的特定技术。在另一些情况下,并未详细示出公知的结构和技术以避免混淆对本说明书的理解。
术语“计算机程序介质”、“计算机可用介质”、“计算机可读取介质”以及“计算机程序产品”被用于一般性地泛指例如主存储器、副存储器、可移除存储设备、安装在硬盘驱动器中的硬盘和信号等介质。这些计算机程序产品都是用于为计算机系统提供软件的方式。计算机可读取介质允许计算机系统从计算机可读取介质中读取数据、指令、消息或消息包以及其他的计算机可读取信息。计算机可读取介质例如可以包括非易失性存储器譬如软盘、ROM、闪存存储 器、磁盘驱动存储器、CD-ROM和其他的永久性存储器。计算机可读取介质有效用于例如在计算机系统之间传送信息譬如数据和计算机指令。
而且,计算机可读取介质可以在瞬态介质例如网络链接和/或网络接口中包括计算机可读取信息,包括允许计算机读取此类计算机可读取信息的有线网络或无线网络。计算机程序(也被称为计算机控制逻辑)被存储在主存储器和/或副存储器内。计算机程序也可以通过通信接口接收。这样的计算机程序在执行时使计算机系统能够完成如本文中所述的本发明中的功能。具体地,计算机程序在执行时使处理器或多核处理器能够完成计算机系统的功能。因此,这样的计算机程序就代表了计算机系统中的控制器。通常,如本文中所用的术语“计算机可读取介质”是指参与向处理器提供指令以供执行的任何介质。这样的介质可以采用多种形式,包括但不限于非易失性介质、易失性介质和传输介质。非易失性介质包括例如光盘或磁盘。易失性介质包括动态存储器。传输介质包括同轴电缆、铜线和光纤,其中包括由总线构成的线缆。传输介质还可以采用例如在无线电波和红外数据通信期间生成的声波或光波的形式。
计算机可读取介质的通用形式包括例如软盘、软磁盘、硬盘、磁带或任意其他的磁性介质、CD-ROM、任意其他的光学介质、穿孔卡片、纸带、任意其他具有孔图案的物理介质、RAM、PROM、EPROM、闪存EPROM、任意其他的存储芯片或存储盒、如下所述的载波或者计算机能够从中读取的任意其他介质。
附图中的流程图和方块图根据本发明的不同实施例示出了系统、方法和计算机程序产品的结构、功能和可以实施的操作。在这方面,流程图或方块图中的每一个模块均可表示程序块、程序段或代码部分,其中包括用于实现一种或多种特定逻辑功能的一条或多条可执行指令。还应该注意到在某些可选的实施方式中,模块中注明的功能可以脱离附图中标明的顺序完成。例如,相继示出的两个模块实际上可以基本上同时执行,或者这两个模块有时可以用相反的顺序执行, 这取决于所涉及到的功能。还应该注意到方块图和/或流程图中的每一个模块以及方块图和/或流程图中的模块组合均可通过专用的基于硬件的系统实现以执行特定功能或动作,或者通过专用硬件和计算机指令的组合来实现。
本文中所用术语仅仅是为了描述特定的实施例,而并不是要限制本发明。如本文中所用,单数形式“一”、“一个”和“这个”应理解为也包括复数形式,除非上下文中清楚地另有说明。进一步应该理解的是术语“包括”和/或“包含”在本说明书中使用时明确了所述特征、整体、步骤、操作、元件和/或部件的存在,但是并不排除存在或加有一个或多个其他的特征、整体、步骤、操作、元件、部件和/或其群组。
以下权利要求中的对应结构、材料、动作和所有装置或步骤以及功能元件的等价形式都应理解为包括用于实现与其他权利要求中明确主张的元素相结合的功能的任意结构、材料或动作。本发明的说明书是为了解释和说明而提供,并不是为了穷举或者将本发明限制为所公开的形式。多种修改和变形对于本领域技术人员来说显而易见且并不背离本发明的保护范围。选择和介绍实施例是为了清楚地解释本发明的原理和实际应用,并且使本领域技术人员能够理解本发明以得到具有各种修改的适用于特定预期用途的不同实施例。
尽管已经介绍并在附图中示出了某些示范性实施例,但是应该理解这样的实施例仅仅是说明而并不是对本发明宽泛内容的限制,并且本发明并不受限于图示和介绍的特定结构和设置方式,原因在于本领域普通技术人员能够想出各种其他的变形。