连续查询的最佳方法Cassandra(+ Spark?)?

时间:2015-01-03 10:39:02

标签: events cassandra apache-spark cassandra-2.0

我们目前正在使用Hazelcast(http://hazelcast.org/)作为分布式内存数据网格。这对我们来说一直很好,但仅仅在内存中已经耗尽了我们的用例路径,并且我们正在考虑将我们的应用程序移植到NoSQL持久存储中。在通常的比较和评估之后,我们接近挑选Cassandra,最后选择Spark进行分析。

尽管如此,我们的架构需求存在差距,我们仍然没有掌握如何在Cassandra中解决(有或没有Spark):Hazelcast允许我们创建一个连续查询,每当添加一行时/从条款结果集中删除/修改,Hazelcast回调相应的通知。我们使用它来通过AJAX流与新的/更改的行连续更新客户端。

这可能是我们正在制造的概念上的不匹配,所以 - 如何在Cassandra中最好地解决这个用例(有或没有Spark的帮助)? API中是否存在允许对键/子句更改进行连续查询的东西(尚未找到它)?是否有其他方法来获取密钥/子句更新流?某种事件?

我知道我们最终可以定期轮询Cassandra,但在我们的用例中,客户端可能会对大量的表子句通知感兴趣(想想"所有对Ship位置的更改)加利福尼亚州的海岸线"),以及从商店中迭代出来会破坏流媒体的可扩展性。

因此,一个神奇的问题:我们缺少什么? Cassandra是错误的工具吗?我们不知道apache领域内外的API或外部库的特定部分是否允许这样做?

非常感谢您的帮助!

雨果

4 个答案:

答案 0 :(得分:1)

我不是火花的专家,所以带上一粒盐,但也许你可以使用这样的方法:

  1. 使用spark streaming实时分析传入的数据流,并实时向客户推送位置更新。

  2. 使用Cassandra进行持久存储,缓存视图以及客户端可以从中提取数据的汇总数据。

  3. 因此,您将编写一个连接到传入数据流的火花流应用程序,可能是定期报告船舶位置的应用程序。当它收到一个船位置时,它会在Cassandra中查找该船的最后已知位置(先前存储在该船舶ID的集群时间序列中,按时间戳反向排序,以便最近的位置是第一行) 。如果船舶位置发生变化,火花应用程序将在Cassandra中插入新的时间序列行并将新位置推送到您的实时客户端。

    Spark还会为Cassandra写一些其他更新,用于客户可能想知道的汇总事项,例如目前旧金山湾有多少艘船的表格。当客户端单击托架时,将查询汇总表以提取该数据以供显示。任何需要在客户端上快速响应的东西都应该通过spark预先计算并存储在Cassandra中以便快速检索。

    当新客户启动时,他们会首先查询(拉出)Cassandra以获取所有船只的当前位置,然后将从火花应用程序中推送对该数据的实时更新。

答案 1 :(得分:1)

使用火花流。需要更新时,请执行两项操作:

  1. 执行saveToCassandra,它将更新cassandra数据以供将来查询。
  2. 使用您正在使用的任何内容将更改下推到客户端。如果您的AJAX推送可以放入流客户端代码中,您可以从Spark Streaming执行AJAX通知。否则,您可以向某个代理发送消息,该代理将转发给Ajax客户端。
  3. 您的代码可能如下所示:

    val notifications = ssc.whateverSourceYouHaveThatGivesADstream(...)
    notifications.foreachRDD(x => {
        x.foreachPartition(x => {
          cassandraConnector.withSessionDo(session => {
              x.foreach(y => {
                  //use session to update cassandra
                  // broadcast via AJAX or send to proxy to broadcast
              })
          })
        })
    })
    

    希望有所帮助。

答案 2 :(得分:1)

Spark Cassandra Connector可能有所帮助。它支持来自cassandra表的流式传输:

import com.datastax.spark.connector.streaming._

val ssc = new StreamingContext(sparkConf, Seconds(1))

val rdd = ssc.cassandraTable("streaming_test", "key_value").select("key", "value").where("fu = ?", 3)

答案 3 :(得分:0)

查看Spark Job Server

您可能想看看Spark Job Server

它可以让您在不同的工作之间共享火花上下文 - 从而兑换RDD - 。

并为近乎实时的火花提供了一个安静的API(基于刷新缓存的频率)查询。