Я работаю над приложением, которое хранит измерения датчиков. Иногда датчики отправляют ошибочные измерения (например, измеренное значение выходит за пределы). Мы не хотим сохранять каждую ошибку измерения отдельно, но мы хотим сохранить статистику об этих ошибках, такую как идентификатор датчика, дату первой ошибки, дату последней ошибки и другую информацию, такую как количество последовательных ошибок , который я здесь опустим ...Как хранить интервал дат в Кассандре?
Вот упрощенная версия класса "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");
Когда мы получим первое измерение по ошибке, мы создаем ErrorStatistic с набором sensorId
и startDate
, а также нулем endDate
. Этот ErrorStatistic хранится в нашей модели в памяти и сохраняется в Cassandra. Затем мы обновляем ErrorStatistic в памяти для следующих измерений по ошибке, пока не получим действительное измерение, после чего ErrorStatistic сохраняется и удаляется из нашей модели в памяти.
Таким образом, Cassandra содержит статистику ошибок с открытыми интервалами (например, [2012-08-01T00: 00Z | null]) и закрытые интервалы (например, [2012-08-01T00: 00Z | 2013-01-12T10: 23Z]).
Я хочу иметь возможность запрашивать данные статистики ошибок по дате.
Например, если у меня есть эти статистические данные 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 (поскольку он открыт -конец ed)
Я не уверен, как я должен хранить и «индексировать» объекты ErrorStatistic, чтобы эффективно их запрашивать. Я совершенно новый для Кассандры, и я мог бы пропустить что-то очевидное.
Edit:. Следующий был добавлен в ответ на предложение Joost, что я должен сосредоточиться на тип запросов Я заинтересован в
у меня будет два типа запроса:
- Первое, как вы догадались, - это перечислить всю ErrorStatistics для данного датчика и временного диапазона. Это кажется относительно легким. Единственная проблема, с которой я столкнулся, заключается в том, когда ErrorStatistics начинает до интересующего меня времени (например, я запрашиваю все ошибки за апрельские месяцы, и я хочу, чтобы мой запрос возвращал ErrorStatistics [2012-03-29: 2012-04-02] тоже ...)
- Второй запрос кажется сложнее.Я хочу найти для данного датчика и даты ошибкуStatistics, чей интервал содержит указанную дату или чей
startDate
предшествует данной дате, с нулемendDate
(это означает, что мы все еще получаем ошибки для этого датчика). Я не знаю, как это сделать эффективно. Я мог бы просто загрузить всю ErrorStatistics для данного датчика, а затем проверить интервалы в Java ... Но я бы хотел избежать этого, если это возможно. Наверное, я хочу, чтобы Cassandra начиналась с определенной даты и смотрела назад, пока не найдет первую ErrorStatistics сstartDate
, которая предшествует данной дате (если она есть), затем загрузите ее и проверьте на Java, если ееendDate
-null
или после указанной даты , Но я понятия не имею, возможно ли это, и насколько это эффективно.
Мне нравится ваша идея создать свою схему с помощью «Таблицы каждого запроса» подхода. Как новый пользователь Cassandra, потребуется некоторое время, чтобы привыкнуть к нему. Я собираюсь обновить свой вопрос, чтобы указать два типа запросов, которые меня будут интересовать. –
Я добавил пример, который может помочь в решении вашей проблемы. –