我正在开发一个存储传感器测量值的应用程序。有时,传感器会发送错误的测量值(例如,测量值超出范围)。我们不想单独保留每个测量错误,但我们希望保留有关这些错误的统计信息,例如传感器 ID、第一个错误的日期、最后一个错误的日期以及其他信息,如连续错误的数量,这里我就省略了...
这是“ErrorStatistic”类的简化版本:
package foo.bar.repository;
import org.joda.time.DateTime;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class ErrorStatistic {
@Nonnull
private final String sensorId;
@Nonnull
private final DateTime startDate;
@Nullable
private DateTime endDate;
public ErrorStatistic(@Nonnull String sensorId, @Nonnull DateTime startDate) {
this.sensorId = checkNotNull(sensorId);
this.startDate = checkNotNull(startDate);
this.endDate = null;
}
@Nonnull
public String getSensorId() {
return sensorId;
}
@Nonnull
public DateTime getStartDate() {
return startDate;
}
@Nullable
public DateTime getEndDate() {
return endDate;
}
public void setEndDate(@Nonnull DateTime endDate) {
this.endDate = checkNotNull(endDate);
}
}
我目前正在使用 Hector 保留这些 ErrorStatistic,如下所示:
private void persistErrorStatistic(ErrorStatistic errorStatistic) {
Mutator<String> mutator = HFactory.createMutator(keyspace, StringSerializer.get());
String rowKey = errorStatistic.getSensorId();
String columnName = errorStatistic.getStartDate().toString(YYYY_MM_DD_FORMATTER);
byte[] value = serialize(errorStatistic);
HColumn<String, byte[]> column = HFactory.createColumn(columnName, value, StringSerializer.get(), BytesArraySerializer.get());
mutator.addInsertion(rowKey, COLUMN_FAMILY, column);
mutator.execute();
}
private static final DateTimeFormatter YYYY_MM_DD_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
当我们收到第一个错误测量值时,我们创建一个 ErrorStatisticsensorId
并startDate
设置和一个 null endDate
。此 ErrorStatistic 保存在我们的内存模型中,并保留在 Cassandra 中。然后,我们更新内存中的 ErrorStatistic 以进行下一次错误测量,直到我们收到一个有效的测量,此时 ErrorStatistic 将被持久化并从我们的内存模型中删除。
因此,Cassandra 包含带有开放式区间(例如 [2012-08-01T00:00Z|null])和封闭区间(例如 [2012-08-01T00:00Z|2013-01-12T10:23Z])的 ErrorStatistics。
我希望能够按日期查询这些 ErrorStatistics。
例如,如果我有这 3 个错误统计信息:
sensorId = foo
startDate = 2012-08-01T00:00Z
endDate = 2012-09-03T02:10Z
sensorId = foo
startDate = 2012-10-04T03:12Z
endDate = 2013-02-01T12:28Z
sensorId = foo
startDate = 2013-03-05T23:22Z
endDate = null
(this means we have not received a valid measurement since 2013-03-05)
如果我用日期查询 Cassandra:
- 2012-08-04T10:00Z --> 它应该返回第一个 ErrorStatistic
- 2012-09-04T00:00Z --> 此时应该返回没有错误
- 2014-01-03T00:00Z --> 它应该返回最后一个 ErrorStatistic(因为它是开放式的)
我不确定我应该如何存储和“索引”这些 ErrorStatistic 对象,以有效地查询它们。我对 Cassandra 很陌生,我可能会遗漏一些明显的东西。
编辑:添加以下内容是为了响应 Joost 的建议,即我应该关注我感兴趣的查询类型。
我将有两种类型的查询:
- 如您所料,第一个是列出给定传感器和时间范围的所有 ErrorStatistics。这似乎相对容易。我将遇到的唯一问题是,当 ErrorStatistics在我感兴趣的时间范围之前开始时(例如,我查询 4 月份的所有错误,并且我希望我的查询返回 ErrorStatistics[2012-03-29:2012- 04-02] 太...)
- 第二个查询似乎更难。对于给定的传感器和日期,我想找到 ErrorStatistics,其间隔包含给定日期,或者
startDate
在给定日期之前,为空endDate
(这意味着我们仍然收到此传感器的错误)。我不知道如何有效地做到这一点。我可以为给定的传感器加载所有 ErrorStatistics,然后检查 Java 中的间隔......但如果可能的话,我想避免这种情况。我想我希望 Cassandra 从给定日期开始并向后看,直到它找到第一个 ErrorStatistics 与startDate
给定日期之前的 a (如果有),然后加载它并检查 Java 是否endDate
是null
或在给定日期之后。但我不知道这是否可能,以及它的效率如何。