我已经在cassandra DB中有记录,使用Java类我正在检索每一行,用TTL更新并将它们存储回Cassandra DB。之后,如果我运行select
查询其执行和显示记录。但是当TTL时间完成时,如果我运行select
查询,它必须显示零记录,但它没有运行select
查询显示Cassandra Failure during read query at consistency ONE
错误。对于其他表select
查询工作正常,但该表(我应用TTL的行)不起作用。
答案 0 :(得分:1)
您正在使用常见的反模式。
1)您正在使用批次将数据分别加载到两个单独的表中。我不知道您是否已经拥有一个集群,或者您已经在本地计算机上了,但这不是您将数据加载到C *集群的方式,并且您将非常强调 您的C *群集。只有在需要保持两个或多个表同步时才应该使用批处理,而不是一次加载一堆记录。我建议您阅读以下有关该主题的内容:
2)您正在使用同步写入将非常独立的记录插入到群集中。您应该使用异步写入来加速数据处理。
3)您正在使用表格中的 TTL 功能,这些功能本身并没有那么糟糕。但是,过期的 TTL 是一个墓碑,这意味着当您SELECT
查询时,C *必须读取所有这些墓碑。
4)您多次绑定准备好的语句:
BoundStatement bound = phonePrepared.bind(macAddress, ...
那应该是
BoundStatement bound = new BoundStatement(phonePrepared).bind(macAddress, ...
为了使用不同的绑定语句。这不是反模式,这是您的代码的问题。
现在,如果你多次运行你的程序,由于TTL功能,你的表有很多墓碑,这意味着C *正在努力阅读所有这些,以便找到你所写的内容"上一次"您成功运行,查询超时需要很长时间。
只是为了好玩,您可以尝试在SELECT
中增加超时(例如2分钟)并喝杯咖啡,同时C *会将您的记录恢复原状。
我不知道你想要达到的目标,但快速的TTL是你的敌人。如果你只想刷新你的记录,那么试着让TTL的时间足够高,这样就不会损害你的表现。或者,一个可能更好的解决方案是添加一个新列 EXPIRED ,"手动"仅在您需要删除记录时才写入。这取决于您的要求。