用于存储消息数据的系统和方法与流程

文档序号:15105959发布日期:2018-08-04 16:53阅读:210来源:国知局

本申请要求于2015年10月9日提交的美国专利申请No.14/879,661的优先权,并且其全部内容通过引用结合于此。



背景技术:

本说明书涉及数据通信系统,特别涉及实现实时的、可扩展的发布-订阅消息传送的系统。

发布-订阅模式(或“PubSub”)是由软件系统实现的数据通信消息传送布置,其中所谓的发布者将消息发布到主题,并且所谓的订户接收与订阅的特定主题有关的消息。每个主题可以有一个或多个发布者,并且发布者通常不知道什么订户(如果有的话)将会收到发布的消息。某些PubSub系统不会缓存消息或具有小缓存,这意味着订户可能不会接收到在订阅特定主题之前发布的消息。PubSub系统在消息发布的浪潮(surge)期间或随着特定主题的订户量增加而容易受到性能不稳定的影响。



技术实现要素:

本文描述的系统和方法允许消息被PubSub系统精确和有效地接收和存储。在某些示例中,PubSub系统包括多个信道,每个信道对应于单独的消息数据的流。每个信道具有相应的缓冲器,存储该信道的消息。消息被写入到缓冲器的可写入部分,并从缓冲器的可读取部分中读取。指示器指示或区分缓冲器的可读取和可写入部分之间的边界。在消息被成功写入到可写入部分后,将指示器在原子操作中进行推进,之后,消息驻留在可读取部分中。

有利的是,PubSub系统组件能够并行读取和写入每个缓冲器。这允许与PubSub系统相关联的组件和进程出于读取和/或写入目的、同时访问每个缓冲器。此外,使用原子操作可确保缓冲器的可读取部分中的消息数据的准确性。通常,原子操作会阻止PubSub系统组件读取新消息,直到指示器已被推进并且新消息已移至可读取部分。

本文描述的系统和方法的实施例提供允许多个进程(例如,ERLANG队列进程)共享相同的存储器空间的“零复制队列”分布式存储系统。在一些示例中,零复制队列允许(i)超高速存储器写入和存储器读取,(ii)并行写入的超低延迟(例如,小于100纳秒)和/或(iii)达50,000次并行读取的超低延迟(例如,小于10纳秒)。零复制队列还引入了自动背压机制来实现最大读取/写入吞吐量。

解决本文描述的问题的现有方法通常采用散列表或关键值存储库,诸如内置的ERLANG术语存储库(ETS)。ETS是存储器数据库,其是ERLANG虚拟机的一部分并且位于允许破坏性更新的虚拟机部分中。尽管这种更新很快,并且为程序员优化某些关键代码提供了一种简便方法,但ETS表具有内在锁定机制,其会增加对同时读取和写入速度的限制。

通过比较,因为不使用锁定,本文描述的零复制队列方法的示例不具有这样的内在限制。这实际上意味着读取者不会阻止写入者,写入者也不会阻止读取者。因此,读取者和写入者都能全速运行而不受任何干扰。

在某些实现中,零复制队列属于非锁定算法的类别,或者更确切地说,是“等待自由(wait-free)”算法。等待自由提供了快速的系统吞吐量,而不会导致进程不足。

通常,本说明书中描述的主题的一个方面可以体现在包括由一个或多个计算机执行的动作的方法中:从多个发布者接收多个消息,该消息的每一个与多个不同信道中的一个信道相关联;将与每个信道相关联的消息进行排序;根据分配给信道的消息的顺序,将信道中的每一个信道的每个消息存储在针对该信道的相应缓冲器中,其中,存储包括将该消息存储在该缓冲器的可写入部分中,以及在原子操作中将区分该缓冲器的可读取部分和该缓冲器的可写入部分之间的边界的指示器进行推进,使得该消息在该原子操作完成之后位于该缓冲器的可读取部分中;以及允许一个或多个订户在该存储期间从一个或多个缓冲器的可读取部分中进行读取。

在一些实现中,该原子操作不能被另一进程或执行线程中断。将该消息存储在该缓冲器的可写入部分中可以包括将该消息的长度存储在该缓冲器的可写入部分中的第一位置处,并将该消息存储在该缓冲器的可写入部分中的第一位置之后。在该原子操作中将区分该缓冲器的可读取部分与该缓冲器的可写入部分之间的边界的指示器进行推进可以包括在该指示器中存储该消息的长度与该指示器的当前值之和。

在一些示例中,每个缓冲器仅存储单个信道的消息。基于该缓冲器的生存时间,针对特定信道的每个缓冲器可以在不同的时间处到期。特定缓冲器可以对应于该计算机中的一个计算机上的写入进程。在各种实现中,每个缓冲器具有相应的生存时间,一旦该生存时间到期将导致该缓冲器对于发布者和订户不可访问。将与每个信道相关联的该消息进行排序可以包括根据该消息的相应的接收时间对该消息进行排序。

