Envío de registros JSON de Nginx con Vector a Clickhouse y Elasticsearch

Envío de registros JSON de Nginx con Vector a Clickhouse y Elasticsearch

Vector, diseñado para recopilar, transformar y enviar datos de logs, métricas y eventos.

→ Github

Escrita en Rust, se distingue por su alto rendimiento y bajo consumo de memoria en comparación con sus similares. Además, se presta especial atención a las funcionalidades relacionadas con la corrección, en particular, las capacidades de almacenar eventos no enviados en el búfer del disco y la rotación de archivos.

Arquitectónicamente, Vector es un enrutador de eventos, que recibe mensajes de uno o más fuentes, aplicando opcionalmente transformaciones sobre esos mensajes transformaciones, y enviándolos a uno o más destinos.

Vector es un reemplazo de filebeat y logstash, puede desempeñar ambos roles (recibir y enviar logs), más detalles en su el sitio web.

Si en Logstash la cadena se construye como input → filter → output, en Vector es fuentes → transforms → sumideros

Puedes ver ejemplos en la documentación.

Esta guía es una versión revisada de la Vyacheslav Rakhinsky. En la guía original hay un manejo de geoip. Durante mis pruebas con geoip desde la red interna, Vector arrojó un error.

Aug 05 06:25:31.889 DEBUG transform{name=nginx_parse_rename_fields type=rename_fields}: vector::transforms::rename_fields: El campo no existía field=«geoip.country_name» rate_limit_secs=30

Si alguien necesita manejar geoip, consulte la guía original de Vyacheslav Rakhinsky.

Configuraremos la cadena Nginx (Access logs) → Vector (Client | Filebeat) → Vector (Server | Logstash) → por separado en Clickhouse y por separado en Elasticsearch. Instalaremos 4 servidores. Aunque se puede hacer con 3 servidores.

Envío de registros JSON de Nginx con Vector a Clickhouse y Elasticsearch

El esquema es aproximadamente así.

Desactivamos Selinux en todos sus servidores

sed -i 's\/^SELINUX=.*\/SELINUX=disabled\/g' \/etc\/selinux\/config
reboot

En todos los servidores instalamos un emulador de servidor HTTP + utilidades

Usaremos como emulador de servidor HTTP nodejs-stub-server desde Maxim Ignatenko

Nodejs-stub-server no tiene rpm. Aquí creamos su rpm. El rpm se construirá con la ayuda de Fedora Copr

Añadimos el repositorio antonpatsev\/nodejs-stub-server

yum -y install yum-plugin-copr epel-release
yes | yum copr enable antonpatsev\/nodejs-stub-server

Instalamos nodejs-stub-server, Apache benchmark y el multiplexor de terminal screen en todos los servidores

yum -y install stub_http_server screen mc httpd-tools screen

Corregí en el archivo \/var\/lib\/stub_http_server\/stub_http_server.js el tiempo de respuesta del stub_http_server para que haya más logs.

var max_sleep = 10;

Iniciaremos stub_http_server.

systemctl start stub_http_server
systemctl enable stub_http_server

Instalación de Clickhouse en el tercer servidor

ClickHouse utiliza un conjunto de instrucciones SSE 4.2, por lo que, a menos que se indique lo contrario, su soporte en el procesador utilizado es un requisito adicional para el sistema. Este es el comando para verificar si el procesador actual soporta SSE 4.2:

grep -q sse4_2 \/proc\/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"

Primero, necesitamos conectar el repositorio oficial:

sudo yum install -y yum-utils
sudo rpm --import https:\/\/repo.clickhouse.tech\/CLICKHOUSE-KEY.GPG
sudo yum-config-manager --add-repo https:\/\/repo.clickhouse.tech\/rpm\/stable\/x86_64

Para instalar los paquetes, es necesario ejecutar los siguientes comandos:

sudo yum install -y clickhouse-server clickhouse-client

Permitimos que clickhouse-server escuche en la tarjeta de red en el archivo \/etc\/clickhouse-server\/config.xml

0.0.0.0

Cambiamos el nivel de logging de trace a debug

debug

Las configuraciones de compresión son las estándar:

min_compress_block_size  65536
max_compress_block_size  1048576

