文章目录

一、Spark Thrift Server 介绍

Spark Thrift Server 是 Spark 社区基于 HiveServer2 实现的一个 Thrift 服务。旨在无缝兼容 HiveServer2。

因为 Spark Thrift Server 的接口和协议都和 HiveServer2 完全一致,因此我们部署好 Spark Thrift Server 后,可以直接使用 hive 的 beeline 访问 Spark Thrift Server 执行相关语句。

Spark Thrift Server 的目的也只是取代 HiveServer2,因此它依旧可以和 Hive Metastore 进行交互,获取到 hive 的元数据。

二、部署 Spark Thrift Server

先将 hive-site.xml、hdfs-site.xml、core-site.xml 拷贝到 spark/conf 目录下。

如果运行的 Hive MetaStore 版本不是 1.2,需要将 hive-site.xml 中的 hive.metastore.schema.verification 参数设置为 false。否则会因为版本不一致报错

之后还需要拷贝相关 jar 包到 spark/jars 目录,否则会报 Could not load shims in class org.apache.hadoop.hive.schshim.FairSchedulerShim 错误。

cp hive/lib/hive-shims* spark/jars
cp hadoop/share/hadoop/yarn/hadoop-yarn-server-resourcemanager-2.7.4.jar spark/jars

之后启动 Thrift Server

# ThriftServer的本质是将Server服务以spark job的形式提交到集群运行,所以需要指定队列
sbin/start-thriftserver.sh --hiveconf spark.yarn.queue=root.bigdata.date

三、Spark Thrift Server 的架构

Spark Thrift Server 大量复用了 HiveServer2 的代码。

HiveServer2 的架构主要是通过 ThriftCLIService 监听端口,然后获取请求后委托给 CLIService 处理。CLIService 又一层层的委托,最终交给 OperationManager 处理。OperationManager 会根据请求的类型创建一个 Operation 的具体实现处理。比如 Hive 中执行 sql 的 Operation 实现是 SQLOperation。

Spark Thrift Server 做的事情就是实现自己的 CLIService——SparkSQLCLIService,接着也实现了 SparkSQLSessionManager 以及 SparkSQLOperationManager。另外还实现了一个处理 sql 的 Operation——SparkExecuteStatementOperation。这样,当 Spark Thrift Server 启动后,对于 sql 的执行就会最终交给 SparkExecuteStatementOperation 了。

Spark Thrift Server 其实就重写了处理 sql 的逻辑,其他的请求处理就完全复用 HiveServer2 的代码了。比如建表、删除表、建 view 等操作,全部使用的是 Hive 的代码。

四、Spark Thrift Server 如何执行 SQL

Spark Thrift Server 的启动其实是通过 spark-submit 将 HiveThriftServer2 提交给集群执行的。因此执行 start-thriftserver.sh 时可以传入 spark-submit 的参数表示提交 HiveThriftServer2 时的参数。另外,因为 HiveThriftServer2 必须要在本地运行,所以提交时的 deployMode 必须是 client,如果设置成 cluster 会报错。HiveThriftServer2 运行起来后,就等于是一个 Driver 了,这个 Driver 会监听某个端口,等待请求。

** 所以 HiveThriftServer2 程序运行起来后就等于是一个长期在集群上运行的 spark application。** 通过 yarn 或者 spark history server 页面我们都可以看到对应的任务。

既然 HiveThriftServer2 就是 Driver,那么运行 SQL 就很简单了。Spark Thrift Server 收到请求后最终是交给 SparkExecuteStatementOperation 处理,SparkExecuteStatementOperation 拿到 SQLContext,然后调用 SQLContext.sql() 方法直接执行用户传过来的 sql 即可。后面的过程就和我们直接写了一个 Main 函数然后通过 spark-submit 提交到集群运行是一样的。

五、和 HiveServer2 的区别

Hive on SparkSpark Thrift Server
任务提交模式每个 session 都会创建一个 RemoteDriver,也就是对于一个 Application。之后将 sql 解析成执行的物理计划序列化后发到 RemoteDriver 执行本身的 Server 服务就是一个 Driver,直接接收 sql 执行。也就是所有的 session 都共享一个 Application
性能性能一般如果存储格式是 orc 或者 parquet,性能会比 hive 高几倍,某些语句甚至会高几十倍。其他格式的话,性能相差不是很大,有时 hive 性能会更好
并发如果任务执行不是异步的,就是在 thrift 的 worker 线程中执行,受 worker 线程数量的限制。异步的话则放到线程池执行,并发度受异步线程池大小限制。处理任务的模式和 Hive 一样。
sql 兼容主要支持 ANSI SQL 2003,但并不完全遵守,只是大部分支持。并扩展了很多自己的语法Spark SQL 也有自己的实现标准,因此和 hive 不会完全兼容。具体哪些语句会不兼容需要测试才能知道
HA可以通过 zk 实现 HA没有内置的 HA 实现,不过 spark 社区提了一个 issue 并带上了 patch,可以拿来用:https://issues.apache.org/jira/browse/SPARK-11100

Spark Thrift Server 的优点

1、在大部分场景下,性能要比 Hive on spark 好,而且好很多

2、SparkSQL 的社区活跃度也很高,基本每月都会发布一个版本,因此性能还会不断提高

Spark Thrift Server 的缺点

1、因为 HiveThriftServer2 是以 Driver 的形式运行在集群的。因此它能使用的集群资源就和单个 Application 直接挂钩。如果 spark 集群没开启动态资源,那么 Spark Thrift Server 能得到的资源就始终都是固定的,这时候设置太大也不好,设置太小也不好。即使开启了动态资源,一般集群都会设置 maxExecutor,这时还是无法很好的利用集群的所有资源。如果将集群所有的资源都分配给了这个 Application,这样像 yarn、mesos 这些资源调度器就完全没有存在的意义了… 因此,单就这一点,Spark Thrift Server 就不是一个合格的企业级解决方案。

2、从 https://issues.apache.org/jira/browse/SPARK-11100 官方的回答来看,spark 官方对于 Spark Thrift Server 这套解决方案也不是很满意。这也可以理解,毕竟 Spark Thrift Server 只是对 HiveServer2 进行的一些小改造。

3、Spark Thrift Server 目前还是基于 Hive 的 1.2 版本做的改造,因此如果 MetaStore 的版本不是 1.2,那么也可能会有一些兼容性的潜在问题。

六、结论

Spark Thrift Server 说白了就是小小的改动了下 HiveServer2,代码量也不多。虽然接口和 HiveServer2 完全一致,但是它以单个 Application 在集群运行的方式还是比较奇葩的。可能官方也是为了实现简单而没有再去做更多的优化。

所以 Spark Thrift Server 最多搭建起来玩玩,或者自己内部做一些快速查询,并不适合真正放在企业级的使用上。