我们目前正在使用Hazelcast(http://hazelcast.org/)作为分布式内存数据网格。这对我们来说一直很好,但仅仅在内存中已经耗尽了我们的用例路径,并且我们正在考虑将我们的应用程序移植到NoSQL持久存储中。在通常的比较和评估之后,我们接近挑选Cassandra,最后选择Spark进行分析。
尽管如此,我们的架构需求存在差距,我们仍然没有掌握如何在Cassandra中解决(有或没有Spark):Hazelcast允许我们创建一个连续查询,每当添加一行时/从条款结果集中删除/修改,Hazelcast回调相应的通知。我们使用它来通过AJAX流与新的/更改的行连续更新客户端。
这可能是我们正在制造的概念上的不匹配,所以 - 如何在Cassandra中最好地解决这个用例(有或没有Spark的帮助)? API中是否存在允许对键/子句更改进行连续查询的东西(尚未找到它)?是否有其他方法来获取密钥/子句更新流?某种事件?
我知道我们最终可以定期轮询Cassandra,但在我们的用例中,客户端可能会对大量的表子句通知感兴趣(想想"所有对Ship位置的更改)加利福尼亚州的海岸线"),以及从商店中迭代出来会破坏流媒体的可扩展性。
因此,一个神奇的问题:我们缺少什么? Cassandra是错误的工具吗?我们不知道apache领域内外的API或外部库的特定部分是否允许这样做?
非常感谢您的帮助!
雨果
答案 0 :(得分:1)
我不是火花的专家,所以带上一粒盐,但也许你可以使用这样的方法:
使用spark streaming实时分析传入的数据流,并实时向客户推送位置更新。
使用Cassandra进行持久存储,缓存视图以及客户端可以从中提取数据的汇总数据。
因此,您将编写一个连接到传入数据流的火花流应用程序,可能是定期报告船舶位置的应用程序。当它收到一个船位置时,它会在Cassandra中查找该船的最后已知位置(先前存储在该船舶ID的集群时间序列中,按时间戳反向排序,以便最近的位置是第一行) 。如果船舶位置发生变化,火花应用程序将在Cassandra中插入新的时间序列行并将新位置推送到您的实时客户端。
Spark还会为Cassandra写一些其他更新,用于客户可能想知道的汇总事项,例如目前旧金山湾有多少艘船的表格。当客户端单击托架时,将查询汇总表以提取该数据以供显示。任何需要在客户端上快速响应的东西都应该通过spark预先计算并存储在Cassandra中以便快速检索。
当新客户启动时,他们会首先查询(拉出)Cassandra以获取所有船只的当前位置,然后将从火花应用程序中推送对该数据的实时更新。
答案 1 :(得分:1)
使用火花流。需要更新时,请执行两项操作:
您的代码可能如下所示:
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
它可以让您在不同的工作之间共享火花上下文 - 从而兑换RDD - 。
并为近乎实时的火花提供了一个安静的API(基于刷新缓存的频率)查询。