Übertragung von Nginx-JSON-Protokollen mit Vector nach Clickhouse und Elasticsearch

Übertragung von Nginx-JSON-Protokollen mit Vector nach Clickhouse und Elasticsearch

Vector, die zum Sammeln, Transformieren und Versenden von Protokoll-, Metrik- und Ereignisdaten dient.

→ Github

Da es in der Programmiersprache Rust geschrieben ist, zeichnet es sich durch hohe Leistung und geringen Speicherverbrauch im Vergleich zu Alternativen aus. Außerdem wird großer Wert auf Korrektheitsfunktionen gelegt, insbesondere auf die Möglichkeit, nicht gesendete Ereignisse im Pufferspeicher auf der Festplatte zu speichern und Dateien zu rotieren.

Architektonisch ist Vector ein Ereignisrouter, der Nachrichten von einem oder mehreren Quellen, optional Transformationen auf diese Nachrichten anwendend Transformationen, und sie an einen oder mehrere Ziele.

Vector ist ein Ersatz für filebeat und logstash, er kann beide Rollen übernehmen (Logs empfangen und senden), nähere Informationen dazu auf ihrer Website.

Wenn in Logstash die Kette als input → filter → output aufgebaut ist, dann ist es in Vector sourcestransformssinks

Beispiele finden Sie in der Dokumentation.

Diese Anleitung ist eine überarbeitete Version der Anleitung von Vyacheslav Rakhinsky.In der Originalanleitung gibt es eine GeoIP-Verarbeitung. Bei meinen Tests gab es mit GeoIP aus dem internen Netzwerk einen Fehler in Vector.

Aug 05 06:25:31.889 DEBUG transform{name=nginx_parse_rename_fields type=rename_fields}: vector::transforms::rename_fields: Feld existierte nicht field=«geoip.country_name» rate_limit_secs=30

Wenn jemand GeoIP verarbeiten muss, wenden Sie sich an die originale Anleitung von Vyacheslav Rakhinsky..

Wir werden die Verbindung Nginx (Zugriffsprotokolle) → Vector (Client | Filebeat) → Vector (Server | Logstash) → getrennt in Clickhouse und getrennt in Elasticsearch einrichten. Wir werden 4 Server einrichten. Obwohl es auch mit 3 Servern möglich ist.

Übertragung von Nginx-JSON-Protokollen mit Vector nach Clickhouse und Elasticsearch

Das Schema sieht ungefähr so aus.

Deaktivieren Sie Selinux auf allen Ihren Servern.

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

Auf allen Servern installieren wir einen HTTP-Serveremulator + Dienstprogramme.

Als HTTP-Server-Emulator verwenden wir nodejs-stub-server ab Maxim Ignatenko

Nodejs-stub-server hat kein rpm. Hier erstellen wir ein rpm. Das rpm wird mit Hilfe von Fedora Copr

Fügen Sie das Repository antonpatsev/nodejs-stub-server hinzu.

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

Wir installieren nodejs-stub-server, Apache Benchmark und den Terminal-Multiplexer screen auf allen Servern.

yum -y install stub_http_server screen mc httpd-tools screen

Ich habe in der Datei /var/lib/stub_http_server/stub_http_server.js die Antwortzeit des stub_http_server geändert, damit mehr Protokolle erstellt werden.

var max_sleep = 10;

Wir starten stub_http_server.

systemctl start stub_http_server
systemctl enable stub_http_server

Installation von Clickhouse auf dem 3. Server

ClickHouse verwendet den Befehlssatz SSE 4.2, daher wird, sofern nicht anders angegeben, die Unterstützung in der verwendeten CPU zu einer zusätzlichen Systemanforderung. Hier ist der Befehl, um zu überprüfen, ob die aktuelle CPU SSE 4.2 unterstützt:

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

Zuerst müssen Sie das offizielle Repository hinzufügen:

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

