HDFSRPC协议详解

本文主要阐述HDFSRPCserver端一个socket连接接收字节流的构成,帮助读者理解HDFSRPC协议。注意hadoop版本为3.1.1。

写在前面

  1. 关于proto写入和读取,使用writeDelimitedTo和read,应该是通用的方式,不作过多的介绍。

  2. 处理rpc各种情况以后server都会使用统一的应答格式(包含错误与正确),即

RpcResponseHeaderProto+Message(rpc调用结果,错误时为NULL)
message RpcResponseHeaderProto {/*** RpcStastus - success or failure* The reponseHeader's errDetail,  exceptionClassName and errMsg contains* further details on the error**/required uint32 callId = 1; // callId used in Requestrequired RpcStatusProto status = 2;optional uint32 serverIpcVersionNum = 3; // Sent if success or failoptional string exceptionClassName = 4;  // if request failsoptional string errorMsg = 5;  // if request fails, often contains strack traceoptional RpcErrorCodeProto errorDetail = 6; // in case of erroroptional bytes clientId = 7; // Globally unique client IDoptional sint32 retryCount = 8 [default = -1];
}

RpcStatus的枚举类,注意当使用FATAL时,connection会关闭

 enum RpcStatusProto {SUCCESS = 0;  // RPC succeededERROR = 1;    // RPC or error - connection left open for future callsFATAL = 2;    // Fatal error - connection closed}

RPC错误的枚举类

enum RpcErrorCodeProto {// Non-fatal Rpc error - connection left open for future rpc callsERROR_APPLICATION = 1;      // RPC Failed - rpc app threw exceptionERROR_NO_SUCH_METHOD = 2;   // Rpc error - no such methodERROR_NO_SUCH_PROTOCOL = 3; // Rpc error - no such protocolERROR_RPC_SERVER  = 4;      // Rpc error on server sideERROR_SERIALIZING_RESPONSE = 5; // error serializign responseERROR_RPC_VERSION_MISMATCH = 6; // Rpc protocol version mismatch// Fatal Server side Rpc error - connection closedFATAL_UNKNOWN = 10;                   // unknown Fatal errorFATAL_UNSUPPORTED_SERIALIZATION = 11; // IPC layer serilization type invalidFATAL_INVALID_RPC_HEADER = 12;        // fields of RpcHeader are invalidFATAL_DESERIALIZING_REQUEST = 13;     // could not deserilize rpc requestFATAL_VERSION_MISMATCH = 14;          // Ipc Layer version mismatchFATAL_UNAUTHORIZED = 15;              // Auth failed}

RPC如果成功,会在head写完后,紧接着写入rpc调用结果proto。

Rpc连接数据流说明

连接中接收的数据结构图

7byte4byte(int len)+RpcrequestconnectionContext4byte(int len)+Rpcrequest
connectionHeaderRpcrequestconnectionContextRpcrequest

connectionHeader

/*** The Rpc-connection header is as follows * +----------------------------------+* |  "hrpc" 4 bytes                  |      * +----------------------------------+* |  Version (1 byte)                |* +----------------------------------+* |  Service Class (1 byte)          |* +----------------------------------+* |  AuthProtocol (1 byte)           |      * +----------------------------------+*/

任何一个连接都会有connectionHeader,connectionHeader由7个字节组成,内容如上。

关于header的check:第一是check前4个字节是否为hrpc,第二是check version。Check version由于要兼顾老版本,处理起来会比较复杂。

当前正确的Version为9:

  // 1 : Introduce ping and server does not throw away RPCs// 3 : Introduce the protocol into the RPC connection header// 4 : Introduced SASL security layer// 5 : Introduced use of {@link ArrayPrimitiveWritable$Internal} in ObjectWritable to efficiently transmit arrays of primitives// 6 : Made RPC Request header explicit// 7 : Changed Ipc Connection Header to use Protocol buffers// 8 : SASL server always sends a final response// 9 : Changes to protocol for HADOOP-8990public static final byte CURRENT_VERSION = 9;

Version的错误处理:

String errMsg = "Server IPC version " + CURRENT_VERSION + " cannot communicate with client version " + clientVersion;
String errClassName = "org.apache.hadoop.ipc.VersionMismatch";

Version=1 不处理

Version=2

4byte(int = 0)1byte(boolean=true)Int+bytes(int为String长度)(String=errClassName)Int+bytes(String=errMsg)

Version=3~8

4byte(int = callId)4byte(int=-1)Int+bytes(int为String长度)(String=errClassName)Int+bytes(String=errMsg)

Version>9(如果前4个字节不为hrpc,也是此错误)

RpcStatusProto.FATAL

RpcErrorCodeProto.FATAL_VERSION_MISMATCH

errMsg

errClassName

AuthProtocol:

现有两个值:NONE(0),SASL(-33),现在只使用0,sasl在后续文章中会有解析。

processOneRpc

任何一个rpcRequest都是由head和body组成

Head的结构

message RpcRequestHeaderProto { // the header for the RpcRequestenum OperationProto {RPC_FINAL_PACKET        = 0; // The final RPC PacketRPC_CONTINUATION_PACKET = 1; // not implemented yetRPC_CLOSE_CONNECTION     = 2; // close the rpc connection}optional RpcKindProto rpcKind = 1;optional OperationProto rpcOp = 2;required sint32 callId = 3; // a sequence number that is sent back in responserequired bytes clientId = 4; // Globally unique client ID// clientId + callId uniquely identifies a request// retry count, 1 means this is the first retryoptional sint32 retryCount = 5 [default = -1];optional RPCTraceInfoProto traceInfo = 6; // tracing infooptional RPCCallerContextProto callerContext = 7; // call context
}

关于Head的check

必须有rpcOP;rpcOP必须为RPC_FINAL_PACKET;必须有rpcKind

Head中比较重要的是callId属性,callId<0为特殊包,callId>=0为正常请求包。

callId<0

callId=PING_CALL_ID 不处理只打印日志

callId=CONNECTION_CONTEXT_CALL_ID

一般接收完connectionHeader,第一个RPC就为connectionContext。

connectionContext的结构

message IpcConnectionContextProto {// UserInfo beyond what is determined as part of security handshake // at connection time (kerberos, tokens etc).optional UserInformationProto userInfo = 2;// Protocol name for next rpc layer.// The client created a proxy with this protocol nameoptional string protocol = 3;
}
message UserInformationProto {optional string effectiveUser = 1;optional string realUser = 2;
}

主要是注意用户,hdfs server会把用户名作为connection Map的key。

还要注意connectionContext每个连接一直有一个,并且接收完此rpc以后立刻会接收下个rpc。

callId=AuthProtocol.SASL.callId(-33)

后续安全文章介绍。

callId>=0

需要注意的是如果没有接收connectionContext,将不会接收callId>=0的rpcRequest,否则则报错。

Hdfs server会根据rpcRequest head中的rpcKind,把rpcRequest body变成对应的对象。

enum RpcKindProto {RPC_BUILTIN          = 0;  // Used for built in calls by testsRPC_WRITABLE         = 1;  // Use WritableRpcEngine RPC_PROTOCOL_BUFFER  = 2;  // Use ProtobufRpcEngine
}

例如当rpcKind=RPC_PROTOCOL_BUFFER

Body=RpcProtobufRequest

RpcProtobufRequest又由RequestHeaderProto和Message(body)组成

RequestHeaderProto的结构

message RequestHeaderProto {required string methodName = 1;required string declaringClassProtocolName = 2;required uint64 clientProtocolVersion = 3;
}

Message(body)一般就是方法的入参。

Server在启动的时候会注册需要用的ProtocolName列表和实现类。例如

ClientNamenodeProtocolPB

ClientNamenodeProtocolPB继承与ClientNamenodeProtocol.BlockingInterface,实际就是ClientNamenodeProtocol.proto中的service定义

service ClientNamenodeProtocol {rpc getBlockLocations(GetBlockLocationsRequestProto)returns(GetBlockLocationsResponseProto);rpc getServerDefaults(GetServerDefaultsRequestProto)returns(GetServerDefaultsResponseProto);...
}

ClientNamenodeProtocolPB会有自己的

ProtocolName(org.apache.hadoop.hdfs.protocol.ClientProtocol)和ProtocolVersion(1)。

RequestHeaderProto中包含了declaringClassProtocolName 和clientProtocolVersion 可以找到对应的协议已经实现类,并根据methodName 去调用对应的方法。例如getBlockLocations方法,如下图。

在此方法中最终的RpcProtobufRequest中的Message(body)会format成

GetBlockLocationsRequestProto对象,调用完成后会返回GetBlockLocationsResponseProto。返回格式具体参考统一返回。

rotocolVersion 可以找到对应的协议已经实现类,并根据methodName 去调用对应的方法。例如getBlockLocations方法,如下图。

[外链图片转存中…(img-PY9haIcM-1710299505785)]

在此方法中最终的RpcProtobufRequest中的Message(body)会format成

GetBlockLocationsRequestProto对象,调用完成后会返回GetBlockLocationsResponseProto。返回格式具体参考统一返回。

独立站原文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/743379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Watt Toolkit (原名 Steam++)加速github访问

这里写自定义目录标题 安装使用可能问题SSL certificate problem 参考 安装 访问 官网下载 下载安装(或解压) 使用 打开 Steam 可执行文件点击网络加速按钮&#xff0c;再选择平台加速选项卡&#xff0c;勾选github项开启加速&#xff1a;点击一键加速按钮关闭加速&#xff…

Electron内调用网页出现 $ is not defined 或者 jQuery is not defined

打包了一个electron应用&#xff0c;引入一个部署好的网页。意外发现&#xff0c;之前在浏览器好好的功能&#xff0c;此刻在electron内部却出现报错&#xff1a; "$ is not defined"\"jQuery is not defined"\ "Luckysheet is not defined" ...…

【测试开发学习历程】压缩、打包与软件安装

目录 一、压缩与打包 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;压缩命令gzip &#xff08;三&#xff09;压缩命令bzip2 &#xff08;四&#xff09;打包命令tar &#xff08;五&#xff09;压缩命令zip 二、常用的安装软件的方式 &#xff08;一&am…

《智能便利,畅享便利柜平台的架构奇妙之旅》

便利柜平台作为一种智能化、便捷的自助服务解决方案&#xff0c;正在逐渐走进人们的生活。本篇博客将深入探讨便利柜平台的架构设计理念、优势和实践&#xff0c;帮助读者了解如何构建智能便利柜平台&#xff0c;提供更便捷的自助服务体验。 ### 便利柜平台架构设计 #### 1. …

Java8中Stream流API最佳实践Lambda表达式使用示例

文章目录 一、创建流二、中间操作和收集操作筛选 filter去重distinct截取跳过映射合并多个流是否匹配任一元素&#xff1a;anyMatch是否匹配所有元素&#xff1a;allMatch是否未匹配所有元素&#xff1a;noneMatch获取任一元素findAny获取第一个元素findFirst归约数值流的使用中…

Android 子线程为什么不能更新UI?

Android 应用的 UI 是在主线程上进行绘制和更新的。 当我们在子线程中直接进行 UI 更新时&#xff0c;会导致以下问题&#xff1a; 1. 线程安全问题&#xff1a;多个线程同时操作 UI&#xff0c;可能导致 UI 组件的状态不一致或者出现竞争条件。 2. 卡顿和 ANR&#xff1a;如果…

Redis有没有可能丢数据

Redis在某些情况下有可能会丢失数据。尽管Redis是一个高性能的内存数据库&#xff0c;但是由于其工作方式和特性&#xff0c;存在一些情况下可能导致数据丢失的情况&#xff0c;包括&#xff1a; 内存溢出&#xff1a; 如果Redis实例的内存用尽&#xff0c;而没有足够的空间来处…

数据结构入门篇 之 【双链表】的实现讲解(附完整实现代码及顺序表与线性表的优缺点对比)

一日读书一日功&#xff0c;一日不读十日空 书中自有颜如玉&#xff0c;书中自有黄金屋 一、双链表 1、双链表的结构 2、双链表的实现 1&#xff09;、双向链表中节点的结构定义 2&#xff09;、初始化函数 LTInit 3&#xff09;、尾插函数 LTPushBack 4&#xff09;、头…

单据分页的实现

单据分页的实现 1. AceWzcgfkjtMaintainProxy.java package nc.ui.jych.wzcgfkjt.ace.serviceproxy;import nc.bs.framework.common.NCLocator; import nc.itf.jych.IWzcgfkjtMaintain; import nc.ui.uif2.components.pagination.IPaginationQueryService; import nc.vo.jych.…

软考高级:信息系统开发方法2(形式化方法、统计过程方法等)概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

RTC协议与算法基础 - RTP/RTCP

首先&#xff0c;需要说明下&#xff0c;webrtc的核心音视频传输是通过RTP/RTCP协议实现的&#xff0c;源码位于src/modules/rtp_rtcp目录下&#xff1a; 下面让我们对相关的内容基础进行简要分析与说明&#xff1a; 一、TCP与UDP协议 1.1、TCP协议 TCP为了实现数据传输的可…

【Python】新手入门学习:详细介绍依赖倒置原则(DIP)及其作用、代码示例

【Python】新手入门学习&#xff1a;详细介绍依赖倒置原则&#xff08;DIP&#xff09;及其作用、代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、Py…

如何将.txtpb在IDE中彩色高亮显示

1. 问题描述 文件内容片段如下&#xff0c;它采用了一种键值对的格式&#xff0c;其中还包括了注释。我们可以采用一种近似的语言色彩识别方案处理它&#xff0c;比如YAML或者Python的语法高亮规则&#xff0c;因为这两种语言在处理键值对和注释的表示上与内容片段相似。当然也…

【QT+QGIS跨平台编译】之七十三:【QGIS_Analysis跨平台编译】—【错误处理:字符串错误】

文章目录 一、字符串错误二、处理方法三、涉及到的文件一、字符串错误 常量中有换行符错误:(也有const char * 到 LPCWSTR 转换的错误) 二、处理方法 需要把对应的文档用记事本打开,另存为 “带有BOM的UTF-8” 三、涉及到的文件 涉及到的文件有: src\analysis\processin…

spring boot-操作excel(EasyExcel 快速开始)/ spring boot接受文件参数 File

文章目录 一、spring boot 操作excel1. 技术选型1.1 EasyExcel1.2 POI 二、EasyExcel使用0. 工作中使用总结1. maven 引入2. demo1&#xff1a;excel写入文件3. demo2&#xff1a;SpringBoot项目中集成EasyExcel实现Excel文件的下载response的三个属性&#xff1a;编码、类型、…

gcc -static参数

在使用 GCC&#xff08;GNU Compiler Collection&#xff09;编译器编译C语言或C语言程序时&#xff0c;-static 选项告诉编译器生成一个完全静态链接的可执行文件。这就意味着程序需要的所有库在编译时都会被包含在执行文件中&#xff0c;它不会在运行时链接动态库&#xff08…

openssl3.2 - exp - 选择最好的内建椭圆曲线

文章目录 openssl3.2 - exp - 选择最好的内建椭圆曲线概述笔记将 openssl ecparam -list_curves 实现迁移到自己的demo工程备注END openssl3.2 - exp - 选择最好的内建椭圆曲线 概述 在openssl中使用椭圆曲线, 只允许选择椭圆曲线的名字, 无法给定椭圆曲线的位数. 估计每种椭…

储能系统--户用储能市场现状(三)

1、户用储能市场现状 2022年&#xff0c;俄乌冲突造成能源价格飙升&#xff0c;欧洲居民电价飞涨&#xff0c;成为点燃户储需求的引线。以德国为例&#xff0c;2022年的居民电价达到40欧分/kWh以上&#xff0c;相比2021年初翻了三倍。因此2022年被称为户储爆发元年&#xff0c…

深度学习armv8/armv9 cache的原理

文章目录 前言1、为什么要用cache?2、背景:架构的变化?2、cache的层级关系 ––big.LITTLE架构&#xff08;A53为例)3、cache的层级关系 –-- DynamIQ架构&#xff08;A76为例)4、DSU / L3 cache5、L1/L2/L3 cache都是多大呢6、cache相关的术语介绍7、cache的分配策略(alocat…

Llama-3即将发布:Meta公布其庞大的AI算力集群

Meta&#xff0c;这家全球科技巨头&#xff0c;再次以其在人工智能&#xff08;AI&#xff09;领域的雄心壮志震惊了世界。3月13日&#xff0c;公司在其官方网站上宣布了两个全新的24K H100 GPU集群&#xff0c;这些集群专为训练其大型模型Llama-3而设计&#xff0c;总计拥有高…