【问题标题】:Does Apache Spark load entire data from target database?Apache Spark 是否从目标数据库加载整个数据?
【发布时间】:2017-07-05 04:14:57
【问题描述】:

我想使用 Apache Spark 并通过 JDBC 连接到 Vertica。

在 Vertica 数据库中,我有 1 亿条记录,并且 spark 代码在另一台服务器上运行。

当我在 Spark 中运行查询并监控网络使用情况时,两台服务器之间的流量非常高。

Spark 似乎从目标服务器加载了所有数据。

这是我的代码:

test_df = spark.read.format("jdbc")
    .option("url" , url).option("dbtable", "my_table")
    .option("user", "user").option("password" , "pass").load()

test_df.createOrReplaceTempView('tb')

data = spark.sql("select * from tb")

data.show()

当我运行它时,经过 2 分钟和非常高的网络使用率,结果返回。

Spark 会从目标数据库中加载全部数据吗?

【问题讨论】:

  • 您可以使用sql("select count(*) from spark_table").explain(true)查看查询计划,这可能会给您更多的见解。

标签: apache-spark jdbc vertica pyspark-sql


【解决方案1】:

JDBC 基于DBs 允许下推查询,以便您仅从磁盘读取相关项目:例如:df.filter("user_id == 2").count 将首先选择仅​​过滤的记录,然后将计数发送到 spark。所以使用JDBC: 1. 计划过滤器,2. 根据您的查询模式对数据库进行分区,并进一步优化表单 spark 端,例如:

val prop = new java.util.Properties
prop.setProperty("driver","org.postgresql.Driver")
prop.setProperty("partitionColumn", "user_id")
prop.setProperty("lowerBound", "1")
prop.setProperty("upperBound", "272")
prop.setProperty("numPartitions", "30")

但是,大多数relational DB 是由树状结构中的特定字段划分的,这对于复杂的大数据查询并不理想:我强烈建议将表从JDBC 复制到no-sql,例如cassandramongoelastic serach 或文件系统,例如 alluxiohdfs,以启用可扩展的 - 并行 - 复杂 - 快速查询。最后,您可以将JDBC 替换为aws redshift,这对于后端/前端来说应该不难实现,但是从您的火花方面来看,处理依赖冲突是一件痛苦的事情 - 但它可以让您进行复杂的查询速度更快,因为它对列进行了分区,因此您可以使用多个工作人员在列本身上下推聚合 .

【讨论】:

  • 对于 spark 中的这个命令:result = df.filter(df.test_col == 1).count(),Spark 在数据库上运行这个查询:SELECT 1 FROM Event WHERE ("test_col" IS NOT NULL) AND ("test_col" = 1) 。 “选择 1”会导致非常高的网络流量以获得大的结果。我怎样才能以不同的方式获得计数?
【解决方案2】:

在您的 spark 作业使用与 spark 作业使用和运行的相同凭据完成登录 Vertica 数据库后:

SELECT * FROM v_monitor.query_requests ORDER BY start_timetamp DESC LIMIT 10000;

这将向您显示 spark 作业发送到数据库的查询,让您查看它是否将 count(*) 推送到数据库,或者它是否确实尝试通过网络检索整个表。

【讨论】:

    猜你喜欢
    • 2011-08-05
    • 1970-01-01
    • 2015-10-13
    • 2020-07-14
    • 1970-01-01
    • 2019-01-12
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多