Para activar la compresión Zstd, se recomienda no tocar la configuración, sino aplicar DDL.

Envío de registros JSON de Nginx con Vector a Clickhouse y Elasticsearch

No encontré cómo aplicar la compresión zstd a través de DDL en Google. Por lo tanto, lo dejé como está.

Colegas, quienes usan la compresión zstd en Clickhouse, por favor compartan las instrucciones.

Para iniciar el servidor como un demonio, ejecute:

service clickhouse-server start

Ahora pasemos a la configuración de Clickhouse.

Accedemos a Clickhouse.

clickhouse-client -h 172.26.10.109 -m

172.26.10.109 — IP del servidor donde está instalado Clickhouse.

Creamos la base de datos vector.

CREATE DATABASE vector;

Verificamos que la base de datos exista.

show databases;

Creamos la tabla vector.logs.

/* Это таблица где хранятся логи как есть */

CREATE TABLE vector.logs
(
    `node_name` String,
    `timestamp` DateTime,
    `server_name` String,
    `user_id` String,
    `request_full` String,
    `request_user_agent` String,
    `request_http_host` String,
    `request_uri` String,
    `request_scheme` String,
    `request_method` String,
    `request_length` UInt64,
    `request_time` Float32,
    `request_referrer` String,
    `response_status` UInt16,
    `response_body_bytes_sent` UInt64,
    `response_content_type` String,
    `remote_addr` IPv4,
    `remote_port` UInt32,
    `remote_user` String,
    `upstream_addr` IPv4,
    `upstream_port` UInt32,
    `upstream_bytes_received` UInt64,
    `upstream_bytes_sent` UInt64,
    `upstream_cache_status` String,
    `upstream_connect_time` Float32,
    `upstream_header_time` Float32,
    `upstream_response_length` UInt64,
    `upstream_response_time` Float32,
    `upstream_status` UInt16,
    `upstream_content_type` String,
    INDEX idx_http_host request_http_host TYPE set(0) GRANULARITY 1
)
ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY timestamp
TTL timestamp + toIntervalMonth(1)
SETTINGS index_granularity = 8192;

Verificamos que se hayan creado las tablas. Ejecutamos clickhouse-client y hacemos la consulta.

Pasamos a la base de datos vector.

use vector;

Ok.

0 rows in set. Elapsed: 0.001 sec.

Observamos las tablas.

show tables;

┌─name────────────────┐
│ logs                │
└─────────────────────┘

Instalación de elasticsearch en el cuarto servidor para enviar los mismos datos a Elasticsearch para comparación con Clickhouse.

Agregamos la clave RPM pública.

rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

Creamos 2 repositorios:

/etc/yum.repos.d/elasticsearch.repo

[elasticsearch]
name=Repositorio de Elasticsearch para paquetes 7.x
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md

/etc/yum.repos.d/kibana.repo

[kibana-7.x]
name=Repositorio de Kibana para paquetes 7.x
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

Instalaremos elasticsearch y kibana.

yum install -y kibana elasticsearch

Dado que será en una sola instancia, necesitamos agregar en el archivo /etc/elasticsearch/elasticsearch.yml:

discovery.type: single-node

Para que vector pueda enviar datos a Elasticsearch desde otro servidor, cambiamos network.host.

network.host: 0.0.0.0

Para conectarnos a kibana, cambiamos el parámetro server.host en el archivo /etc/kibana/kibana.yml.

server.host: "0.0.0.0"

Iniciamos y habilitamos elasticsearch para que se inicie automáticamente.

systemctl enable elasticsearch
systemctl start elasticsearch

y kibana.

systemctl enable kibana
systemctl start kibana

Configuración de Elasticsearch para modo single-node, 1 shard, 0 replicas. Seguramente ustedes tendrán un clúster con muchos servidores y no necesitan hacer esto.

Para futuros índices, actualizamos la plantilla por defecto:

curl -X PUT http://localhost:9200/_template/default -H 'Content-Type: application/json' -d '{"index_patterns": ["*"],"order": -1,"settings": {"number_of_shards": "1","number_of_replicas": "0"}}' 

Instalación Vector como reemplazo de Logstash en el segundo servidor.

yum install -y https://packages.timber.io/vector/0.9.X/vector-x86_64.rpm mc httpd-tools screen

