如何从已完成的Spark Job中缓存仍然可以访问其他作业?

时间:2016-05-16 10:50:55

标签: caching apache-spark cassandra spark-jobserver

我的项目是为用户实现交互查询以发现该数据。就像我们有一个用户可以选择的列列表然后用户添加到列表并按下查看数据。 Cassandra中的当前数据存储,我们使用Spark SQL从中进行查询。

数据流是我们在Spark商店处理到Cassandra之后有一个原始日志。数据是时间序列,包含20多列和4个指标。目前我测试了因为群集密钥超过20个维度所以写入Cassandra非常慢。

这里的想法是将Cassandra中的所有数据加载到Spark中并将其缓存在内存中。为客户端提供API并在Spark Cache上运行查询。 但我不知道如何保持缓存的数据持续存在。我尝试使用spark-job-server,他们有功能调用share object。但不确定它是否有效。

我们可以提供一个具有40多个CPU核心和100 GB RAM的集群。我们估计要查询的数据大约是100 GB。

我已经尝试过:

  • 尝试存储在Alluxio并从中加载到Spark但是加载的时间很慢,因为当它加载4GB数据时需要先做2件事,从Alluxio读取需要1分钟以上然后存入磁盘(Spark) Shuffle)花费超过2或3分钟。这意味着我们的目标是在1分钟内。我们测试了8个CPU内核中的1个作业。
  • 尝试存储在MemSQL中但有点贵。 1天它需要2GB RAM。我们在扩展时不确定速度是否保持良好。
  • 尝试使用Cassandra,但Cassandra不支持GROUP BY。

所以,我真正想知道的是我的方向是对还是不对?我可以改变归档目标(像MySQL这样的查询,SUM,ORDER BY)通过API返回客户端。

1 个答案:

答案 0 :(得分:3)

如果在DataFrame上明确调用cachepersist,它将保存在内存(和/或磁盘中,具体取决于您选择的存储级别),直到关闭上下文。这也适用于sqlContext.cacheTable

因此,当您使用Spark JobServer时,您可以创建一个长时间运行的上下文(使用REST或在服务器启动时)并将其用于同一数据集上的多个查询,因为它将被缓存直到上下文或JobServer服务关闭。但是,使用这种方法,您应确保为此上下文提供了大量可用内存,否则Spark会将大部分数据保存在磁盘上,这会对性能产生一些影响。

此外,JobServer的命名对象功能对于在作业之间共享特定对象很有用,但如果将数据注册为临时表(df.registerTempTable("name"))并对其进行缓存(sqlContext.cacheTable("name"),则不需要这样做。 ),因为您将能够从多个作业(使用sqlContext.sqlsqlContext.table)查询您的表,只要这些作业在相同的上下文中执行。