在另一方面,在本说明中描述的主题可以被体现在包括具有存储在其上的指令的非暂态计算机可读介质的系统中。该系统还包括数据处理装置,被配置为执行用于执行操作的指令,该操作包括:从多个发布者接收多个消息,该消息中的每一个与多个不同信道中的一个信道相关联;将与每个信道相关联的消息进行排序;根据分配给该信道的消息的顺序,将该信道中的每一个信道的每个消息存储在针对该信道的相应的缓冲器中,其中,存储包括将该消息存储在该缓冲器的可写入部分中,并且在原子操作中将区分该缓冲器的可读取部分和该缓冲器的可写入部分之间的边界的指示器进行推进,使得该消息在该原子操作完成之后位于该缓冲器的可读取部分中;以及允许一个或多个订户在该存储期间从一个或多个该缓冲器的可读取部分中进行读取。

在某些实现中,该原子操作不能被另一进程或执行线程中断。将该消息存储在该缓冲器的可写入部分中可以包括将该消息的长度存储在该缓冲器的可写入部分中的第一位置处,并将该消息存储在该缓冲器的可写入部分中的第一位置之后。在该原子操作中将区分该缓冲器的可读取部分与该缓冲器的可写入部分之间的边界的指示器进行推进可以包括在该指示器中存储该消息的长度与该指示器的当前值之和。

在一些示例中,每个缓冲器仅存储单个信道的消息。基于该缓冲器的生存时间,针对特定信道的每个缓冲器在不同的时间处到期。特定缓冲器可以对应于该计算机中的一个计算机上的写入进程。在各种实现中,每个缓冲器具有相应的生存时间,一旦该生存时间到期将导致该缓冲器对于发布者和订户不可访问。对与每个信道相关联的消息进行排序可以包括根据该消息的相应的接收时间对该消息进行排序。

在另一方面,本说明描述的主题可以体现在存储在一个或多个非暂态存储介质中的计算机程序产品中,其用于控制数据处理装置的处理模式。该计算机程序产品可由该数据处理装置执行,以使得该数据处理装置执行操作,该操作包括:从多个发布者接收多个消息,该消息中的每一个与多个不同信道中的一个信道相关联;将与每个信道相关联的消息进行排序;根据分配给信道的消息的顺序,将信道中的每一个信道的每个消息存储在针对该信道的相应的缓冲器中,其中,存储包括将该消息存储在该缓冲器的可写入部分中,并且在原子操作中将区分该缓冲器的可读取部分和该缓冲器的可写入部分之间的边界的指示器进行推进,使得该消息在该原子操作完成之后位于该缓冲器的可读取部分中;以及允许一个或多个订户在该存储期间从一个或多个该缓冲器的可读取部分中进行读取。

在某些实现中,该原子操作不能被另一进程或执行线程中断。将该消息存储在该缓冲器的可写入部分中可以包括将该消息的长度存储在该缓冲器的可写入部分中的第一位置处,并将该消息存储在该缓冲器的可写入部分中的第一位置之后。在该原子操作中将区分该缓冲器的可读取部分与该缓冲器的可写入部分之间的边界的指示器进行推进可以包括在该指示器中存储该消息的长度与该指示器的当前值之和。

在一些示例中,每个缓冲器仅存储单个信道的消息。基于该缓冲器的生存时间,针对特定信道的每个缓冲器可以在不同的时间处到期。特定缓冲器对应于该计算机中的一个计算机上的写入进程。在各种实现中,每个缓冲器具有相应的生存时间,一旦该生存时间到期将导致该缓冲器对于发布者和订户不可访问。对与每个信道相关联的消息进行排序可以包括根据该消息的相应的接收时间对该消息进行排序。

在本说明书中描述的主题的一个或多个实施例的细节在附图说明和下面的说明书中阐述。主题的其他特征、方面和优点将从说明书、附图说明和权利要求中变得明显。

附图说明

图1A示出了支持PubSub通信模式的示例系统。

图1B示出了示例客户端设备上的软件的功能层。

图2是示例消息传送系统的图。

图3A是用于将数据写入到小流(streamlet)的示例方法的数据流程图。

图3B是用于从小流读取数据的示例方法的数据流程图。

图4A是在第一时间处的示例缓冲器的示意图。

图4B是在第二时间处的图4A的示例缓冲器的示意图。

图5是在缓冲器中存储消息的示例方法的示意图。

具体实施方式

图1A示出了支持PubSub通信模式的示例系统100。发布者客户端(例如,发布者1)可以通过系统100将消息发布到指定信道(例如,“信道1”)。消息可以包括任何类型的信息,包括以下各项中的一种或多种:文本、图像内容、声音内容、多媒体内容、视频内容、二进制数据等等。其他类型的消息数据是可能的。订户客户端(例如,订户2)可以使用系统100订阅指定的信道,并开始接收在订阅请求之后或自给定位置(例如,消息号或时间偏移)起发生的消息。客户端既可以是发布者又可以是订户。

根据配置,可以将PubSub系统分类如下:

·一对一(1:1)。在这种配置中,每个信道有一个发布者和一个订户。典型的用例是私人消息传送。