Um Pakete zu installieren, führen Sie die folgenden Befehle aus:

sudo yum install -y clickhouse-server clickhouse-client

Wir erlauben dem clickhouse-server, auf die Netzwerkkarte in der Datei /etc/clickhouse-server/config.xml zu hören.

0.0.0.0

Ändern Sie das Protokollierungslevel von trace auf debug.

debug

Die Standardeinstellungen für die Komprimierung sind:

min_compress_block_size  65536
max_compress_block_size  1048576

Um die Zstd-Komprimierung zu aktivieren, wird empfohlen, die Konfiguration nicht zu ändern, sondern besser DDL zu verwenden.

Übertragung von Nginx-JSON-Protokollen mit Vector nach Clickhouse und Elasticsearch

Ich habe keine Informationen gefunden, wie man Zstd-Komprimierung über DDL in Google anwendet. Daher habe ich es so gelassen, wie es ist.

Kollegen, die zstd-Komprimierung in Clickhouse verwenden — bitte teilt mir eure Anleitungen mit.

Um den Server im Hintergrund zu starten, führen Sie Folgendes aus:

service clickhouse-server start

Jetzt gehen wir zu den Clickhouse-Einstellungen.

Wir gehen zu Clickhouse.

clickhouse-client -h 172.26.10.109 -m

172.26.10.109 — die IP des Servers, auf dem Clickhouse installiert ist.

Lassen Sie uns die Datenbank vector erstellen.

CREATE DATABASE vector;

Wir überprüfen, ob die Datenbank vorhanden ist.

show databases;

Wir erstellen die Tabelle 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;

Wir prüfen, ob die Tabellen erstellt wurden. Starten wir clickhouse-client und führen eine Anfrage durch.

Wir gehen zur Datenbank vector.

use vector;

Ok.

0 rows in set. Elapsed: 0.001 sec.

Wir schauen uns die Tabellen an.

show tables;

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

Installation von Elasticsearch auf dem vierten Server, um dieselben Daten an Elasticsearch zu senden, um sie mit Clickhouse zu vergleichen.

Fügen wir den öffentlichen RPM-Schlüssel hinzu.

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

Lassen Sie uns 2 Repositories erstellen:

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

[elasticsearch]
name=Elasticsearch repository for 7.x packages
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=Kibana repository for 7.x packages
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

Wir installieren Elasticsearch und Kibana.

yum install -y kibana elasticsearch

Da es in einer Instanz ausgeführt wird, muss der Parameter in der Datei /etc/elasticsearch/elasticsearch.yml hinzugefügt werden:

discovery.type: single-node

Damit Vector Daten von einem anderen Server an Elasticsearch senden kann, ändern wir network.host.

network.host: 0.0.0.0

Um eine Verbindung zu Kibana herzustellen, ändern wir den Parameter server.host in der Datei /etc/kibana/kibana.yml.

server.host: "0.0.0.0"

Starten Sie Elasticsearch und aktivieren Sie den Autostart.

systemctl enable elasticsearch
systemctl start elasticsearch

und Kibana.

systemctl enable kibana
systemctl start kibana

Konfiguration von Elasticsearch für den Single-Node-Modus mit 1 Shard, 0 Replica. Wahrscheinlich haben Sie einen Cluster aus vielen Servern und müssen dies nicht tun.

Für zukünftige Indizes aktualisieren wir die Standardvorlage:

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"}}' 

Installation Vector als Ersatz für Logstash auf dem zweiten Server.

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

Lassen Sie uns Vector als Ersatz für Logstash konfigurieren. Bearbeiten Sie die Datei /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"

Sie können den Abschnitt transforms.nginx_parse_add_defaults anpassen.

Da das Vyacheslav Rakhinsky verwendet diese Konfigurationen für ein kleines CDN, und dort können in upstream_* mehrere Werte ankommen.

Zum Beispiel:

"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"

Wenn dies nicht Ihre Situation ist, kann dieser Abschnitt vereinfacht werden.