Configuramos Vector como reemplazo de Logstash. Editamos el archivo /etc/vector/vector.toml.

# /etc/vector/vector.toml

data_dir = "/var/lib/vector"

[sources.nginx_input_vector]
  # General
  type                          = "vector"
  address                       = "0.0.0.0:9876"
  shutdown_timeout_secs         = 30

[transforms.nginx_parse_json]
  inputs                        = [ "nginx_input_vector" ]
  type                          = "json_parser"

[transforms.nginx_parse_add_defaults]
  inputs                        = [ "nginx_parse_json" ]
  type                          = "lua"
  version                       = "2"

  hooks.process = """
  function (event, emit)

    function split_first(s, delimiter)
      result = {};
      for match in (s..delimiter):gmatch("(.-)"..delimiter) do
          table.insert(result, match);
      end
      return result[1];
    end

    function split_last(s, delimiter)
      result = {};
      for match in (s..delimiter):gmatch("(.-)"..delimiter) do
          table.insert(result, match);
      end
      return result[#result];
    end

    event.log.upstream_addr             = split_first(split_last(event.log.upstream_addr, ', '), ':')
    event.log.upstream_bytes_received   = split_last(event.log.upstream_bytes_received, ', ')
    event.log.upstream_bytes_sent       = split_last(event.log.upstream_bytes_sent, ', ')
    event.log.upstream_connect_time     = split_last(event.log.upstream_connect_time, ', ')
    event.log.upstream_header_time      = split_last(event.log.upstream_header_time, ', ')
    event.log.upstream_response_length  = split_last(event.log.upstream_response_length, ', ')
    event.log.upstream_response_time    = split_last(event.log.upstream_response_time, ', ')
    event.log.upstream_status           = split_last(event.log.upstream_status, ', ')

    if event.log.upstream_addr == "" then
        event.log.upstream_addr = "127.0.0.1"
    end

    if (event.log.upstream_bytes_received == "-" or event.log.upstream_bytes_received == "") then
        event.log.upstream_bytes_received = "0"
    end

    if (event.log.upstream_bytes_sent == "-" or event.log.upstream_bytes_sent == "") then
        event.log.upstream_bytes_sent = "0"
    end

    if event.log.upstream_cache_status == "" then
        event.log.upstream_cache_status = "DISABLED"
    end

    if (event.log.upstream_connect_time == "-" or event.log.upstream_connect_time == "") then
        event.log.upstream_connect_time = "0"
    end

    if (event.log.upstream_header_time == "-" or event.log.upstream_header_time == "") then
        event.log.upstream_header_time = "0"
    end

    if (event.log.upstream_response_length == "-" or event.log.upstream_response_length == "") then
        event.log.upstream_response_length = "0"
    end

    if (event.log.upstream_response_time == "-" or event.log.upstream_response_time == "") then
        event.log.upstream_response_time = "0"
    end

    if (event.log.upstream_status == "-" or event.log.upstream_status == "") then
        event.log.upstream_status = "0"
    end

    emit(event)

  end
  """

[transforms.nginx_parse_remove_fields]
    inputs                              = [ "nginx_parse_add_defaults" ]
    type                                = "remove_fields"
    fields                              = ["data", "file", "host", "source_type"]

[transforms.nginx_parse_coercer]

    type                                = "coercer"
    inputs                              = ["nginx_parse_remove_fields"]

    types.request_length = "int"
    types.request_time = "float"

    types.response_status = "int"
    types.response_body_bytes_sent = "int"

    types.remote_port = "int"

    types.upstream_bytes_received = "int"
    types.upstream_bytes_send = "int"
    types.upstream_connect_time = "float"
    types.upstream_header_time = "float"
    types.upstream_response_length = "int"
    types.upstream_response_time = "float"
    types.upstream_status = "int"

    types.timestamp = "timestamp"

[sinks.nginx_output_clickhouse]
    inputs   = ["nginx_parse_coercer"]
    type     = "clickhouse"

    database = "vector"
    healthcheck = true
    host = "http://172.26.10.109:8123" #  Адрес Clickhouse
    table = "logs"

    encoding.timestamp_format = "unix"

    buffer.type = "disk"
    buffer.max_size = 104900000
    buffer.when_full = "block"

    request.in_flight_limit = 20

