12/CHP

12/CHP

集群哈希映射协议

集群哈希映射协议 (CHP) 定义了一个集群范围的键值哈希映射,以及在客户端集合之间共享此哈希映射的机制。CHP 允许客户端使用哈希映射的子树,更新值,以及定义临时值。CHP 源自《指南》第 5 章中定义的 Clone 模式。

许可证

版权所有 (c) 2011 iMatix Corporation。

本规范是自由软件;您可以根据自由软件基金会发布的 GNU 通用公共许可证的条款重新分发和/或修改它;可以是许可证的第 3 版,或者(由您选择)任何后续版本。

分发本规范是希望它会有用,但 **不提供任何担保**;甚至不包含适销性或特定用途适用性的默示担保。有关更多详细信息,请参阅 GNU 通用公共许可证。

您应该已随本程序收到一份 GNU 通用公共许可证的副本;如果未收到,请参见 https://gnu.ac.cn/licenses

变更流程

本规范是自由开放的标准(参见“自由开放标准的定义”),并受数字标准组织的一致性导向规范系统 (COSS) 管辖(参见“一致性导向规范系统”)。

语言

本文档中的关键词“必须”、“不得”、“要求”、“应”、“不应”、“应该”、“不应”、“推荐”、“可以”和“可选”应按 RFC 2119 中的描述进行解释(参见“RFC 中用于指示需求级别的关键词”)。

目标

CHP 旨在为通过 0MQ 网络连接的客户端集群提供可靠的发布/订阅基础。它定义了一个由键值对组成的“哈希映射”抽象。任何客户端都可以随时修改任何键值对,更改会传播到所有客户端。客户端可以随时加入网络。

架构

CHP 连接一组客户端应用程序和一组服务器。客户端连接到服务器。客户端之间互相不可见。客户端可以随意加入和离开。

端口和连接

服务器必须打开以下三个端口

  • 一个 SNAPSHOT 端口(0MQ ROUTER 套接字),端口号为 P。
  • 一个 PUBLISHER 端口(0MQ PUB 套接字),端口号为 P + 1。
  • 一个 COLLECTOR 端口(0MQ SUB 套接字),端口号为 P + 2。

客户端应该打开至少两个连接

  • 一个 SNAPSHOT 连接(0MQ DEALER 套接字),连接到端口号 P。
  • 一个 SUBSCRIBER 连接(0MQ SUB 套接字),连接到端口号 P + 1。

如果客户端想要更新哈希映射,可以打开第三个连接

  • 一个 PUBLISHER 连接(0MQ PUB 套接字),连接到端口号 P + 2。

摘自 ØMQ 参考手册(参见“[]()”)

接收消息时,ROUTER 套接字应在将消息传递给应用程序之前,在消息前添加一个包含发起对端身份的消息部分。发送消息时,ROUTER 套接字应移除消息的第一部分,并使用它来确定消息将要路由到的对端身份。

下面解释的命令中未显示此额外帧。

状态同步

客户端必须首先向其快照连接发送一个 ICANHAZ 命令。此命令由两个帧组成,如下所示

ICANHAZ command
-----------------------------------
Frame 0: "ICANHAZ?"
Frame 1: subtree specification

两个帧都是 0MQ 字符串。子树规范可以为空。如果不为空,则由一个斜杠后跟一个或多个路径段组成,以斜杠结尾。

服务器必须通过向其快照端口发送零个或多个 KVSYNC 命令来响应 ICANHAZ 命令,随后发送一个 KTHXBAI 命令。服务器必须在每个命令前加上客户端的身份,该身份由 0MQ 随 ICANHAZ 命令提供。KVSYNC 命令按如下方式指定一个键值对

KVSYNC command
-----------------------------------
Frame 0: key, as 0MQ string
Frame 1: sequence number, 8 bytes in network order
Frame 2: <empty>
Frame 3: <empty>
Frame 4: value, as blob

序列号没有意义,可以为零。

KTHXBAI 命令采用此形式

KTHXBAI command
-----------------------------------
Frame 0: "KTHXBAI"
Frame 1: sequence number, 8 bytes in network order
Frame 2: <empty>
Frame 3: <empty>
Frame 4: subtree specification

序列号必须是先前发送的 KVSYNC 命令中的最高序列号。

客户端收到 KTHXBAI 命令后,应该开始从其订阅者连接接收消息并应用它们。

服务器到客户端更新

当服务器有哈希映射的更新时,必须在其发布者套接字上将其作为 KVPUB 命令广播。KVPUB 命令具有以下形式

KVPUB command
-----------------------------------
Frame 0: key, as 0MQ string
Frame 1: sequence number, 8 bytes in network order
Frame 2: UUID, 16 bytes
Frame 3: properties, as 0MQ string
Frame 4: value, as blob

序列号必须严格递增。客户端必须丢弃任何序列号不严格大于上次收到的 KTHXBAI 或 KVPUB 命令的 KVPUB 命令。

UUID 是可选的,帧 2 可以为空(大小为零)。属性字段格式为零个或多个“name=value”实例。如果键值对没有属性,属性字段为空。

如果值为空,客户端应该删除其具有指定键的键值条目。

在没有其他更新的情况下,服务器应该以固定的间隔发送 HUGZ 命令,例如每秒一次。HUGZ 命令具有此格式

HUGZ command
-----------------------------------
Frame 0: "HUGZ"
Frame 1: 00000000
Frame 2: <empty>
Frame 3: <empty>
Frame 4: <empty>

客户端可以将 HUGZ 的缺失视为服务器崩溃的指示,请参阅下面的可靠性部分。

客户端到服务器更新

当客户端有哈希映射的更新时,可以将其通过其发布者连接发送给服务器作为 KVSET 命令。KVSET 命令具有此形式

KVSET command
-----------------------------------
Frame 0: key, as 0MQ string
Frame 1: sequence number, 8 bytes in network order
Frame 2: UUID, 16 bytes
Frame 3: properties, as 0MQ string
Frame 4: value, as blob

序列号没有意义,可以为零。如果使用可靠的服务器架构,UUID 应该是一个通用唯一标识符。

如果值为空,服务器必须删除其具有指定键的键值条目。

服务器应该接受以下属性

  • “ttl” - 指定生存时间(秒)。如果 KVSET 命令具有 ttl 属性,服务器应该在 TTL 过期时删除该键值对,并广播一个带有空值的 KVPUB,以从所有客户端中删除它。

可靠性

CHP 可用于双服务器配置,其中备用服务器在主服务器故障时接管。CHP 未指定用于此故障转移的机制,但《指南》中的 Binary Star 模式可能会有所帮助。

为帮助服务器可靠性,客户端可以

  • 在每个 KVSET 命令中设置一个 UUID。
  • 检测在一段时间内缺乏 HUGZ,并将其用作当前服务器已发生故障的指示。
  • 连接到备用服务器并重新请求状态同步。

可伸缩性和性能

CHP 设计用于扩展到大量(数千)客户端,仅受限于代理上的系统资源。由于所有更新都通过单个服务器传递,总吞吐量在峰值时将限制在每秒几百万次更新,可能更低。

安全性

CHP 未实现任何身份验证、访问控制或加密机制,不应在需要这些功能的任何部署中使用。

参考实现

《指南》第 5 章中的 C99 克隆示例(参见“ØMQ - The Guide”)是 CHP 的主要参考实现。