12/CHP
集群哈希映射协议
- 状态:稳定
- 编辑:Pieter Hintjens ph@imatix.com
集群哈希映射协议 (CHP) 定义了一个集群范围的键值哈希映射,以及在客户端集合之间共享此哈希映射的机制。CHP 允许客户端使用哈希映射的子树,更新值,以及定义临时值。CHP 源自《指南》第 5 章中定义的 Clone 模式。
- 名称:https://rfc.zeromq.cn/spec:12/CHP
- 编辑:Pieter Hintjens ph@imatix.com
许可证
版权所有 (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 的主要参考实现。