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 脚本时出错