从Spark中的DataFrame筛选和选择数据

时间:2018-07-24 09:31:14

标签: apache-spark

我正在研究Spark-JDBC程序 到目前为止,我想出了以下代码:

object PartitionRetrieval {
    var conf  = new SparkConf().setAppName("Spark-JDBC")
    val log   = LogManager.getLogger("Spark-JDBC Program")
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conFile       = "/home/hmusr/ReconTest/inputdir/testconnection.properties"
    val properties    = new Properties()
    properties.load(new FileInputStream(conFile))
    val connectionUrl = properties.getProperty("gpDevUrl")
    val devUserName   = properties.getProperty("devUserName")
    val devPassword   = properties.getProperty("devPassword")
    val driverClass   = properties.getProperty("gpDriverClass")
    val tableName     = "source.bank_accounts"
    try {
    Class.forName(driverClass).newInstance()
    } catch {
    case cnf: ClassNotFoundException =>
        log.error("Driver class: " + driverClass + " not found")
        System.exit(1)
    case e: Exception =>
        log.error("Exception: " + e.printStackTrace())
        System.exit(1)
    }
    def main(args: Array[String]): Unit = {
        val spark   = SparkSession.builder().config(conf).master("yarn").enableHiveSupport().getOrCreate()
        val gpTable = spark.read.format("jdbc").option("url", connectionUrl)
                                                        .option("dbtable",tableName)
                                                        .option("user",devUserName)
                                                        .option("password",devPassword).load()
        val rc = gpTable.filter(gpTable("source_system_name")==="ORACLE").count()
        println("gpTable Count: " + rc)
    }
}

在上面的代码中,语句:val gpTable = spark.read.format("jdbc").option("url", connectionUrl)table: bank_accounts的全部数据转储到DataFrame: gpTable中,然后DataFrame: rc得到过滤后的数据。我对表有这样的疑问:bank_accounts是一个很小的表,如果将它作为一个整体作为数据帧加载到内存中,则不会起作用。但是在我们的生产中,有些表具有数十亿条记录。在那种情况下,建议使用JDBC连接将数据加载到DataFrame中的方法是什么? 有人可以在这里让我知道Spark-Jdbc入口点的概念吗?

1 个答案:

答案 0 :(得分:0)

  •   

    该语句...将表:bank_accounts的全部数据转储到DataFrame:gpTable中,然后DataFrame:rc获取过滤后的数据。

    不。 additionalDays并不急。它仅定义数据绑定。

    此外,简单谓词(例如琐碎的等式)会将检查推送到源,并且在执行计划时仅应加载必需的列。

    在数据库日志中,您应该看到类似的查询

    DataFrameReader
  •   

    如果它作为一个数据帧整体加载到内存中。

    不。除非它发出指令(主要是 SELECT 1 FROM table WHERE source_system_name = 'ORACLE' ),否则Spark不会将数据加载到内存中,即使如此,它也将自身限制为适合可用存储内存的块。

    在标准过程中,它仅保留计算计划所需的数据。对于全局计划,内存占用空间不应该取决于数据量。

  •   

    在那种情况下,建议使用JDBC连接将数据加载到DataFrame中的方法是什么?

    请检查Partitioning in spark while reading from RDBMS via JDBCWhats meaning of partitionColumn, lowerBound, upperBound, numPartitions parameters?https://stackoverflow.com/a/45028675/8371915有关可伸缩性的问题。

    此外,您还可以阅读Does spark predicate pushdown work with JDBC?