·一对多(1:N)。在这种配置中,每个信道有一个发布者和多个订户。典型的用例是广播消息(例如,股票价格)。

·多对多(M:N)。在这种配置中,有许多发布者发布到单个信道。消息然后被传递给多个订户。典型的用例是地图应用。

创建指定信道不需要单独的操作。信道是在信道被订阅时或消息被发布到信道时隐式创建的。在某些实现中,信道名称可以通过命名空间来限定。命名空间包括一个或多个信道名称。不同的命名空间可以具有相同的信道名称,而不会造成混淆。命名空间名称可以是信道名称的前缀,其中命名空间和信道名称由点分隔。在某些实现中,在指定信道授权设置时可以使用命名空间。例如,消息传送系统100可以具有app1.foo和app1.system.notifications信道,其中“app1”是命名空间的名称。该系统可以允许客户端订阅并发布到app1.foo信道。但是,客户端只能订阅,而不能发布到app1.system.notifications信道。

图1B示出了示例客户端设备上的软件的功能层。客户端设备(例如,客户端102)是数据处理装置,例如,个人计算机、膝上型计算机、平板电脑、智能手机、智能手表、或服务器计算机。其他类型的客户端设备也是可能的。应用层104包括将与PubSub系统100集成的(一个或多个)终端用户应用。消息传送层106是针对应用层104的编程接口,用于利用系统100的服务,例如,信道订阅、消息发布、消息取回、用户认证、和用户授权。在一些实现中,传递到消息传送层106和从消息传送层106传递的消息被编码为JavaScript对象表示法(JSON)对象。其他消息编码方案是可能的。

操作系统108层包括客户端102上的操作系统软件。在各种实现中,可以使用持久或非持久连接来向/从系统100发送和接收消息。持久连接可以使用例如网络套接字来创建。诸如TCP/IP层112之类的传输协议实现与系统100的传输控制协议/互联网协议通信,该传输控制协议/互联网协议通信可被消息传送层106用来通过到系统100的连接发送消息。其他通信协议是可能的,包括例如用户数据报协议(UDP)。在进一步的实现方式中,可以采用可选的传输层安全(TLS)层110来确保消息的机密性。

图2是示例消息传送系统100的图。系统100提供用于实现PubSub通信模式的功能。例如,该系统包括可以部署在一个或多个地理位置中的一个或多个数据中心122处部署的软件组件和存储装置。该系统包括MX节点(例如,MX节点或多路复用器节点202、204和206)、Q节点(例如,Q节点或队列节点208、210和212)、一个或多个信道管理器节点(例如,信道管理器214、215)、以及可选地一个或多个C节点(例如,C节点或缓存节点220和222)。每个节点可以在虚拟机或物理机器(例如,数据处理装置)上执行。每个MX节点通过外部网络216充当用于一个或多个发布者和/或订户连接的端点。例如,MX节点、Q节点、C节点、和信道管理器之间的内部通信通过内部网络218进行。作为说明,MX节点204可以是来自客户端102的订户连接的终点。每个Q节点缓冲供MX节点消费的信道数据。发布到信道的有序消息序列是逻辑信道流。例如,如果三个客户端将消息发布到给定信道,则由客户端发布的组合消息包括信道流。可以按客户端发布的时间、MX节点接收的时间、或Q节点接收的时间来对信道流中的消息进行排序。用于对信道流中的消息进行排序的其他方式也是可能的。在不止一个消息将按顺序被分配给同一位置的情况下,可以选择一个消息(例如,随机地)以具有该顺序中较晚的序列。每个信道管理器节点负责通过将信道流分割成所谓的小流来管理Q节点负载。小流将在下面进一步讨论。可选的C节点提供缓存并加载来自Q节点的移除。

在示例消息传送系统100中,一个或多个客户端设备(发布者和/或订户)建立到MX节点(例如,MX 204)的相应持久连接(例如,TCP连接)。MX节点充当这些连接的端点。例如,可以基于外部协议(例如,JSON)对这些连接所承载的外部消息(例如,在相应客户端设备和MX节点之间的)进行编码。MX节点终止外部协议并将外部消息转换为内部通信,反之亦然。MX节点代表客户端发布和订阅小流。这样,MX节点可以复用并且合并订阅同一信道或发布到同一信道的客户端设备的请求,从而将多个客户端设备作为一个来表示而非逐个表示。

在示例消息传送系统100中,Q节点(例如,Q节点208)可以存储一个或多个信道流的一个或多个小流。小流是针对信道流的一部分的数据缓冲器。当存储装置已满时,小流将关闭写入。在小流的生存时间(TTL)到期时,小流将关闭读取和写入并解除分配。作为说明,小流可以具有1MB的最大大小和3分钟的TTL。不同的信道可以具有由不同的TTL限制的小流。例如,一个信道中的小流最多可以存在三分钟,而另一个信道中的小流最多可以存在10分钟。在各种实现方式中,小流对应于在Q节点上运行的计算进程。例如,计算进程可以在小流的TTL到期之后终止,从而将计算资源(针对小流的)释放回Q节点。

