1

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

数据流是我们有一个原始日志,经过 Spark 存储处理到 Cassandra 中。数据是具有 20 多列和 4 个指标的时间序列。目前我进行了测试,因为集群键中有 20 多个维度,所以写入 Cassandra 非常慢。

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

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

我已经尝试过的:

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

所以,我真正想知道的是我的方向是对还是错?我可以改变什么来归档目标(查询像 MySQL 有很多 group by、SUM、ORDER BY)通过 API 返回到客户端。

4

1 回答 1

3

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

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

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

于 2016-05-16T13:06:22.747 回答