[sinks.elasticsearch]
    type = "elasticsearch"
    inputs   = ["nginx_parse_coercer"]
    compression = "none"
    healthcheck = true
    # 172.26.10.116 - сервер где установен elasticsearch
    host = "http://172.26.10.116:9200" 
    index = "vector-%Y-%m-%d"

Puedes ajustar la sección transforms.nginx_parse_add_defaults.

Dado que Viacheslav Rakhinskiy. usa estas configuraciones para un pequeño CDN y en upstream_* pueden recibir varios valores.

Por ejemplo:

"upstream_addr": "128.66.0.10:443, 128.66.0.11:443, 128.66.0.12:443"
"upstream_bytes_received": "-, -, 123"
"upstream_status": "502, 502, 200"

Si esta no es su situación, esta sección se puede simplificar.

Crearemos la configuración del servicio para systemd /etc/systemd/system/vector.service

# /etc/systemd/system/vector.service

[Unit]
Description=Vector
After=network-online.target
Requires=network-online.target

[Service]
User=vector
Group=vector
ExecStart=/usr/bin/vector
ExecReload=/bin/kill -HUP $MAINPID
Restart=no
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=vector

[Install]
WantedBy=multi-user.target

Después de crear las tablas, se puede iniciar Vector.

systemctl enable vector
systemctl start vector

Los registros de vector se pueden ver así:

journalctl -f -u vector

En los registros deben aparecer estas entradas:

INFO vector::topology::builder: Healthcheck: Pasó.
INFO vector::topology::builder: Healthcheck: Pasó.

En el cliente (Servidor Web) — primer servidor.

En el servidor con nginx, es necesario desactivar ipv6, ya que en la tabla logs en clickhouse se utiliza el campo upstream_addr IPv4, ya que no utilizo ipv6 dentro de la red. Si no se desactiva ipv6, habrá errores:

DB::Exception: Valor IPv4 inválido.: (al leer el valor de la clave upstream_addr)

Es posible que los lectores deban agregar soporte para ipv6.

Creamos el archivo /etc/sysctl.d/98-disable-ipv6.conf

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Aplicamos la configuración.

sysctl --system

Instalaremos nginx.

Agregué el archivo del repositorio nginx /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

Instalaremos el paquete nginx.

yum install -y nginx

Para empezar, necesitamos configurar el formato de los registros en Nginx en el archivo /etc/nginx/nginx.conf

usuario nginx;
# Debes establecer los procesos de trabajo según tus núcleos de CPU, nginx no se beneficia de configurar más de eso
worker_processes auto; # algunas versiones recientes lo calculan automáticamente

# número de descriptores de archivo utilizados por nginx
# el límite para el máximo de FDs en el servidor suele ser establecido por el SO.
# si no estableces FD, se utilizarán las configuraciones del SO que por defecto son 2000
worker_rlimit_nofile 100000;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