当从客户端设备接收到发布请求时,MX节点(例如,MX 204)向信道管理器(例如,信道管理器214)发出请求以授权对小流的访问以写入正在发布的消息。但是,请注意,如果MX节点已被授权对该信道的小流的写入访问(并且该信道尚未关闭写入),则MX节点可以将该消息写入该小流,而无需请求授权对小流的访问。一旦消息被写入信道的小流,消息就可以被MX节点读取并提供给该信道的订户。

类似地,在接收到来自客户端设备的信道订阅请求时,MX节点向信道管理器发出请求以授权对信道的小流的访问以从其读取消息。如果MX节点已被授权对信道的小流的读取访问(并且信道的TTL尚未关闭读取),则MX节点可以从小流读取消息,而无需请求授权对该小流的访问。读取的消息然后可以被转发到订阅了该信道的客户端设备。在各种实现方式中,从小流读取的消息由MX节点缓存,使得MX节点可以减少需要从小流读取的次数。

作为说明,MX节点可以请求来自信道管理器的授权,该授权允许MX节点将数据块存储到存储特定信道的小流的特定Q节点上的小流中。示例小流授权请求和授权数据结构如下:

StreamletGrantRequest数据结构存储流信道的名称和模式,该模式指示MX节点是意图从小流读取还是写入到小流。MX节点将StreamletGrantRequest发送到信道管理器节点。作为响应,信道管理器节点向MX节点发送StreamletGrantResponse数据结构。StreamletGrantResponse包含小流的标识符(streamlet-id)、小流的最大大小(limit-size)、小流可以存储的最大消息量(limit-msgs)、TTL(limit-life)、以及该小流所在的Q节点的标识符(q-node)。StreamletGrantRequest和StreamletGrantResponse也可以有位置字段,其指向小流中的用于从小流中读取的位置(或信道中的位置)。

一旦小流关闭,授权就失效。例如,一旦小流的TTL已到期,小流就关闭读取和写入,并且当小流的存储装置已满时,小流将关闭写入。当授权变为无效时,MX节点可以请求来自信道管理器的新授权以从小流读取或写入小流。新授权将针对不同的小流,并将根据新小流所在的位置针对相同或不同的Q节点。

图3A是在各种实施例中用于将数据写入到小流的示例方法的数据流程图。在图3A中,如前描述,当写入小流的MX节点(例如,MX 202)请求被信道管理器(例如,信道管理器214)授权时,MX节点建立与Q节点的传输控制协议(TCP)连接(302),其中Q节点在从信道管理器接收的授权响应中被标识。可以通过多个写入授权(例如,由多个发布者客户端发布的消息)同时写入一个小流。MX节点和Q节点之间的其他类型的连接协议也是可能的。

然后,MX节点发送准备发布消息(304),其具有MX节点想要写入Q节点的小流的标识符。如前描述,小流标识符和Q节点标识符可以由信道管理器在写授权中提供。Q节点将消息移交给所标识的小流的处理机(handler)进程301(例如,在Q节点上运行的计算进程)(306)。处理机进程可以向MX节点发送确认(308)。在接收到确认之后,MX节点开始将消息写入(发布)到处理机进程(例如,310、312、314、和318),该处理机进程又将接收到的数据存储在所标识的小流中。处理机进程还可以向MX节点发送确认(316、320)以用于接收到的数据。在一些实现方式中,确认可以是捎带的(piggy-backed)或累积的。例如,处理机进程可以针对接收到的每预定量的数据(例如,对于接收的每100个消息)或者每预定时间段(例如,每一毫秒)向MX节点发送确认。可以使用其他确认调度算法(如Nagle算法)。

如果小流不再接受发布的数据(例如,当小流满时),则处理机进程发送指示问题的否定确认(NAK)消息(330),接着是EOF(文件结束)消息(332)。通过这种方式,处理机进程针对发布授权关闭与MX节点的关联。如果MX节点有额外的消息要存储,则MX节点可以请求来自信道管理器的另一个小流的写入授权。

图3B是在各种实施例中用于从小流读取数据的示例方法的数据流程图。在图3B中,MX节点(例如,MX 202)向信道管理器(例如,信道管理器214)发送从信道中的特定消息或时间偏移开始读取特定信道的请求。信道管理器向MX节点返回包括以下各项的读取授权:包含特定消息的小流的标识符、与特定消息相对应的小流中的位置、以及包含特定小流的Q节点(例如,Q节点208)的标识符。MX节点然后建立与Q节点的TCP连接(352)。MX节点和Q节点之间的其他类型的连接协议也是可能的。

然后,MX节点向Q节点发送具有小流的标识符(在Q节点中)以及MX节点想要从其读取的小流中的位置的订阅消息(356)。Q节点将该订阅消息移交给小流的处理机进程351(356)。处理机进程可以向MX节点发送确认(358)。处理机进程然后将从小流中的位置开始的消息发送到MX节点(360、364、366)。在一些实现方式中,处理机进程可以将小流中的所有消息发送到MX节点。在发送完特定小流中的最后一个消息之后,处理机进程可以将最后一个消息的通知发送给MX节点。MX节点可以向信道管理器发送针对包含特定信道中下一个消息的另一个小流的另一个请求。

