《SparkSQL内核剖析》【Thrift Server篇】

本文介绍了Thrift的基本概念,包括其接口定义语言、协议层、传输层和数据类型。详细阐述了Spark Thrift Server的作用,它是如何提供分布式的SQL接口。通过Spark Thrift Server,客户端可以交互式地执行Spark SQL操作。文中还提及了会话管理和操作管理在Spark SQL中的实现。
摘要由CSDN通过智能技术生成

写在前面

前两天,我司开发环境Zeppelin在跑一个统计任务时,挂了,报错信息如下:
在这里插入图片描述

Thrift Server通信失败了,具体原因没有深究。然而,Thrift这个看似熟悉却又陌生的词汇吸引了我的注意力。碰巧今天在学习《Spark内核剖析》第10章,Spark SQL连接Hive时,又一次提到了Thrift,于是便有了此文。

本文主要回答以下问题

  • Thrift是什么、有什么用
  • Spark Thrift Server是什么、有什么用

什么是Thrift

Thrift是一种接口描述语言和二进制通讯协议,可以用来定义跨语言的服务。跨语言服务通信协议并不是什么稀奇玩意儿,有基于JSON格式的RESTful服务,基于XML格式的SOAP Web Service等。Thrift由Facebook开源,谷歌也开源了类似的技术,叫做Protobuf。它们带来最主要的好处是提供了一种跨语言通信的机制,其次是支持二进制格式压缩消息,进行IO优化,从而提升了数据传输性能。

举个例子,HBase是Java语言编写的,它提供了Java API接口,但其他语言的客户端怎么办呢?这时候HBase就可以用Thrift实现一套通信接口,从而其他编程语言也可以使用HBase的各种客户端API。

一个Thrift服务的基本框架如下图所示,由以下几个关键部分组成

  • 接口定义,定义接口字段和数据格式,采用Interface Definition Language(IDL)编写,例如下图中的Hello.java
  • 公共文件, 利用代码生成工具,由接口定义生成特定编程语言的框架代码和库依赖文件
  • 客户端实现,自行实现客户端通信逻辑
  • 服务端实现,自行实现服务端通信逻辑

这也就表明了使用Thrift的基本步骤:1. 定义接口 2. 生成代码框架 3. 实现服务端和客户端逻辑。
Thrift基础框架
例如下面的Hello.thrift,定义了服务 Hello 的五个方法,每个方法包含一个方法名,参数列表和返回类型。每个参数包括参数序号,参数类型以及参数名。使用 Thrift 工具编译 Hello.thrift,就会生成相应的 Hello.java 文件。该文件包含了在 Hello.thrift 文件中描述的服务 Hello 的接口定义,即 Hello.Iface 接口,以及服务调用的底层通信细节。

namespace java service.demo 
service Hello{
    
 string helloString(1:string para) 
 i32 helloInt(1:i32 para) 
 bool helloBoolean(1:bool para) 
 void helloVoid() 
 string helloNull() 
}

Thrift基本结构

Thrift的基本结构如下图所示
在这里插入图片描述

SeriviceClient和ServiceProcessor这一层,以及write()/read()这一层,是由代码生成器产生。
协议层Protocol、传输层Transport和底层IO由Thrift框架提供,我们不需要过度关心。
我们展开介绍下协议层TProtocol和传输层TTransport。

协议层

协议层定义的是传输什么内容,回答的是What的问题。

  • TBinaryProtocol 二进制编码格式
  • TCompactProtocol 密集的二进制编码格式
  • TJSONProtocol JSON 数据编码格式
  • TSimpleJSONProtocol 简化版JSON协议,只支持写入的协议
  • TDebugProtocol 使用人类可读的txt格式,辅助debug

传输层

传输层定义的是传输方式,回答的是How的问题。

TTransport这一层负责抽象出操作系统无关的通信协议;支持的传输协议包括:

  • TSocket - 使用阻塞式 I/O 进行传输,是最常见的模式
  • TFramedTransport - 使用非阻塞方式,按块的大小进行传输,类似于 Java 中的 NIO
  • TNonblockingTransport - 使用非阻塞方式,用于构建异步客户端
  • TMemoryTransport - 使用内存IO
  • TZlibTransport - 使用zlib进行压缩

数据类型

  • 基本类型,包括bool,byte,int16,int32,int64,double,string
  • 结构体,参考C语言struct
  • 枚举
  • 容器,包括List,Set,Map等
  • 异常
  • 服务

不支持的数据类型:

  • 循环结构体 - 结构体只能包含在它之前声明过的结构体。结构体不能包含自身
  • 结构体继承- 应该使用结构体组合代替继承
  • 多态- 因为没有继承,所以同样不支持多态
  • 重载- 一个服务中的方法必须不重名
  • 异构容器 - 所有容器中的元素必须具有相同类型
  • 返回null - 函数不能直接返回null,应该使用包装结构体或者标记值代替null。

Spark Thrift Sever

Spark Thrift Server是做什么的呢?

我们要交互式地使用Spark SQL执行各种操作:读入数据,执行统计分析,写出数据等等。这个交互的过程就是由Spark Thrift Server提供服务端支持的。Spark项目利用Thrift Server对外提供了一个分布式的SQL接口。

Spark Thrift的客户端和服务端交互中,两个重要的概念是会话Session操作Operation。会话就是一次访问周期,从客户端发起访问开始,到服务端或客户端关闭时结束。操作就是客户端向服务端发起的各种动作。通常情况下服务端同时管理着多个会话,每个会话对应一个客户端。每个会话、每个操作都有一个引用称作句柄,分别叫做会话句柄SessionHandle操作句柄OperationHandle。会话句柄是在客户端持久化服务端信息的结构体,主要内容就是服务端的ID。操作句柄是客户端的引用,它指向服务端异步运行的一个任务。它们的定义见sql/hive-thriftserver/if/TCLIService.thrift

// Client-side handle to persistent
// session information on the server-side.
struct TSessionHandle {
   
  1: required THandleIdentifier sessionId
}
// Client-side reference to a task running
// asynchronously on the server.
struct TOperationHandle {
   
  1: required THandleIdentifier operationId
  2: required TOperationType operationType
  3: required bool hasResultSet
  4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值