我正在研究存儲傳感器測量的應用程序。有時,傳感器會發送錯誤的測量結果(例如測量值超出限制範圍)。我們不希望單獨持續每個測量錯誤,但我們希望保留關於這些錯誤的統計信息,例如傳感器ID,第一個錯誤的日期,最後一個錯誤的日期以及其他信息,例如連續錯誤的數量,我會在這裏省略......我應該如何在Cassandra中存儲日期間隔?
這裏是「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);
}
}
我使用赫克託如下目前堅持這些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");
當我們收到錯誤的第一個測量值時,我們使用sensorId
和startDate
集合創建一個ErrorStatistic,並創建一個空值endDate
。這個ErrorStatistic保存在我們的內存模型中,並堅持在Cassandra中。 然後我們更新內存中的ErrorStatistic以進行下一次測量,直到我們收到有效的測量結果,此時ErrorStatistic被持久化並從我們的內存模型中刪除。因此,Cassandra包含具有開放式區間的ErrorStatistics(例如[2012-08-01T00:00Z | null])和閉區間(例如[2012-08-01T00:00Z | 2013-01-12T10:23Z] )。
我希望能夠按日期查詢這些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)
如果我查詢卡桑德拉的日期:
- 2012-08-04T10:00Z - >它應該返回第一ErrorStatistic
- 2012-09-04T00:00Z - >它應返回沒有任何錯誤,此時
- 2014-01-03T00:00Z - >應該返回最後ErrorStatistic(因爲它是開放的-結束編輯)
我不知道如何存儲和「索引」這些ErrorStatistic對象,以有效地查詢它們。我對卡桑德拉來說很陌生,我可能會錯過一些明顯的東西。
編輯:。以下回應到Joost的建議,我應該專注於我感興趣的查詢類型加入
我將有兩種類型的查詢:
- 首先,如你所猜,列出所有傳感器和時間範圍內的所有ErrorStatistics。這似乎相對容易。我將遇到的唯一問題是ErrorStatistics在我感興趣的時間範圍之前開始(例如,我查詢四月份的所有錯誤,並且希望我的查詢返回ErrorStatistics [2012-03-29: 2012-04-02]太...)
- 第二個查詢似乎更難。對於給定的傳感器和日期,我希望找到ErrorStatistics,其間隔包含給定日期,或者在給定日期之前的日期爲
startDate
,空值爲endDate
(這意味着我們仍然收到此傳感器的錯誤)。我不知道如何有效地做到這一點。我可以加載給定傳感器的所有ErrorStatistics,然後檢查Java中的間隔......但是如果可能,我想避免這種情況。我想我想讓Cassandra在給定的日期開始並向後看,直到它找到第一個ErrorStatistics(在給定日期之前的startDate
)(如果有的話),然後加載它並檢查Java,如果它的endDate
是null
或在給定日期之後。但我不知道這是否可能,以及如何有效。
查詢我喜歡你的設計使用了「每次查詢表」的方法我的架構的想法。作爲一名新的Cassandra用戶,需要一段時間才能習慣它。我將更新我的問題以指定我將感興趣的兩種類型的查詢。 – 2013-05-02 08:46:57
我已經添加了一個可能有助於解決您的問題的示例。 – 2013-05-09 07:55:53