我在Hadoop中有大约100 GB的时间序列数据。我想使用Spark从1000个不同的时间范围中获取所有数据。
我通过创建一个包含大约1000 'OR BETWEEN X AND Y OR BETWEEN Q AND R'
个语句的超长SQL语句,尝试使用Apache Hive。
我也尝试过使用Spark。在这种技术中,我创建了一个具有相关时间范围的数据框,并将其加载到spark中:
spark_session.CreateDataFrame()
和
df.registerTempTable()
有了这个,我正在使用新创建的时间戳数据帧和更大的时间戳数据集进行连接。
此查询花了很长时间,我想知道是否有更有效的方法来执行此操作。
答案 0 :(得分:1)
特别是如果没有以任何特殊方式对数据进行分区或排序,您或Spark无论如何都需要扫描所有数据。
我会根据时间范围集定义一个谓词:
import scala.collection.immutable.Range
val ranges: List[Range] = ??? // load your ranges here
def matches(timestamp: Int): Boolean = {
// This is not efficient, a better data structure than a List
// should be used, but this is just an example
ranges.contains(_.contains(timestamp))
}
val data: RDD[(Int, T)] = ??? // load the data in an RDD
val filtered = data.filter(x => matches(x.first))
您可以对DataFrame / DataSet和UDF执行相同的操作。
如果驱动程序中提供了范围集,则此方法很有效。如果它来自一个表,比如100G数据,首先将它收集回驱动程序,如果不是太大。
答案 1 :(得分:0)
您的Spark作业通过100GB数据集来选择相关数据。 我不认为使用SQL或数据框api之间存在很大差异,因为无论如何都会发生完整扫描。
我会考虑重新构建您的数据,因此针对特定查询进行了优化。
在您的情况下,按时间划分可以带来相当大的改进(例如,带有分区的HIVE表)。 如果使用相同的字段执行搜索(已用于分区) - Spark作业将仅查看相关分区。