# proporciona el contexto del archivo de configuración en el que se especifican las directivas que afectan al procesamiento de conexiones.
events {
    # determina cuántos clientes serán atendidos por trabajador
    # max clientes = worker_connections * worker_processes
    # el número máximo de clientes también está limitado por la cantidad de conexiones de socket disponibles en el sistema (~64k)
    worker_connections 4000;

    # optimizado para atender a muchos clientes con cada hilo, esencial para linux -- para entorno de prueba
    use epoll;

    # acepta tantas conexiones como sea posible, puede inundar las conexiones del trabajador si se establece demasiado bajo -- para entorno de prueba
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

log_format vector escape=json
    '{'
        '"node_name":"nginx-vector",'
        '"timestamp":"$time_iso8601",'
        '"server_name":"$server_name",'
        '"request_full": "$request",'
        '"request_user_agent":"$http_user_agent",'
        '"request_http_host":"$http_host",'
        '"request_uri":"$request_uri",'
        '"request_scheme": "$scheme",'
        '"request_method":"$request_method",'
        '"request_length":"$request_length",'
        '"request_time": "$request_time",'
        '"request_referrer":"$http_referer",'
        '"response_status": "$status",'
        '"response_body_bytes_sent":"$body_bytes_sent",'
        '"response_content_type":"$sent_http_content_type",'
        '"remote_addr": "$remote_addr",'
        '"remote_port": "$remote_port",'
        '"remote_user": "$remote_user",'
        '"upstream_addr": "$upstream_addr",'
        '"upstream_bytes_received": "$upstream_bytes_received",'
        '"upstream_bytes_sent": "$upstream_bytes_sent",'
        '"upstream_cache_status":"$upstream_cache_status",'
        '"upstream_connect_time":"$upstream_connect_time",'
        '"upstream_header_time":"$upstream_header_time",'
        '"upstream_response_length":"$upstream_response_length",'
        '"upstream_response_time":"$upstream_response_time",'
        '"upstream_status": "$upstream_status",'
        '"upstream_content_type":"$upstream_http_content_type"'
    '}';

    access_log  /var/log/nginx/access.log  main;
    access_log  /var/log/nginx/access.json.log vector;      # Nuevo log en formato json

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

Para no romper tu configuración actual, Nginx permite tener múltiples directivas access_log

access_log  /var/log/nginx/access.log  main;            # Log estándar
access_log  /var/log/nginx/access.json.log vector;      # Nuevo log en formato json

No olvides añadir una regla en logrotate para los nuevos logs (si el archivo de log no termina en .log)

Eliminamos default.conf de /etc/nginx/conf.d/

rm -f /etc/nginx/conf.d/default.conf

Añadimos un host virtual /etc/nginx/conf.d/vhost1.conf

server {
    listen 80;
    server_name vhost1;
    location / {
        proxy_pass http://172.26.10.106:8080;
    }
}

Añadimos el host virtual /etc/nginx/conf.d/vhost2.conf

server {
    listen 80;
    server_name vhost2;
    location / {
        proxy_pass http://172.26.10.108:8080;
    }
}

Añadimos el host virtual /etc/nginx/conf.d/vhost3.conf

server {
    listen 80;
    server_name vhost3;
    location / {
        proxy_pass http://172.26.10.109:8080;
    }
}

Añadimos el host virtual /etc/nginx/conf.d/vhost4.conf

server {
    listen 80;
    server_name vhost4;
    location / {
        proxy_pass http://172.26.10.116:8080;
    }
}

Añadimos en el archivo /etc/hosts los hosts virtuales (172.26.10.106 es la IP del servidor donde está instalado nginx) en todos los servidores:

172.26.10.106 vhost1
172.26.10.106 vhost2
172.26.10.106 vhost3
172.26.10.106 vhost4

Y si todo está listo, entonces

nginx -t 
systemctl restart nginx

Ahora instalaremos el mismo Vector

yum install -y https://packages.timber.io/vector/0.9.X/vector-x86_64.rpm

Crearemos el archivo de configuración para systemd /etc/systemd/system/vector.service

[Unit]
Description=Vector
After=network-online.target
Requires=network-online.target

[Service]
User=vector
Group=vector
ExecStart=/usr/bin/vector
ExecReload=/bin/kill -HUP $MAINPID
Restart=no
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=vector

[Install]
WantedBy=multi-user.target

Y configuraremos la sustitución de Filebeat en la configuración /etc/vector/vector.toml. La dirección IP 172.26.10.108 es la dirección IP del servidor de logs (Vector-Server)

data_dir = "/var/lib/vector"

[sources.nginx_file]
  type                          = "file"
  include                       = [ "/var/log/nginx/access.json.log" ]
  start_at_beginning            = false
  fingerprinting.strategy       = "device_and_inode"

[sinks.nginx_output_vector]
  type                          = "vector"
  inputs                        = [ "nginx_file" ]

  address                       = "172.26.10.108:9876"

No olvides agregar el usuario vector al grupo necesario para que pueda leer los archivos de log. Por ejemplo, nginx en centos crea logs con permisos del grupo adm.

usermod -a -G adm vector

Iniciaremos el servicio vector

systemctl enable vector
systemctl start vector

Los registros de vector se pueden ver así:

journalctl -f -u vector

En los logs debería aparecer este registro

INFO vector::topology::builder: Healthcheck: Passed.

Pruebas de carga

Realizamos pruebas utilizando Apache benchmark.

El paquete httpd-tools ha sido instalado en todos los servidores

Empezamos la prueba usando Apache benchmark desde 4 servidores diferentes en screen. Primero lanzamos el multiplexor de terminal screen, y luego iniciamos la prueba con Apache benchmark. Cómo trabajar con screen puedes encontrar en el artículo.

Desde el primer servidor

while true; do ab -H "User-Agent: 1server" -c 100 -n 10 -t 10 http://vhost1/; sleep 1; done

Desde el segundo servidor

while true; do ab -H "User-Agent: 2server" -c 100 -n 10 -t 10 http://vhost2/; sleep 1; done

Desde el tercer servidor

while true; do ab -H "User-Agent: 3server" -c 100 -n 10 -t 10 http://vhost3/; sleep 1; done

Desde el cuarto servidor

while true; do ab -H "User-Agent: 4server" -c 100 -n 10 -t 10 http://vhost4/; sleep 1; done

Verificaremos los datos en Clickhouse

Accedemos a Clickhouse.

clickhouse-client -h 172.26.10.109 -m

Hacemos una consulta SQL

SELECCIONAR * DE vector.logs;

┌─node_name────┬───────────timestamp─┬─server_name─┬─user_id─┬─request_full───┬─request_user_agent─┬─request_http_host─┬─request_uri─┬─request_scheme─┬─request_method─┬─request_length─┬─request_time─┬─request_referrer─┬─response_status─┬─response_body_bytes_sent─┬─response_content_type─┬───remote_addr─┬─remote_port─┬─remote_user─┬─upstream_addr─┬─upstream_port─┬─upstream_bytes_received─┬─upstream_bytes_sent─┬─upstream_cache_status─┬─upstream_connect_time─┬─upstream_header_time─┬─upstream_response_length─┬─upstream_response_time─┬─upstream_status─┬─upstream_content_type─┐
│ nginx-vector │ 2020-08-07 04:32:42 │ vhost1      │         │ GET / HTTP/1.0 │ 1server            │ vhost1            │ /           │ http           │ GET            │             66 │        0.028 │                  │             404 │                       27 │                       │ 172.26.10.106 │       45886 │             │ 172.26.10.106 │             0 │                     109 │                  97 │ DISABLEADO              │                     0 │                0.025 │                       27 │                  0.029 │             404 │                       │
└──────────────┴─────────────────────┴─────────────┴─────────┴────────────────┴────────────────────┴───────────────────┴─────────────┴────────────────┴────────────────┴────────────────┴──────────────┴──────────────────┴─────────────────┴──────────────────────────┴───────────────────────┴───────────────┴─────────────┴─────────────┴───────────────┴───────────────┴─────────────────────────┴─────────────────────┴───────────────────────┴───────────────────────┴──────────────────────┴──────────────────────────┴────────────────────────┴─────────────────┴───────────────────────

Conocemos el tamaño de las tablas en Clickhouse

SELECT concat(database, '.', table)                         AS tabla,
       formatReadableSize(sum(bytes))                       AS tamaño,
       sum(rows)                                            AS filas,
       max(modification_time)                               AS última_modificación,
       sum(bytes)                                           AS tamaño_bytes,
       any(engine)                                          AS motor,
       formatReadableSize(sum(primary_key_bytes_in_memory)) AS tamaño_claves_principales
FROM system.parts
WHERE active
GROUP BY database, table
ORDER BY tamaño_bytes DESC;

Verificamos cuánto espacio ocupan los logs en Clickhouse.

Envío de registros JSON de Nginx con Vector a Clickhouse y Elasticsearch

El tamaño de la tabla logs es de 857.19 MB.

Envío de registros JSON de Nginx con Vector a Clickhouse y Elasticsearch

El tamaño de los mismos datos en el índice de Elasticsearch ocupa 4.5 GB.

Si no se especifica vector en los parámetros de Clickhouse, los datos ocupan 4500/857.19 = 5.24 veces menos que en Elasticsearch.

En vector, el campo compression se utiliza por defecto.

Chat de Telegram sobre Clickhouse
Chat de Telegram sobre Elasticsearch
Chat de Telegram sobre "Recolección y análisis de sistemas mensajes"

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster