Как мне найти последний элемент для данных временных рядов?

#database #elasticsearch #time-series #data-analysis

#База данных #elasticsearch #временные ряды #анализ данных

Вопрос:

Например, есть данные временных рядов, такие как использование корневого раздела. Структура данных выглядит следующим образом:

 name: root_disk_utilizatoin
ip: 1.1.1.1
timestamp: 1234567890
value: 0.5
  

У нас есть миллионы серверов, которые сообщают эти данные каждые несколько минут. Я ожидаю найти последние данные для каждого сервера.

Первая идея — сохранить эти данные временных рядов в каком-либо хранилище, таком как elasticsearc или tsdb (influxdb / opentsdb). Затем запросите хранилище, чтобы получить результат. Но я беспокоюсь о производительности. Независимо от того, какое хранилище я выбрал, они должны выполнить следующие два шага, чтобы архивировать результат.

  1. группируйте данные по IP
  2. сортировка данных по временной метке и возврат последней

Я думаю, это будет очень дорогостоящий процесс (займет много времени).

Так что, я думаю, это может быть не очень хорошей идеей.

  • Есть ли у вас похожие требования и как вы их решаете?
  • Будет ли это проблемой для базы данных временных рядов, такой как influxdb?

Комментарии:

1. Сначала необходимо указать скорость ввода данных? затем, учитывая скорость ввода и тип запроса, решите, какая база данных может выполнять ваши задачи. возможно, вам подойдет apache cassandra.

Ответ №1:

Вы можете использовать комбинацию агрегации терминов с максимальной агрегацией

Добавление рабочего примера с индексными данными, поисковым запросом и результатом поиска

Индексировать данные:

 {
  "name": "root_disk_utilizatoin",
  "ip": "1.1.1.2",
  "timestamp": 1234567891,
  "value": 0.5
}
{
  "name": "root_disk_utilizatoin",
  "ip": "1.1.1.1",
  "timestamp": 1234567890,
  "value": 0.5
}
  

Поисковый запрос:

     {
  "size":0,
  "aggs": {
    "unique_id": {
      "terms": {
        "field": "ip.keyword",
        "order": {
          "latestOrder": "desc"
        },
        "size":1
      },
      "aggs": {
        "latestOrder": {
          "max": {
            "field": "timestamp"
          }
        }
      }
    }
  }
}
  

Результат поиска:

 "aggregations": {
    "unique_id": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 1,
      "buckets": [
        {
          "key": "1.1.1.2",
          "doc_count": 1,
          "latestOrder": {
            "value": 1.234567891E9
          }
        }
      ]
    }
  

Комментарии:

1. OP сказал, что «миллионы серверов сообщают каждые несколько минут»… Агрегирование терминов с миллионами сегментов требует больших затрат

2. Да @Val это будет дорогостоящее решение, но OP также хочет group data by ip , и, насколько я знаю, это может быть достигнуто только путем агрегирования терминов. Есть ли какой-либо другой способ добиться этого?

3. В этом случае я бы, вероятно, использовал composite агрегацию (с terms исходным кодом), чтобы таким образом OP мог эффективно разбивать результаты на страницы…

4. он не решил, какую базу данных он хочет использовать. он понятия не имеет, что mysql выходит из игры, когда говорит о больших данных. :))

5. @Kramer Li у вас была возможность просмотреть мой ответ, с нетерпением жду обратной связи от вас 🙂