如何在Thrift服务器上查看pyspark临时表?

时间:2019-06-29 20:41:24

标签: python apache-spark pyspark thrift spark-thriftserver

我正在尝试通过Thrift在pyspark上创建一个临时表。我的最终目标是能够使用JDBC从数据库客户端(如DBeaver)访问它。

我先用蜂线测试。

这就是我在做什么。

  1. 使用docker在我自己的计算机上启动了一个只有一个工作人员的集群,并在spark.sql.hive.thriftServer.singleSession true上添加了spark-defaults.conf
  2. 启动Pyspark shell(出于测试目的)并运行以下代码:

    from pyspark.sql import Row l = [('Ankit',25),('Jalfaizy',22),('saurabh',20),('Bala',26)] rdd = sc.parallelize(l) people = rdd.map(lambda x: Row(name=x[0], age=int(x[1]))) people = people.toDF().cache() peebs = people.createOrReplaceTempView('peebs') result = sqlContext.sql('select * from peebs')

    到目前为止,一切正常。

  3. 在另一个终端上,我初始化spark thrift服务器: ./sbin/start-thriftserver.sh --hiveconf hive.server2.thrift.port=10001 --conf spark.executor.cores=1 --master spark://172.18.0.2:7077

    服务器似乎正常启动,并且我可以在我的Spark集群主UI上看到正在运行的pyspark和thrift服务器作业。

  4. 然后我使用蜂线连接到集群

    ./bin/beeline beeline> !connect jdbc:hive2://172.18.0.2:10001

    这就是我得到的

      

    连接到jdbc:hive2://172.18.0.2:10001   
    输入jdbc:hive2://172.18.0.2:10001的用户名:   
    输入jdbc:hive2://172.18.0.2:10001的密码:   
    2019-06-29 20:14:25信息实用程序:310-提供的权限:172.18.0.2:10001   
    2019-06-29 20:14:25信息实用程序:397-已解决的权限:172.18.0.2:10001   
    2019-06-29 20:14:25信息HiveConnection:203-将尝试使用JDBC Uri打开客户端传输:jdbc:hive2://172.18.0.2:10001   
    连接到:Spark SQL(版本2.3.3)   
    驱动程序:Hive JDBC(1.2.1.spark2版本)   
    交易隔离:TRANSACTION_REPEATABLE_READ

    似乎还可以。

  5. 当我列出show tables;时,我什么都看不到。

我想强调的两个有趣的事情是:

  1. 当我启动pyspark时,我收到这些警告

      

    WARN ObjectStore:6666-在metastore中找不到版本信息。 hive.metastore.schema.verification未启用,因此记录架构版本1.2.0

         

    WARN ObjectStore:568-无法获取数据库默认值,返回NoSuchObjectException

         

    WARN ObjectStore:568-无法获取数据库global_temp,返回NoSuchObjectException

  2. 启动节俭服务器时,我得到了这些信息:

      

    rsync from spark://172.18.0.2:7077   
    ssh:无法解析主机名spark:名称或服务未知   
    rsync:连接意外关闭(到目前为止已收到0个字节)[接收器]   
    rsync错误:io.c(235)出现无法解释的错误(代码255)[Receiver = 3.1.2]   
    启动org.apache.spark.sql.hive.thriftserver.HiveThriftServer2,登录到...

我已经浏览了几篇文章和讨论。我看到有人说除非通过同一代码启动服务器,否则无法通过节俭公开临时表。如果是这样,我该如何在python(pyspark)中做到这一点?

谢谢

3 个答案:

答案 0 :(得分:0)

createOrReplaceTempView创建一个内存表。需要在创建内存表的同一驱动程序JVM上启动Spark节俭服务器。
在上面的示例中,创建表的驱动程序与运行STS(Spark Thrift服务器)的驱动程序不同。
两种选择
1.在启动STS的同一JVM中使用createOrReplaceTempView创建表。
2.使用支持的metastore,并使用org.apache.spark.sql.DataFrameWriter#saveAsTable创建表,以便可以独立于JVM访问表(实际上没有任何Spark驱动程序。

关于错误:
1.与客户端和服务器元存储库版本有关。
2.似乎有些rsync脚本试图解码spark:\\ url
两者似乎都与该问题无关。

答案 1 :(得分:0)

经过几次测试,我能够提出一个对我有用的简单(无需身份验证)代码。

重要的一点是,如果要通过JDBC提供临时表,则需要在同一JVM中启动Thrift服务器(相同的Spark作业),并确保代码挂起,以便应用程序在集群中保持运行。

下面是我创建的可供参考的示例代码:

import time
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession
from py4j.java_gateway import java_import

spark = SparkSession \
    .builder \
    .appName('the_test') \
    .enableHiveSupport()\
    .config('spark.sql.hive.thriftServer.singleSession', True)\
    .config('hive.server2.thrift.port', '10001') \
    .getOrCreate()

sc=spark.sparkContext
sc.setLogLevel('INFO')

java_import(sc._gateway.jvm, "")


from pyspark.sql import Row
l = [('John', 20), ('Heather', 34), ('Sam', 23), ('Danny', 36)]
rdd = sc.parallelize(l)
people = rdd.map(lambda x: Row(name=x[0], age=int(x[1])))
people = people.toDF().cache()
peebs = people.createOrReplaceTempView('peebs')

sc._gateway.jvm.org.apache.spark.sql.hive.thriftserver.HiveThriftServer2.startWithContext(spark._jwrapped)

while True:
    time.sleep(10)

我在spark-submit中仅使用了上面的.py,并且我能够通过beeline通过JDBC并通过Hive JDBC Driver使用DBeaver进行连接。

答案 2 :(得分:0)

万一有人需要在Spark Streaming中执行此操作,我可以使它像这样工作。

from pyspark.sql.functions import *
from pyspark.sql.types import *
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession
from py4j.java_gateway import java_import

spark = SparkSession \
    .builder \
    .appName('restlogs_qlik') \
    .enableHiveSupport()\
    .config('spark.sql.hive.thriftServer.singleSession', True)\
    .config('hive.server2.thrift.port', '10001') \
    .getOrCreate()

sc=spark.sparkContext
sc.setLogLevel('INFO')

#Order matters! 
java_import(sc._gateway.jvm, "")
sc._gateway.jvm.org.apache.spark.sql.hive.thriftserver.HiveThriftServer2.startWithContext(spark._jwrapped)

#Define schema of json
schema = StructType().add("partnerid", "string").add("sessionid", "string").add("functionname", "string").add("functionreturnstatus", "string")

#load data into spark-structured streaming
df = spark \
      .readStream \
      .format("kafka") \
      .option("kafka.bootstrap.servers", "localhost:9092") \
      .option("subscribe", "rest_logs") \
      .load() \
      .select(from_json(col("value").cast("string"), schema).alias("parsed_value"))

#Print output
query = df.writeStream \
            .outputMode("append") \
            .format("memory") \
            .queryName("view_figures") \
            .start()

query.awaitTermination();

启动后,您可以使用带有蜂巢的JDBC进行测试。我无法理解的是,我必须在同一脚本中启动Thrift服务器。这是启动脚本的方法。

    spark-submit --master local[2] \
--conf "spark.driver.extraClassPath=D:\\Libraries\\m2_repository\\org\\apache\\kafka\\kafka-clients\\2.0.0\\kafka-clients-2.0.0.jar" \
--packages org.apache.spark:spark-sql-kafka-0-10_2.11:2.4.1 \
"C:\\Temp\\spark_kafka.py"

希望这对某人有帮助。顺便说一下,我正处于初步研究阶段,请不要对我进行评判。