使用包含时间范围的spark Dataframe加入时间序列数据

时间:2015-10-14 17:45:08

标签: apache-spark apache-spark-sql

我有两个数据帧,其中包含以下格式的事件详细信息(eventData)。

|id|parameter  |value|eventtime           |
+++++++++++++++++++++++++++++++++++++++++++
|1 |temperature|23   |2005-Apr-11 11:20:00|
|2 |temperature|21   |2005-Apr-12 14:34:00|

和另一个包含时间范围

Operationdata

|operationid|paramter   |start_time          |end_time            |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|1234       |Temperature|2005-Apr-11 10:20:00|2005-Apr-11 12:20:00|
|1235       |Temperature|2005-Apr-12 14:00:00|2005-Apr-11 16:30:00|

现在,我想加入这两个数据帧来获取以下输出。

|operationid|paramter   |value|eventtime           |
++++++++++++++++++++++++++++++++++++++++++++++++++++
|1234       |Temperature|23   |2005-Apr-11 11:20:00|
|1235       |Temperature|21   |2005-Apr-12 14:34:00|

我可以使用以下SQL查询

来实现这一点
joinSQL = sqlContext.sql("select OperationDF.operationid,eventDF.parameter,eventDF.value,eventDF.eventtime from eventDF,OperationDF where eventDF.eventtime >= jdbcDF.start_time AND eventDF.eventtime <= jdbcDF.end_time")

此查询以我想要的方式返回数据,但它在两个数据帧之间执行CartesianProduct。

OperationDF实际上是从RDBMS获取的,我必须在OperationDF上执行SQLContext.cacheTable以避免多个查询到数据库。

我是新手,我现在的问题是

  1. 有更好的方法来加入并避免使用CartesianProduct

  2. SQLContext.cacheTable是否将Dataframe内容保留在驱动程序内存中,还是将其分布在群集中?

  3. 如果它保存在驱动程序内存中,我们如何处理数据帧太大而无法保存在驱动程序内存中的情况。
  4. 感谢。

1 个答案:

答案 0 :(得分:0)

  

SQLContext.cacheTable是否将Dataframe内容保留在驱动程序内存中,还是将其分布在群集中?

每个DataFrameRDD都分布在工作节点上。除非你collect没有数据存储在驱动程序中。

  

有更好的方法来进行加入并避免使用CartesianProduct

除非内部引擎可以优化此类型或范围连接,并且据我所知,此时它不能,答案否。

如果您有一些可用于限制结果的附加信息(例如最大偶数跨度),则可以使用其他谓词来改进此信息。

如果没有,并且您可以负担全部排序,则可以使用低级API和/或某些窗口函数组合来处理此问题。