我正在尝试通过Thrift在pyspark上创建一个临时表。我的最终目标是能够使用JDBC从数据库客户端(如DBeaver)访问它。
我先用蜂线测试。
这就是我在做什么。
spark.sql.hive.thriftServer.singleSession true
上添加了spark-defaults.conf
启动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')
到目前为止,一切正常。
在另一个终端上,我初始化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服务器作业。
然后我使用蜂线连接到集群
./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
似乎还可以。
当我列出show tables;
时,我什么都看不到。
我想强调的两个有趣的事情是:
当我启动pyspark时,我收到这些警告
WARN ObjectStore:6666-在metastore中找不到版本信息。 hive.metastore.schema.verification未启用,因此记录架构版本1.2.0
WARN ObjectStore:568-无法获取数据库默认值,返回NoSuchObjectException
WARN ObjectStore:568-无法获取数据库global_temp,返回NoSuchObjectException
启动节俭服务器时,我得到了这些信息:
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)中做到这一点?
谢谢
答案 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"
希望这对某人有帮助。顺便说一下,我正处于初步研究阶段,请不要对我进行评判。