HBASE-7533 Write an RPC Specification for 0.96

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1459094 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2013-03-20 22:57:59 +00:00
parent 5fde90f68f
commit 15a59be843
2 changed files with 172 additions and 0 deletions

View File

@ -3733,6 +3733,8 @@ See the HTrace <filename>README</filename> for more information on Samplers.
</appendix> </appendix>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="rpc.xml" />
<index xml:id="book_index"> <index xml:id="book_index">
<title>Index</title> <title>Index</title>
</index> </index>

170
src/docbkx/rpc.xml Normal file
View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xml:id="hbase.rpc"
version="5.0" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<!--/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<title>0.95 RPC Specification</title>
<para>In 0.95, all client/server communication is done with
<link xlink:href="https://code.google.com/p/protobuf/">protobufed</link> Messages rather than with
<link xlink:href="http://hadoop.apache.org/docs/current/api/org/apache/hadoop/io/Writable.html">Hadoop Writables</link>.
Our RPC wire format therefore changes.
This document describes the client/server request/response protocol and our new RPC wire-format.</para>
<para/>
<para>For what RPC is like in 0.94 and previous,
see Benoît/Tsunas <link xlink:href="https://github.com/OpenTSDB/asynchbase/blob/master/src/HBaseRpc.java#L164">Unofficial Hadoop / HBase RPC protocol documentation</link>.
For more background on how we arrived at this spec., see
<link xlink:href="https://docs.google.com/document/d/1WCKwgaLDqBw2vpux0jPsAu2WPTRISob7HGCO8YhfDTA/edit#">HBase RPC: WIP</link></para>
<para/>
<section><title>RPC</title>
<para>The client will send setup information on connection establish.
Thereafter, the client invokes methods against the remote server sending a protobuf Message and receiving a protobuf Message in response.
Optionally, Cells(KeyValues) can be passed outside of protobufs in follow-behind Cell blocks (because
<link xlink:href="https://docs.google.com/document/d/1WEtrq-JTIUhlnlnvA0oYRLp0F8MKpEBeBSCFcQiacdw/edit#">we cant protobuf megabytes of KeyValues</link> or Cells).
These CellBlocks are encoded and optionally compressed.</para>
<para/>
<para>For more detail on the protobufs involved, see the
<link xlink:href="http://svn.apache.org/viewvc/hbase/trunk/hbase-protocol/src/main/protobuf/RPC.proto?view=markup">RPC.proto</link> file in trunk.</para>
<section>
<title>Connection Setup</title>
<para>Client initiates connection.</para>
<section><title>Client</title>
<para>On connection setup, client sends a preamble followed by a connection header.
</para>
<section>
<title>&lt;preamble&gt;</title>
<para><programlisting>&lt;MAGIC 4 byte integer&gt; &lt;1 byte RPC Format Version&gt; &lt;1 byte auth type&gt;<footnote><para> We need the auth method spec. here so the connection header is encoded if auth enabled.</para></footnote></programlisting></para>
<para>E.g.: HBas0x000x80 -- 4 bytes of MAGIC -- HBas -- plus one-byte of version, 0 in this case, and one byte, 0x80 (SIMPLE). of an auth type.</para>
</section>
<section>
<title>&lt;Protobuf ConnectionHeader Message&gt;</title>
<para>Has user info, and “protocol”, as well as the encoders and compression the client will use sending CellBlocks.
CellBlock encoders and compressors are for the life of the connection.
CellBlock encoders implement org.apache.hadoop.hbase.codec.Codec.
CellBlocks may then also be compressed.
Compressors implement org.apache.hadoop.io.compress.CompressionCodec.</para>
</section>
</section><!--Client-->
<section><title>Server</title>
<para>After client sends preamble and connection header,
server does NOT respond if successful connection setup.  No response means server is READY to accept requests and to give out response.
If the version or authentication in the preamble is not agreeable or the server has trouble parsing the preamble,
it will throw a org.apache.hadoop.hbase.ipc.FatalConnectionException explaining the error and will then disconnect.
If the client in the connection header -- i.e. the protobufd Message that comes after the connection preamble -- asks for for a
Service the server does not support or a codec the server does not have, again we throw a FatalConnectionException with explanation.</para>
</section>
</section>
<section><title>Request</title>
<para>After a Connection has been set up, client makes requests. Server responds.</para>
<para>A request is made up of a protobuf RequestHeader followed by a protobuf Message parameter.
The header includes method name and optionally, metadata on the optional CellBlock that may be following.
The parameter type suits the method being invoked: i.e. if we are doing a getRegionInfo request,
the protobuf Message param will be an instance of GetRegionInfoRequest.
The response will be a GetRegionInfoResponse.
The CellBlock is optionally used ferrying the bulk of the RPC data: i.e Cells/KeyValues.</para>
<para/>
<section><title>Request Parts</title>
<section><title>&lt;Protobuf RequestHeader Message&gt;</title>
<para>Will have call.id, trace.id, and method name, etc. including optional Metadata on the Cell block if one is following.
Data is protobufd inline in this pb Message or optionally comes in the following CellBlock</para>
</section>
<section><title>&lt;Protobuf Param Message&gt;</title>
<para>If the method being invoked is getRegionInfo, if you study the Service descriptor for the client to regionserver protocol,
you will find that the request sends a GetRegionInfoRequest protobuf Message param in this position.</para>
</section>
<section><title>&lt;CellBlock&gt;</title>
<para>An encoded and optionally compressed Cell block.</para>
</section>
</section><!--Request parts-->
</section><!--Request-->
<section><title>Response</title>
<para>Same as Request, it is a protobuf ResponseHeader followed by a protobuf Message response where the Message response type suits the method invoked.
Bulk of the data may come in a following CellBlock.</para>
<section><title>Response Parts</title>
<section><title>&lt;Protobuf ResponseHeader Message&gt;</title>
<para>Will have call.id, etc. Will include exception if failed processing.  Optionally includes metadata on optional, following CellBlock.</para>
</section>
<section><title>&lt;Protobuf Response Message&gt;</title>
<para>Return or may be nothing if exception. If the method being invoked is getRegionInfo, if you study the Service descriptor for the client to regionserver protocol,
you will find that the response sends a GetRegionInfoResponse protobuf Message param in this position.</para>
</section>
<section><title>&lt;CellBlock&gt;</title>
<para>An encoded and optionally compressed Cell block.</para>
</section>
</section><!--Parts-->
</section><!--Response-->
<section><title>Exceptions</title>
<para>There are two distinct types.
There is the request failed which is encapsulated inside the response header for the response.
The connection stays open to receive new requests.
The second type, the FatalConnectionException, kills the connection.</para>
<para>Exceptions can carry extra information.
See the ExceptionResponse protobuf type.
It has a flag to indicate do-no-retry as well as other miscellaneous payload to help improve client responsiveness.</para>
</section>
<section><title>CellBlocks</title>
<para>These are not versioned.
Server can do the codec or it cannot.
If new version of a codec with say, tighter encoding, then give it a new class name.
Codecs will live on the server for all time so old clients can connect.</para>
</section>
</section>
<section><title>Notes</title>
<section><title>Constraints</title>
<para>In some part, current wire-format -- i.e. all requests and responses preceeded by a length -- has been dictated by current server non-async architecture.</para>
</section>
<section><title>One fat pb request or header+param</title>
<para>We went with pb header followed by pb param making a request and a pb header followed by pb response for now.
Doing header+param rather than a single protobuf Message with both header and param content:</para>
<para>
<orderedlist>
<listitem>
<para>Is closer to what we currently have</para>
</listitem>
<listitem>
<para>Having a single fat pb requires extra copying putting the already pbd param into the body of the fat request pb (and same making result)</para>
</listitem>
<listitem>
<para>We can decide whether to accept the request or not before we read the param; for example, the request might be low priority.  As is, we read header+param in one go as server is currently implemented so this is a TODO.</para>
</listitem>
</orderedlist>
</para>
<para>The advantages are minor.  If later, fat request has clear advantage, can roll out a v2 later.</para>
</section>
<section><title>Compression</title>
<para>Uses hadoops compression codecs.</para>
</section>
</section>
</appendix>