【问题标题】:Running a SELECT query with ALLOW FILTERING on Amazon Keyspaces returns no data在 Amazon Keyspaces 上运行带有 ALLOW FILTERING 的 SELECT 查询不会返回任何数据
【发布时间】:2022-12-15 04:44:03
【问题描述】:
我们已经使用 aws keyspace 服务和 cassandra-driver for node 实现了 cassandra。客户端工作正常,我们能够对数据执行创建和更新操作。但是,使用客户端运行简单的 cql 查询不会返回任何数据(空行)。
当我在 aws 仪表板上的 cql 编辑器上运行完全相同的查询时,它工作正常并且确实返回了所需的数据。
询问:
SELECT * FROM <TABLE_NAME> WHERE product_id = '<PRODUCT_ID>' ALLOW FILTERING
在 aws 仪表板上的 cql 编辑器上运行相同的查询工作正常。
【问题讨论】:
标签:
node.js
amazon-web-services
cassandra
amazon-keyspaces
datastax-node-driver
【解决方案1】:
我注意到您在查询中使用了 ALLOW FILTERING 子句,这表明 product_id 不是表的分区键。
如果您在没有分区键的情况下查询表,则请求的协调器必须联系集群中的所有节点以获取请求的数据。查询很可能在等待所有节点的响应时超时,因此没有数据返回。
我怀疑它在 cqlsh 中有效,因为它的超时时间比 Node.js 驱动程序的默认超时时间长。
您将需要查看应用程序日志并从 Node.js 驱动程序中查找警告或错误以获取线索。干杯!
? 请将鼠标悬停在上面的 cassandra 标签上并单击手表吊牌. ?谢谢!
【讨论】:
-
您好,感谢您的答复。经过少量挖掘后,我发现 amazon keyspace SELECT 语句结果被分成大小为 1 MB(或更小)的数据“页面”。这可能是我得到空行的原因,因为当我尝试不同的选择查询时,它们正在工作,但行数不同且不恒定。但是,我通过使用 cassandra 驱动程序的流方法解决了这个问题,然后我能够获取相应的数据。 Doc Link
【解决方案2】:
是的,您在查询语句中使用了部分分区键。 Keyspaces 将过滤存储层上的行。扫描给定数量后,它将返回给客户端。如果过滤条件没有找到结果,它将导致一个空白页面。没有行的页面。这是避免无限请求时间的安全卫士。您可以继续迭代页面,直到到达迭代器的末尾。
上面的方法在抓取前 X 行时很有用,但对于全表扫描我建议使用 AWS Glue。
在下面的示例中,我们使用 Spark 和 Glue 执行相同的产品查找。在引擎盖下,Spark 将对结果进行解析和分页。 Glue 将配置内存和计算资源。在这项工作中,我们将结果导出到 s3。一般的全表扫描可以是 TB 大小。该架构适用于小型或大型表,因为它使用无服务器资源。
Job.init(args("JOB_NAME"), glueContext, args.asJava)
val tableName = args("TABLE_NAME")
val keyspaceName = args("KEYSPACE_NAME")
val backupS3 = args("S3_URI")
val backupFormat = args("FORMAT")
val productId = args("PRODUCT_ID")
val tableDf = sparkSession.read
.format("org.apache.spark.sql.cassandra")
.options(Map( "table" -> tableName, "keyspace" -> keyspaceName))
.load()
.where(col("product_id") === productId)
tableDf.write.format(backupFormat).mode(SaveMode.ErrorIfExists).save(backupS3)
Job.commit()
您可以在此处找到完整的导出到 s3 示例和胶水创建脚本。 here