在 0.95 中,所有客户端/服务器通信都是使用 protobuf'ed 消息而不是 Hadoop Writables 完成的。因此我们的 RPC 线格式会发生变化本文档描述了客户端/服务器请求/响应协议以及我们新的 RPC 线路格式。
对于 0.94 及之前的 RPC,请参阅 Benoît/ Tsuna 的非官方 Hadoop / HBase RPC 协议文档。有关我们如何达到此规范的更多背景信息,请参阅 HBase RPC:WIP
我们可以发展一种线形式
一种格式,不需要我们的重写服务器核心或从根本上改变其当前架构(以后)。
当前指定格式的问题列表以及我们希望在版本 2 中的位置等。例如,如果要移动服务器异步或支持流/分块,我们必须更改什么?
关于它如何工作的图表
简洁地描述线格式的语法。目前我们有这些单词和 rpc protobuf idl 的内容,但来回的语法将有助于 groking rpc。此外,客户端/服务器上的一个小型状态机交互将有助于理解(并确保正确实现)。
客户端将发送有关连接建立的设置信息。此后,客户端调用针对远程服务器的方法发送 protobuf 消息并接收 protobuf 消息作为响应。沟通是同步的。所有来回前面都有一个 int,它具有请求/响应的总长度。可选地,Cells(KeyValues)可以在后续 Cell 块中的 protobufs 之外传递(因为我们不能 protobuf 兆字节的 KeyValues 或 Cells)。这些 CellBlock 被编码并可选地压缩。
有关所涉及的 protobufs 的更多详细信息,请参阅 master 中的 RPC.proto 文件。
客户端启动连接。
在连接设置上,客户端发送前导码,后跟连接头。
<MAGIC 4 byte integer> <1 byte RPC Format Version> <1 byte auth type>
我们需要 auth 方法规范。这里,如果启用 auth,则编码连接头。
例如:HBas0x000x50 - 4 个字节的 MAGIC - “HBas” - 加上一个字节的版本,在这种情况下为 0,还有一个字节,0x50(SIMPLE)。一个身份验证类型。
有用户信息和``protocol'',以及客户端将使用发送 CellBlocks 的编码器和压缩。 CellBlock 编码器和压缩器用于连接的生命周期。 CellBlock 编码器实现 org.apache.hadoop.hbase.codec.Codec。然后也可以压缩 CellBlock。压缩器实现 org.apache.hadoop.io.compress.CompressionCodec。这个 protobuf 是使用 writeDelimited 编写的,所以它是以带有序列化长度的 pb varint 开头的
客户端发送前导码和连接头后,如果连接设置成功,服务器不响应。没有响应意味着服务器准备好接受请求并给出响应。如果前导中的版本或身份验证不合适或服务器在解析前导码时遇到问题,则会抛出 org.apache.hadoop.hbase.ipc.FatalConnectionException 来解释错误,然后断开连接。如果连接头中的客户端 - 即连接前导码后面的 protobuf'd 消息 - 要求服务器不支持服务器或服务器没有的编解码器,我们再次抛出 FatalConnectionException 并附带说明。
建立连接后,客户端发出请求。服务器响应。
请求由 protobuf RequestHeader 和 protobuf Message 参数组成。标头包括方法名称和可选的 CellBlock 上可能跟随的元数据。参数类型适合被调用的方法:即,如果我们正在执行 getRegionInfo 请求,则 protobuf Message param 将是 GetRegionInfoRequest 的实例。响应将是 GetRegionInfoResponse。 CellBlock 可选地用于传送大量 RPC 数据:即 Cells / KeyValues。
该请求以一个 int 开头,该 int 保存后面的总长度。
将包含 call.id,trace.id 和方法名称等,包括 IFF 上的 Cell 块上的可选元数据。数据在此 pb 消息中是内联的,或者可选地包含在以下 CellBlock 中
如果调用的方法是 getRegionInfo,如果您研究客户端的服务描述符到 regionserver 协议,您会发现请求在此位置发送 GetRegionInfoRequest protobuf 消息参数。
经编码且可选地压缩的 Cell 块。
与 Request 相同,它是一个 protobuf ResponseHeader,后跟一个 protobuf Message 响应,其中 Message 响应类型适合调用的方法。大量数据可能会出现在以下 CellBlock 中。
响应以一个 int 开头,该 int 保存了后面的总长度。
将有 call.id 等。如果处理失败将包括异常。可选地包括关于可选的元数据,IFF 下面有一个 CellBlock。
如果例外,则返回或可能无效。如果调用的方法是 getRegionInfo,如果您研究客户端的服务描述符到 regionserver 协议,您会发现响应在此位置发送 GetRegionInfoResponse protobuf 消息参数。
An encoded and optionally compressed Cell block.
有两种不同的类型。请求失败,它封装在响应的响应头内。连接保持打开状态以接收新请求。第二种类型 FatalConnectionException 会终止连接。
例外可以携带额外的信息。请参阅 ExceptionResponse protobuf 类型。它有一个标志,表示不重试以及其他杂项有效负载,以帮助提高客户响应能力。
这些都没有版本。服务器可以执行编解码器,也可以不执行。如果编解码器的新版本说更严格的编码,那么给它一个新的类名。编解码器将一直存在于服务器上,以便老客户端可以连接。
约束
在某些部分,当前的线路格式 - 即所有请求和响应前面都有一个长度 - 由当前的服务器非异步架构决定。
一个胖 pb 请求或标题+参数
我们用 pb 标题跟随 pb param 发出请求和 pb 标题然后是 pb 响应。执行 header + param 而不是一个包含 header 和 param 内容的 protobuf 消息:
更接近我们现在拥有的
有一个单一的脂肪 pb 需要额外的复制将已经 pb'd 的参数放入脂肪请求 pb 的主体(并且相同的结果)
在我们阅读参数之前,我们可以决定是否接受请求;例如,请求可能是低优先级。当然,我们一次性读取 header + param,因为服务器当前已实现,因此这是一个 TODO。
优点很小。如果以后,胖请求有明显的优势,以后可以推出 v2。
CellBlock 编解码器
要启用默认KeyValueCodec
以外的编解码器,请将hbase.client.rpc.codec
设置为要使用的 Codec 类的名称。编解码器必须实现 hbase 的Codec
接口。连接建立后,所有传递的单元块将与此编解码器一起发送。只要编解码器在服务器的 CLASSPATH 上,服务器就会使用相同的编解码器返回单元块(否则你将获得UnsupportedCellCodecException
)。
要更改默认编解码器,请设置hbase.client.default.rpc.codec
。
要完全禁用单元块并转到纯 protobuf,请将默认值设置为空 String,并且不要在 Configuration 中指定编解码器。因此,将hbase.client.default.rpc.codec
设置为空字符串,不要设置hbase.client.rpc.codec
。这将导致客户端连接到没有指定编解码器的服务器。如果服务器没有看到编解码器,它将返回纯 protobuf 中的所有响应。一直运行纯 protobuf 比使用 cellblocks 运行要慢。
压缩
使用 hadoop 的压缩编解码器。要启用压缩传递的 CellBlock,请将hbase.client.rpc.compressor
设置为要使用的 Compressor 的名称。 Compressor 必须实现 Hadoop 的 CompressionCodec 接口。连接建立后,所有传递的单元块将被压缩发送。只要压缩器在 CLASSPATH 上,服务器就会返回使用同一压缩器压缩的单元块(否则你将获得UnsupportedCompressionCodecException
)。