Wir erstellen die service-Einstellungen für 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

Nach dem Erstellen der Tabellen kann Vector gestartet werden.

systemctl enable vector
systemctl start vector

Die Logs von Vector können wie folgt angezeigt werden.

journalctl -f -u vector

In den Logs sollten folgende Einträge vorhanden sein.

INFO vector::topology::builder: Healthcheck: Bestanden.
INFO vector::topology::builder: Healthcheck: Bestanden.

Auf dem Client (Webserver) — 1. Server.

Auf dem Server mit nginx muss ipv6 deaktiviert werden, da im Feld logs in ClickHouse das Attribut upstream_addr IPv4 verwendet wird, da ich kein ipv6 im Netzwerk nutze. Wenn ipv6 nicht deaktiviert wird, treten Fehler auf:

DB::Exception: Ungültiger IPv4-Wert.: (beim Lesen des Wertes des Schlüssels upstream_addr)

Möglicherweise möchten Leser die Unterstützung für ipv6 hinzufügen.

Wir erstellen die Datei /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

Wir wenden die Einstellungen an.

sysctl --system

Wir installieren nginx.

Habe die nginx-Repository-Datei /etc/yum.repos.d/nginx.repo hinzugefügt.

[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

Wir installieren das nginx-Paket.

yum install -y nginx

Zunächst müssen wir das Logformat in Nginx in der Datei /etc/nginx/nginx.conf einstellen.

Benutzer nginx;
# Sie müssen die Anzahl der Arbeitsprozesse basierend auf Ihren CPU-Kernen festlegen, nginx profitiert nicht von der Einstellung von mehr als dieser Zahl
worker_processes auto; # einige letzte Versionen berechnen es automatisch

# Anzahl der Dateideskriptoren, die für nginx verwendet werden
# Das Limit für die maximalen FDs auf dem Server wird normalerweise vom Betriebssystem festgelegt.
# Wenn Sie keine FDs festlegen, werden die Einstellungen des Betriebssystems verwendet, die standardmäßig 2000 betragen
worker_rlimit_nofile 100000;

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

# Bietet den Konfigurationsdateikontext, in dem die Direktiven, die den Verbindungsprozess beeinflussen, angegeben sind.
events {
    # Bestimmt, wie viele Clients pro Worker bedient werden
    # max clients = worker_connections * worker_processes
    # max clients ist auch durch die Anzahl der verfügbaren Socketverbindungen im System (~64k) begrenzt
    worker_connections 4000;

    # Optimiert zum Bedienen vieler Clients mit jedem Thread, entscheidend für Linux – für Testumgebungen
    use epoll;

    # Akzeptiert so viele Verbindungen wie möglich, kann Worker-Verbindungen überfluten, wenn zu niedrig eingestellt – für Testumgebungen
    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;      # Neuer Log im JSON-Format

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

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

Um Ihre aktuelle Konfiguration nicht zu beschädigen, erlaubt Nginx mehrere Direktiven für access_log

access_log  /var/log/nginx/access.log  main;            # Standard-Log
access_log  /var/log/nginx/access.json.log vector;      # Neuer Log im JSON-Format

Vergessen Sie nicht, eine Regel für logrotate für die neuen Logs hinzuzufügen (wenn die log-Datei nicht auf .log endet)

Löschen Sie default.conf aus /etc/nginx/conf.d/

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

Fügen Sie den virtuellen Host /etc/nginx/conf.d/vhost1.conf hinzu

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

Fügen Sie den virtuellen Host /etc/nginx/conf.d/vhost2.conf hinzu

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

Fügen Sie den virtuellen Host /etc/nginx/conf.d/vhost3.conf hinzu

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

Fügen Sie den virtuellen Host /etc/nginx/conf.d/vhost4.conf hinzu

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

Fügen Sie die virtuellen Hosts in die Datei /etc/hosts (172.26.10.106 IP des Servers, auf dem nginx installiert ist) für alle Server hinzu:

172.26.10.106 vhost1
172.26.10.106 vhost2
172.26.10.106 vhost3
172.26.10.106 vhost4

Und wenn alles bereit ist, dann

nginx -t 
systemctl restart nginx

Jetzt installieren wir das selbst Vector

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

Erstellen Sie die Konfigurationsdatei für 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

Und konfigurieren Sie den Ersatz für Filebeat in der Konfiguration /etc/vector/vector.toml. Die IP-Adresse 172.26.10.108 ist die IP-Adresse des Log-Servers (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"

Vergessen Sie nicht, den Benutzer vector zur erforderlichen Gruppe hinzuzufügen, damit er die Logdateien lesen kann. Zum Beispiel erstellt nginx in CentOS Logs mit den Rechten der Gruppe adm.

usermod -a -G adm vector

Starten wir den Vector-Dienst

systemctl enable vector
systemctl start vector

Die Logs von Vector können wie folgt angezeigt werden.

journalctl -f -u vector

Im Log sollte dieser Eintrag zu finden sein

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

Lasttest

Wir führen den Test mit Apache Benchmark durch.

Auf allen Servern wurde das Paket httpd-tools installiert

Wir starten die Tests mit Apache Benchmark von 4 verschiedenen Servern in Screen. Zuerst starten wir den Terminal-Multiplexer screen und dann die Tests mit Apache Benchmark. Wie man mit screen umgeht, können Sie in finden Artikel.

Vom 1. Server

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

Vom 2. Server

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

Vom 3. Server

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

Vom 4. Server

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

Überprüfen wir die Daten in Clickhouse

Wir gehen zu Clickhouse.

clickhouse-client -h 172.26.10.109 -m

Führen Sie die SQL-Abfrage aus

SELECT * FROM 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 │ DISABLED              │                     0 │                0.025 │                       27 │                  0.029 │             404 │                       │
└──────────────┴─────────────────────┴─────────────┴─────────┴────────────────┴────────────────────┴───────────────────┴─────────────┴────────────────┴────────────────┴────────────────┴──────────────┴──────────────────┴─────────────────┴──────────────────────────┴───────────────────────┴───────────────┴─────────────┴─────────────┴───────────────┴───────────────┴─────────────────────────┴─────────────────────┴───────────────────────┴───────────────────────┴──────────────────────┴──────────────────────────┴────────────────────────┴─────────────────┴───────────────────────

Wir erfahren die Größe der Tabellen in Clickhouse

select concat(database, '.', table)                         as table,
       formatReadableSize(sum(bytes))                       as size,
       sum(rows)                                            as rows,
       max(modification_time)                               as latest_modification,
       sum(bytes)                                           as bytes_size,
       any(engine)                                          as engine,
       formatReadableSize(sum(primary_key_bytes_in_memory)) as primary_keys_size
from system.parts
where active
group by database, table
order by bytes_size desc;

Wir erfahren, wie viel Platz die Protokolle in Clickhouse einnehmen.

Übertragung von Nginx-JSON-Protokollen mit Vector nach Clickhouse und Elasticsearch

Die Größe der Tabelle logs beträgt 857,19 MB.

Übertragung von Nginx-JSON-Protokollen mit Vector nach Clickhouse und Elasticsearch

Die Größe derselben Daten im Index in Elasticsearch beträgt 4,5 GB.

Wenn die Daten im Vector in Clickhouse nicht angegeben werden, benötigt es 4500/857,19 = 5,24 Mal weniger als in Elasticsearch.

Im Vector-Feld wird standardmäßig Compression verwendet.

Telegram-Chat zu Clickhouse
Telegram-Chat zu Elasticsearch
Telegram-Chat zu "Sammlung und Analyse von systemischen Nachrichten"

Quelle: habr.com

60GB SSD 8Gb DDR4