Spark Cassandra连接器 - 分区键的范围查询

时间:2014-11-19 23:20:15

标签: cassandra apache-spark

我正在评估spark-cassandra-connector,并且我正在努力尝试让分区键的范围查询起作用。

根据连接器的文档,似乎可以使用相等或IN运算符对分区键进行服务器端过滤,但不幸的是,我的分区键是时间戳,所以我无法使用它

所以我尝试使用Spark SQL并使用以下查询(' timestamp'是分区键):

select * from datastore.data where timestamp >= '2013-01-01T00:00:00.000Z' and timestamp < '2013-12-31T00:00:00.000Z'

虽然作业产生了200个任务,但查询没有返回任何数据。

此外,我可以确保自从在cqlsh上运行查询后返回数据(使用&#39; token&#39;函数进行适当的转换)是否返回数据。

我在独立模式下使用spark 1.1.0。 Cassandra是2.1.2,连接器版本是&#39; b1.1&#39;科。 Cassandra司机是DataStax&#39; master&#39;科。 Cassandra集群覆盖在具有3台服务器的火花集群上,复制因子为1。

Here is the job's full log

有人知道吗?

更新:尝试根据分区键进行服务器端过滤时(使用CassandraRDD.where方法),我遇到以下异常:

Exception in thread "main" java.lang.UnsupportedOperationException: Range predicates on partition key columns (here: timestamp) are not supported in where. Use filter instead.

但不幸的是,我不知道&#34;过滤&#34;是...

2 个答案:

答案 0 :(得分:8)

我认为CassandraRDD错误告诉您在Cassandra中不允许您尝试执行的查询,并且必须在CassandraRDD中加载所有表,然后对此CassandraRDD执行spark过滤操作。

所以你的代码(在scala中)应该是这样的:

val cassRDD= sc.cassandraTable("keyspace name", "table name").filter(row=> row.getDate("timestamp")>=DateFormat('2013-01-01T00:00:00.000Z')&&row.getDate("timestamp") < DateFormat('2013-12-31T00:00:00.000Z'))

如果您对制作此类查询感兴趣,可能需要查看其他Cassandra连接器,例如Stratio开发的连接器

答案 1 :(得分:8)

您可以通过多种方式获得所需的解决方案。

最强大的一个是使用Straion与Cassandra集成的Lucene索引,它允许您通过服务器端的任何索引字段进行搜索。您的写作时间会增加,但另一方面,您可以查询任何时间范围。您可以在Cassandra here中找到有关Lucene索引的更多信息。这个扩展版本的Cassandra完全集成到deep-spark project中,因此您可以通过它在Cassandra中获取Lucene索引的所有优点。我建议您在执行检索中小型结果集的受限查询时使用Lucene索引,如果要检索大部分数据集,则应使用下面的第三个选项。

另一种方法(取决于应用程序的工作方式)可能是截断您的时间戳字段,以便您可以使用IN运算符查找它。问题是,据我所知,你不能使用spark-cassandra-connector,你应该使用没有与Spark集成的直接Cassandra驱动程序,或者你可以看一下深火花项目即将发布的新功能即将发布。您的查询看起来像这样:

select * from datastore.data where timestamp IN ('2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', ... , '2013-12-31')

,但是,正如我之前所说,我不知道它是否符合您的需求,因为您可能无法截断您的数据并按日期/时间对其进行分组。

您拥有的最后一个选项,但效率较低,是将完整数据集带到您的火花群集并在RDD上应用过滤器。

免责声明:我为Stratio工作:-)如果您需要任何帮助,请随时与我们联系。

我希望它有所帮助!