如果特定小流关闭(例如,在其TTL已经到期之后),则处理机进程可以发送取消订阅消息(390),随后是EOF消息(392),以关闭针对读取授权的与MX节点的关联。当MX节点移动到特定信道中的消息的另一小流(例如,如信道管理器所指示的)时,MX节点可以关闭与处理机进程的关联。如果MX节点收到来自对应客户端设备的取消订阅消息,MX节点也可以关闭与处理机进程的关联。

在各种实现方式中,可以在同一时刻写入和读取小流。例如,在同一时刻可以有有效读取授权和有效写入授权。在各种实现方式中,可以通过多个读取授权(例如,针对由多个发布者客户端所订阅的信道)来同时读取小流。小流的处理机进程可以基于例如到达时间来对来自同时写入授权的消息进行排序,并基于该顺序存储消息。通过这种方式,发布到来自多个发布者客户端的信道的消息可以被序列化并存储在信道的小流中。

在消息传送系统100中,一个或多个C节点(例如,C节点220)可以卸载来自一个或多个Q节点的数据传输。例如,如果有许多MX节点从Q节点请求针对特定信道的小流,则小流可以被卸载并缓存在一个或多个C节点中。替代地,MX节点(例如,如来自信道管理器的读取授权所指示的)可以从C节点读取小流。

如上所述,消息传送系统100中的信道的消息在信道流中被排序。信道管理器(例如,信道管理器214)将信道流分割成固定大小的小流,其中每个小流驻留在相应的Q节点上。以这种方式,存储信道流可以在许多Q节点之间共享;每个Q节点存储信道流的一部分(一个或多个小流)。更具体地,可以将小流存储在与Q节点上的计算进程相关联的寄存器和动态存储器元件中,从而避免需要访问诸如硬盘之类的持久且较慢的存储设备。这导致更快的消息访问。信道管理器还可以通过监控Q节点的相应工作负载并以避免过载任何一个Q节点的方式分配小流来平衡消息传送系统100中的Q节点之间的负载。

在各种实现方式中,信道管理器维护标识了每个活动小流的列表、小流所在的相应Q节点、以及小流中第一消息的位置的标识以及流程是否关闭写入。在一些实现方式中,Q节点通知信道管理器以及发布到小流的任何MX节点:由于小流已满或小流的TTL已到期,小流被关闭。当小流关闭时,小流会保留在信道管理器的活动小流列表中,直到小流的TTL已到期,使得MX节点可以继续从小流中取回消息。

当MX节点请求针对给定信道的写入授权并且不存在可写入的针对该信道的小流时,信道管理器在Q节点中的一个上分配新小流并在StreamletGrant中返回小流和Q节点的标识。否则,信道管理器在StreamletGrant中返回当前打开写入的小流和对应的Q节点的标识。MX节点可以将消息发布到小流,直到小流已满或小流的TTL已到期,在此之后信道管理器可以分配新的小流。

当MX节点请求针对给定信道的读取授权并且不存在可读的针对该信道的小流时,信道管理器在Q节点中的一个上分配新的小流,并在StreamletGrant中返回小流和Q节点的标识。否则,信道管理器将返回包含MX节点希望从其读取的位置的小流和Q节点的标识。然后,Q节点可以开始从指定位置处开始的小流向MX节点发送消息,直到小流中没有更多消息要发送。当新消息被发布到小流时,订阅该小流的MX节点将收到新消息。如果小流的TTL已经到期,则处理机351将EOF消息发送到订阅该小流的任何MX节点(392)。

如前面参照图2所述,消息传送系统100可以包括多个信道管理器(例如,信道管理器214、215)。多个信道管理器提供弹性并防止单点故障。例如,一个信道管理器可以将它维护的小流列表和当前授权复制给另一个“从属”信道管理器。至于另一个示例,多信道管理器可以通过使用诸如Paxos或Raft协议之类的分布式共识协议来协调它们之间的操作。

在某些实现中,PubSub系统从一个或多个信道的多个发布者接收消息。PubSub系统组件(例如,Q节点或MX节点)可以对消息进行排序并将消息写入一个或多个缓冲器(例如,每信道一个缓冲器)。各种系统组件和/或进程可以从缓冲器读取消息并将消息分发给一个或多个接收者或订户。

图4A和4B是用于将消息数据存储在PubSub系统中的示例缓冲器400或零复制队列的示意图。缓冲器400包括可读取部分402和可写入部分404。PubSub系统的一个或多个组件或进程(例如,Q节点或MX节点)可以将消息写入可写入部分404和/或可以从可读取部分402中读取消息。指示器(pointer)406将可读取部分402和可写入部分404之间的边界408进行区分。指示器406可以是或可以包括例如存储器地址。

图4A示出了当消息410和412被存储在可读取部分402中并且新消息414正被写入可写入部分404中时,在第一时间处的示例缓冲器400。指示器406指示可读取部分402和可写入部分404的边界408位于消息412和消息414之间。在此第一时间处,一个或多个PubSub系统组件或进程(例如,Q节点或MX节点)可以从可读取部分402读取消息410和412。PubSub系统组件或进程还可以将新消息414写入到可写入部分404。在各种示例中,PubSub系统组件和/或进程可以并行地从缓冲器400读取和写入到缓冲器400中,使得该读取和写入同时发生。例如,多个组件和/或进程可以同时从可读取部分402读取消息410和/或消息412。而且,当消息410和/或消息412正在被读取时,组件或进程可以向可写入部分404写入新消息414。箭头415指示通过缓冲器400的消息数据的流的方向。如箭头415指示,新消息被添加到缓冲器的右侧,使得较旧的消息位于左侧而较新的消息位于右侧。

图4B示出了在消息414已经被成功写入到缓冲器400并且指示器406已经被推进以指示消息414现驻留在可读取部分402内时的第二时间处的示例缓冲器400。在该第二时间处,消息410、412、和414可从可读取部分402中被读取,并且新消息416正被写入可写入部分404。一旦消息416已被写入缓冲器400,可以执行额外的原子操作以进一步推进指示器406和边界408,使得消息416驻留在可读取部分402中。然后可以将额外消息写入可写入部分404。

在优选实现中,在任何附加的新消息被添加到可写入部分404之前,新消息被写入到可写入部分404,并且被移动到可读取部分402。这防止新消息被另一新消息覆盖。一旦新消息被成功写入到缓冲器400中,根据新消息的长度,指示器406可以被推进到新的位置。指示器406的新位置可以是例如指示器406的先前位置加上新消息的长度。指示器位置和消息长度可以存储在存储器中。

在优选实现中,指示器406在原子操作中被推进到新的位置,在此期间禁止与缓冲器400相关联的某些读取或写入活动。例如,在该原子操作期间,PubSub系统组件或进程可能无法写入缓冲器400和/或读取最近添加到缓冲器400的消息。替代地或附加地,PubSub系统组件可能无法在原子操作期间读取指示器406。这可以防止PubSub系统组件或进程在指示器406被推进时读取错误的指示器位置,该错误读取可能花费不止一个CPU周期。通常,新添加到缓冲器400的消息不是可读取部分402的一部分或可用于读取,直到指示器406已经在原子操作中被推进并且新消息驻留在可读取部分402中。在可读取部分402中的所有其他消息可用于在原子操作之前、期间和/或之后的读取。在某些示例中,原子操作是原子添加、或提取并添加操作。原子操作优选地不能被另一进程或执行线程中断。在各种实现中,消息被一次一个地(即,串行地)排序并写入可写入部分404。对消息进行排序可以包括例如根据接收时间(例如,PubSub系统接收消息的顺序)排列消息或优先化该消息。一次写入一条消息可防止新消息被另一条新消息覆盖。在任何新消息可被写入到可写入部分404之前,先前的新消息应该通过推进指示器406被完全写入并且移动到可读取部分402。

在某些示例中,缓冲器400通过在全局可访问的存储设备上分配存储器的一部分来实现。全局可访问的存储设备的一部分可以存储指示器的信息(例如,存储器地址)。缓冲器400可以被分配一个生存时间,此后缓冲器到期并且不再可用于写入和读取。

通常,缓冲器400构成PubSub系统的一部分或由其使用。例如,缓冲器400可以形成PubSub系统的Q节点或MX节点的一部分或由其使用。PubSub系统中的每个MX节点和每个Q节点都可以具有或使用其自己的一组缓冲器以存储消息数据。每组缓冲器可以包含每信道一个缓冲器,或每信道不止一个缓冲器。在某些情况下,对于PubSub系统组件,单个缓冲器可用于存储所有信道的消息数据。

使用或包括缓冲器的每个MX节点、Q节点或其他PubSub系统组件优选地仅完成由组件接收的任何给定消息的一个副本。这最小化MX节点和Q节点必须执行的写入数量,并且还可以释放其他进程的CPU时间。为了与请求消息的订户、组件或进程共享该消息,缓冲器400中的消息的位置(例如,存储器地址)可以被提供给订户或进程,然后该订户或进程可以从缓冲器400中的该位置读取消息。

当组件或进程想要将消息写入缓冲器400时,可以将消息发送到缓冲器400的写入进程(例如,ERLANG写入进程)。写入进程然后可以以接收消息的顺序(例如,基于写入进程接收或通知的时间)来将消息和其他消息写入缓冲器400。对于写入到缓冲器400的每个消息,写入进程可以首先将消息写入到缓冲器的可写入部分404(例如,在由指示器406的当前位置指示的缓冲器400的尾端)。然后,写入进程可以使用原子操作(例如,提取并添加原子操作)将指示器406移动到新写入的消息之后的位置。在一些情况下,每条消息的长度(例如,在消息的前面)与消息本身一起被写入缓冲器400,使得读者知道该消息有多大(例如,以字节为单位)。

