Cassandra 在查找时间序列数据时返回可变结果

Posted

技术标签:

【中文标题】Cassandra 在查找时间序列数据时返回可变结果【英文标题】:Cassandra returns variable results when looking for time series data 【发布时间】:2017-04-20 13:59:42 【问题描述】:

当我在 DataStax DevCenter 中进行此查询时,将返回 2 行。返回的行应该是 12 月 30 日的敌人。

SELECT * FROM abc.alerts_by_type_and_timestamp WHERE alert_type IN ('Permanent Fault', 'Temporary Fault') AND alert_timeStamp >= '2015-12-30T15:00+0000' AND alert_timeStamp <= '2015-12-31T15:00+0000'

但是像这样在 PreparedStatement 中运行

    SELECT * FROM abc.alerts_by_type_and_timestamp WHERE alert_type IN :alertTypes AND alert_timeStamp >= :minTimestamp AND alert_timeStamp <= :maxTimestamp

返回 4 行以下。

    17:52:48,587 INFO  [stdout] (default task-39) minTimestamp: 2015-12-30 15:00:00.0 - maxTimestamp : 2015-12-31 15:00:00.0
    17:52:50,904 INFO  [stdout] (default task-39) row : Row[Permanent Fault, Thu Dec 31 12:09:22 PST 2015, 2015, 365, .....]
    17:52:50,904 INFO  [stdout] (default task-39) row : Row[Permanent Fault, Thu Dec 31 12:08:14 PST 2015, 2015, 365, ....]
    17:52:50,905 INFO  [stdout] (default task-39) row : Row[Temporary Fault, Thu Dec 31 12:09:22 PST 2015, 2015, 365, ...]
    17:52:50,906 INFO  [stdout] (default task-39) row : Row[Temporary Fault, Thu Dec 31 12:08:14 PST 2015, 2015, 365, ...]

    17:52:50,906 INFO  [stdout] (default task-39) count is : 4

我相信这是由于时间转换。数据存储为 GMT,但 PreparedStatement 以某种方式在 PST 中传递它??

我该如何解决这个问题?

我也试过这个:

DateTime dateTime = new DateTime(minTimestamp.getTime(), DateTimeZone.UTC);
DateTime dateTime2 = new DateTime(maxTimestamp.getTime(), DateTimeZone.UTC);
BoundStatement stmtByAlertTypeAndTimestamp = pStmt.bind()
    .setTimestamp("minTimestamp", new Timestamp(dateTime.getMillis()))
    .setTimestamp("maxTimestamp", new Timestamp(dateTime2.getMillis()))
    .setList("Types", Types);

在日期时间打印出时间:

 minTimestamp: 2016-07-19 17:00:00.0  
 maxTimestamp: 2016-07-26 00:00:00.0

谢谢

【问题讨论】:

【参考方案1】:

您应该更改文件 $CASSANDRA_HOME/pylib/cqlshlib/formatter.py

将函数 strftime 更改为

def strftime(time_format, seconds):
    tzless_dt = datetime_from_timestamp(seconds)
    return tzless_dt.replace(tzinfo=pytz.utc).astimezone(pytz.timezone('Asia/Kolkata')).strftime(time_format)

并导入pytz库

我这样做是为了将 cqlsh 输出更改为 IST。您可以根据需要更改时区

说明:实际上 cassandra 始终将数据存储在 GMT 中,并且准备好的语句在本地时区(系统时区)中花费时间,因此您的结果在两个查询中都不同。

还有另一种解决方法,您可以在带有时区的准备好的语句中传递数据时间,然后根据我的说法它应该可以正常工作

希望对你有帮助

【讨论】:

如何在带时区的准备好的语句中传递时间?我尝试了几件事,但没有奏效。 您使用的是哪种语言的预处理语句?我认为该语言将支持这样做,或者您也可以将时间对象转换为字符串并附加 '+xxxx' 其中 xxxx 表示时区偏移 使用java。我试过这样的事情: DateTime dateTime = new DateTime(minTimestamp.getTime(), DateTimeZone.UTC); DateTime dateTime2 = new DateTime(maxTimestamp.getTime(), DateTimeZone.UTC); BoundStatement stmtByAlertTypeAndTimestamp = pStmt.bind() .setTimestamp("minTimestamp", new Timestamp(dateTime.getMillis())) .setTimestamp("maxTimestamp", new Timestamp(dateTime2.getMillis())) .setList("Types", Types ); 能否请您评论 System.out.println(datetime.toString()) 的输出,这将清除很多事情 minTimestamp 和 maxTimestamp 是您需要的时间戳吗?请不要在这两种情况下更改输入值,这会令人困惑,我无法弄清楚您是否获得了所需的时间戳

以上是关于Cassandra 在查找时间序列数据时返回可变结果的主要内容,如果未能解决你的问题,请参考以下文章

Cassandra 并不总是在单个数据中心返回相同查询的预期数据,设置 5 个副本

使用 cassandra 对 hadoop-2.2.0 运行 piglatin 脚本时出错

通过 Spark SQL 查询 Cassandra UDT

Cassandra如何保证数据最终一致性

如何在启用TDE的情况下查询Cassandra中的敏感数据?

Cassandra 与 docker swarm,“无法查找主机 cassandra-seed”