«Дорогой» – конечно в прежде всего в переносном значении, Elasticsearch сложно устанавливать, настраивать и обновлять. Это хорошо известно всем, кто работал ES про проде. SaaS версия Elastic позволяет сэкономить время, но это решение по понятным причинам не доступно для большинства компаний в России.

Я убежден, что «инфраструктура» – можно назвать это платформой или платформенными сервисами, должны быть максимально простыми и «дешевыми». Поэтому всегда нахожусь в поиске новых решений в этой сфере.

Quickwit – это поисковой движок нового поколения, альтернатива для Elasticsearch, Loki и Splunk. Одна из главных особенностей Quickwit, заключается в том, что индексы хранятся в объектном хранилище (s3, minio, другие s3-совместимые проекты). Такая архитектура позволяет сократить использование вычислительных ресурсов и хранилища в несколько раз.

Этот проект написан на Rust. Как и случае с Vector (Сборщик логов, альтернатива для Filebeat) это позволяет добиваться значительного прироста производительности и сократить расходы на on-prem и облачную инфраструктуру.

Не все возможности экосистемы Elastic реализованны в Quickwit. Нет красивого UI типа Kibana. Однако проект уже сейчас поддерживает интеграцию с Grafana, Jaeger, OpenTelemetry, Kafka.

Benchmark

Для того, чтобы, быстро, без заморочек проверить Quicktime, пишем программку на Go:

package main

import (
    "os"
    "log/slog"
)

func main() {
	for {
		logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
    		logger.Debug("Debug message")
    		logger.Info("Info message")
    		logger.Warn("Warning message")
    		logger.Error("Error message")
	}
}

Для структурированного логирования в json используется slog, которая теперь входит в стандартную библиотеку. Эта нехитрая программка генерирует 3,6 гигабайтов логов за 60 секунд – то есть примерно 5Т логов за 24 часа.

Программку упаковываем в Docker и вместе с сервисами Quickwit запускаем в docker-compose:

version: "3"

x-default-logging: &logging
 driver: "json-file"
 options:
   max-size: "5m"
   max-file: "2"
   tag: "{{.Name}}|{{.ImageName}}|{{.ID}}"

services:
  genlog1:
    image: genlogs/genlog
    command: ["./genlogs"]
    logging: *logging
  genlog2:
    image: genlogs/genlog
    command: ["./genlogs"]
    logging: *logging

  quickwit:
    image: quickwit/quickwit:${QW_VERSION:-0.8.1}
    volumes:
      - ./qwdata:/quickwit/qwdata
    ports:
      - 7280:7280
    environment:
      - NO_COLOR=true
      - QW_ENABLE_OPENTELEMETRY_OTLP_EXPORTER=true
      - OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:7281
    command: ["run"]
    logging: *logging

  otel-collector:
    user: "0"
    image: otel/opentelemetry-collector-contrib:${OTEL_VERSION:-0.87.0}
    volumes:
      - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
    command: ["--config=/etc/otel-collector-config.yaml"]
    logging: *logging

Физический сервер на котором проводилось тестирование:

Процессор: Intel Xeon E-2236 3.4 ГГц 
Память: 32 ГБ DDR4 ECC 
Диск: 
2 × 480 ГБ SSD SATA

Создаем запрос для подсчета количества записей со значениями INFO, DEBUG, WARN, и ERROR в минуту:

{
  "query": "*",
  "max_hits": 0,
  "aggs": {
    "count_per_minute": {
      "histogram": {
          "field": "timestamp_nanos",
          "interval": 60000000
      },
      "aggs": {
        "severity_text_count": {
          "terms": {
            "field": "severity_text"
          }
        }
      }
    }
  }
}

Выполняем запрос с помощью curl:
curl -XPOST -H "Content-Type: application/json" http://IP_ADDRESS:7280/api/v1/otel-logs-v0_7/search --data @agg.json

Получаем ответ меньше чем за секунду. Индекс otel-logs-v0_7 содержит 140 миллионов документов, которые занимают около 92Г на диске в не сжатом виде:

{
  "num_hits": 139495352,
  "hits": [],
  "elapsed_time_micros": 20343,
  "errors": [],
  "aggregations": {
    "count_per_minute": {
      "buckets": [
        {
          "doc_count": 27826,
          "key": 1717560000000.0,
          "key_as_string": "2024-06-05T04:00:00Z",
          "severity_text_count": {
            "buckets": [],
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0
          }
        },
        {
          "doc_count": 139467526,
          "key": 1717620000000.0,
          "key_as_string": "2024-06-05T20:40:00Z",
          "severity_text_count": {
            "buckets": [],
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0
          }
        }
      ]
    }
  }
}

Для того, чтобы использовать UI Quickwit:

http://IP_ADDRESS:7280

На официальном сайте проекта можно найти более репрезентативные сравнения. Однако даже для такого простого теста Elastic потребовал гораздо больше времени и вычислительных ресурсов.

Quickwit благодаря свой простоте можно рассматривать в качестве альтернативы Elastic при разработке SEIM и XDR решений. Такие проекты как FortiSEIM и Wazuh используют ES, хотя Quickwit может быть гораздо эффективнее хранения и поиска по большим объемам логов. Но это уже тема для другой статьи.

Комментарии (1)


  1. SlavikF
    06.06.2024 15:08
    +3

    В статье по большей части - водичка. Информации - минимум.

    Могли бы написать например, что дэшборды - это платная функция, которую обещают допилить только к концу года.

    Alerting обещают прикрутить "когда-нибудь".

    Frontend - это Grafana: https://github.com/quickwit-oss/quickwit-datasource?tab=readme-ov-file. И там они пишут, что pagination работает через пень-колоду, много данных не смотрите, выбирайте периоды поменьше...

    В общем, удачи ребятам.