图5是用于在PubSub系统中存储多个信道的消息数据的示例方法500的流程图。PubSub系统从多个发布者接收多个消息(步骤502)。例如,发布者可以是用户的客户端设备、MX节点或Q节点。每个消息优选地与多个不同信道中的一个相关联。例如,根据从发布者接收消息的顺序,针对每个信道对消息进行排序(步骤504)。将每个信道的每个消息存储在针对该信道的相应的缓冲器中(步骤506)。为了存储信道的消息,根据消息被分配给信道的顺序,将消息写入相应的缓冲器的可写入部分。在原子操作中,将区分缓冲器的可读取部分和可写入部分之间边界的指示器进行推进(步骤508)。在推进指示器之后,消息驻留在缓冲器的可读取部分。一个或多个订户被允许从一个或多个缓冲器的可读取部分读取(步骤510)。

在各种实施方式中,本文描述的系统和方法利用自动背压机制,其减小高消息流量期间的系统上的压力。通常,背压是一种在系统边缘放置负载的方法。当系统资源不能处理大量的写入请求时,背压可以防止系统崩溃或爆炸。例如,因为零复制队列(例如,缓冲器400)具有有限大小,所以在某一时刻,该零复制队列达到其存储容量。当零复制队列已满时,至少部分因为该原子操作,没有系统组件能够写入该零复制队列。在该情况下,尝试写入操作的写入者(例如,MX节点或Q节点)将接收通知写入者零复制队列已满的错误消息。写入者然后可以通过寻求外部实体(例如仲裁器)来识别可用于写入的下一个零复制队列,以重新尝试写入操作。旧的零复制队列缓冲器优选地在特定的生存时间(可能是10秒、30秒、60秒或更长)之后循环。

本说明书中描述的主题和操作的实施例可以以数字电子电路或者计算机软件、固件、或硬件(包括本说明书中公开的结构及其结构等同物),或者以它们中的一个或多个的组合来实现。本说明书中描述的主题的实施例可以被实现为编码在计算机存储介质上的一个或多个计算机程序(即,计算机程序指令的一个或多个模块),用于由数据处理装置执行或控制数据处理装置的操作。替代地或附加地,可以将程序指令编码在人工生成的传播信号上,例如,机器生成的电信号、光信号、或电磁信号,该信号被生成以对信息进行编码以便传输给合适的接收机装置以供数据处理装置执行。计算机存储介质可以是或者可以被包括在计算机可读存储设备、计算机可读存储基板、随机或串行存取存储器阵列或设备、或者它们中的一个或多个的组合。此外,尽管计算机存储介质不是传播信号,但计算机存储介质可以是在人工生成的传播信号中编码的计算机程序指令的源或目的地。计算机存储介质也可以是或可以被包括在一个或多个单独的物理组件或介质(例如,多个CD、磁盘、或其他存储设备)。

本说明书中描述的操作可以被实现为由数据处理装置对存储在一个或多个计算机可读存储设备上的数据或从其他源接收的数据执行的操作。

术语“数据处理装置”涵盖用于处理数据的所有类型的装置、设备、和机器,包括例如可编程处理器、计算机、片上系统、或多个、或前述各项的组合。该装置可以包括专用逻辑电路,例如,FPGA(现场可编程门阵列)或ASIC(专用集成电路)。除了硬件之外,该装置还可以包括为所涉及的计算机程序创建执行环境的代码,例如,构成处理器固件、协议栈、数据库管理系统、操作系统、跨平台运行时间环境、虚拟机、或它们中的一个或多个的组合的代码。装置和执行环境可以实现各种不同的计算模型基础设施,如Web服务、分布式计算、和网格计算基础设施。

计算机程序(也被称为程序、软件、软件应用、脚本、或代码)可以以任何形式的编程语言来编写,包括编译或解释语言、声明性、过程性、或功能性语言,并且可以以任何形式来部署,包括作为独立程序或作为模块、组件、子程序、对象、或适用于计算环境的其他单元。计算机程序可能(但不一定)对应于文件系统中的文件。程序可以被存储在保存其他程序或数据(例如,存储在标记语言资源中的一个或多个脚本)的文件的一部分、专用于所涉及的程序的单个文件、或者多个协调文件(例如,存储一个或多个模块、子程序、或部分代码的文件)中。计算机程序可以被部署为在一个计算机上执行或在位于一个站点或跨多个站点分布并通过通信网络互连的多个计算机上执行。

本说明书中描述的过程和逻辑流程可以由执行一个或多个计算机程序的一个或多个可编程处理器执行,以通过对输入数据进行操作并生成输出来执行动作。过程和逻辑流程也可以由专用逻辑电路(例如,FPGA(现场可编程门阵列)或ASIC(专用集成电路))执行,并且装置也可以被实现为专用逻辑电路。

作为示例,适用于执行计算机程序的处理器包括通用和专用微处理器两者,以及任何类型的数字计算机的任何一个或多个处理器。通常,处理器将从只读存储器或随机存取存储器或两者接收指令和数据。计算机的基本元件是用于根据指令来执行动作的处理器和用于存储指令和数据的一个或多个存储器设备。通常,计算机还将包括用于存储数据的一个或多个大容量存储设备(例如,磁盘、磁光盘、或光盘),或者可操作地耦接到一个或多个大容量存储设备以从一个或多个大容量存储设备接收数据或将数据传送到一个或多个大容量存储设备或两者。但是,计算机不需要具有这种设备。此外,计算机可以嵌入到另一个设备中,例如,智能手机、移动音频、或视频播放器、游戏机、全球定位系统(GPS)接收器、或便携式存储设备(例如,通用串行总线(USB)闪存驱动器),仅举几例。适用于存储计算机程序指令和数据的设备包括所有形式的非易失性存储器、介质、和存储器设备,例如包括半导体存储器设备(例如,EPROM、EEPROM、和闪存设备);磁盘(例如,内部硬盘或可移动磁盘);磁光盘;以及CD ROM和DVD-ROM盘。处理器和存储器可以由专用逻辑电路补充或并入其中。

为了提供与用户的交互,本说明书中描述的主题的实施例可以在具有以下各项的计算机上实现:用于向用户显示信息的显示设备(例如,CRT(阴极射线管)或LCD(液晶显示器)监视器)以及用户可以通过其向计算机提供输入的键盘和定点设备(例如,鼠标或轨迹球)。其他类型的设备也可以用于提供与用户的交互;例如,提供给用户的反馈可以是任何形式的感官反馈,例如,视觉反馈、听觉反馈、或触觉反馈;并且可以以任何形式接收来自用户的输入,包括声学、语音、或触觉输入。另外,计算机可以通过向用户所使用的设备发送资源和从该设备接收资源来与用户交互;例如,通过响应于从web浏览器接收到的请求而将网页发送到用户的客户端设备上的web浏览器。

本说明书中描述的主题的实施例可以在计算系统中实现,该计算系统包括后端组件(例如,作为数据服务器),或者包括中间件组件(例如,应用服务器),或者包括前端组件(例如,具有图形用户界面或Web浏览器的客户端计算机,用户可以通过该图形用户界面或Web浏览器与本说明书中描述的主题的实现方式交互),或者包括一个或多个这样的后端、中间件、或前端组件的任意组合。系统的组件可以通过数字数据通信的任何形式或介质(例如,通信网络)互连。通信网络的示例包括局域网(“LAN”)和广域网(“WAN”)、网间网络(例如,互联网)、和对等网络(例如,自组(ad hoc)对等网络)。

计算系统可以包括客户端和服务器。客户端和服务器通常彼此远离并且通常通过通信网络进行交互。客户端和服务器之间的关系是通过运行在各个计算机上并且彼此具有客户端-服务器关系的计算机程序来实现的。在一些实施例中,服务器(例如,出于向与客户端设备交互的用户显示数据和从这些用户接收用户输入的目的)向客户端设备发送数据(例如,HTML页面)。(例如,作为用户交互的结果)在客户端设备处生成的数据可以在服务器处从客户端设备接收。

一个或多个计算机的系统可以被配置为通过在系统上安装软件、固件、硬件或它们的组合来执行特定操作或动作,这些软件、固件、硬件或它们的组合在操作中使得系统执行这些动作。一个或多个计算机程序可以被配置为通过包括在由数据处理装置执行时使得该装置执行动作的指令来执行特定操作或动作。

尽管本说明书包含许多具体的实现细节,但这些不应该被解释为对任何发明或可能要求保护的内容的范围的限制,而是作为对特定于特定发明的特定实施例的特征的描述。本说明书中在单独实施例的上下文中描述的某些特征也可以在单个实施例中组合实现。相反地,在单个实施例的上下文中描述的各种特征也可以在多个实施例中分开地或以任何合适的子组合来实现。此外,尽管上文可以将特征描述为以某些组合起作用并且甚至最初如此被要求保护,但是来自所要求保护的组合的一个或多个特征在一些情况下可以从组合中删除,并且所要求保护的组合可以针对子组合或子组合的变形。

类似地,尽管在附图中以特定顺序描述了操作,但是这不应被理解为要求以所示的特定顺序或按连续顺序执行这样的操作,或者执行所有示出的操作以实现期望的结果。在某些情况下,多任务和并行处理可能是有利的。此外,上述实施例中的各种系统组件的分离不应被理解为在所有实施例中都需要这种分离,并且应理解的是,所描述的程序组件和系统通常可以一起集成在单个软件产品中或者封装到多个软件产品。

因此,已经描述了主题的特定实施例。其他实施例在以下权利要求的范围内。在一些情况下,权利要求中记载的动作可以以不同的顺序执行并且仍然实现期望的结果。另外,附图中描绘的过程不一定需要所示的特定顺序或连续顺序来实现期望的结果。在某些实现方式中,多任务和并行处理可能是有利的。

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