
, dissenyat per recollir, transformar i enviar dades de registre, mètriques i esdeveniments.
→
En estar escrit en llenguatge Rust, es caracteritza per un alt rendiment i un baix consum de memòria RAM en comparació amb els seus anàlegs. A més, es presta molta atenció a les funcions relacionades amb la correcció, en particular, la capacitat de desar els esdeveniments no enviats en una memòria intermèdia del disc i girar fitxers.
Arquitectònicament, Vector és un encaminador d'esdeveniments que rep missatges d'un o més fonts, aplicant opcionalment sobre aquests missatges transformacions, i enviant-los a un o més desguassos.
Vector és un substitut de filebeat i logstash, pot actuar en ambdues funcions (rebre i enviar registres), més detalls sobre ells .
Si a Logstash la cadena es construeix com a entrada → filtre → sortida, a Vector ho és → →
Es poden trobar exemples a la documentació.
Aquesta instrucció és una instrucció revisada de . Les instruccions originals contenen el processament de geoip. Quan es va provar geoip des d'una xarxa interna, el vector va donar un error.
Aug 05 06:25:31.889 DEBUG transform{name=nginx_parse_rename_fields type=rename_fields}: vector::transforms::rename_fields: Field did not exist field=«geoip.country_name» rate_limit_secs=30Si algú necessita processar geoip, consulteu les instruccions originals de .
Configurarem la combinació de Nginx (Registres d'accés) → Vector (Client | Filebeat) → Vector (Servidor | Logstash) → per separat a Clickhouse i per separat a Elasticsearch. Instal·larem 4 servidors. Encara que es pot evitar amb 3 servidors.

L'esquema és una cosa així.
Desactiveu Selinux a tots els vostres servidors
sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
rebootInstal·lem un emulador de servidor HTTP + utilitats a tots els servidors
Com a emulador de servidor HTTP utilitzarem d'
Nodejs-stub-server no té un rpm. crear rpm per a això. rpm es compilarà amb
Afegiu el repositori antonpatsev/nodejs-stub-server
yum -y install yum-plugin-copr epel-release
yes | yum copr enable antonpatsev/nodejs-stub-serverInstal·leu nodejs-stub-server, el punt de referència Apache i el multiplexor de terminals de pantalla a tots els servidors
yum -y install stub_http_server screen mc httpd-tools screenVaig corregir el temps de resposta stub_http_server al fitxer /var/lib/stub_http_server/stub_http_server.js perquè hi hagués més registres.
var max_sleep = 10;Anem a llançar stub_http_server.
systemctl start stub_http_server
systemctl enable stub_http_serveral servidor 3
ClickHouse utilitza el conjunt d'instruccions SSE 4.2, de manera que tret que s'especifiqui el contrari, el suport al processador utilitzat es converteix en un requisit addicional del sistema. Aquí teniu l'ordre per comprovar si el processador actual admet SSE 4.2:
grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"Primer heu de connectar el repositori 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_64Per instal·lar paquets, heu d'executar les ordres següents:
sudo yum install -y clickhouse-server clickhouse-clientPermet que clickhouse-server escolti la targeta de xarxa al fitxer /etc/clickhouse-server/config.xml
<listen_host>0.0.0.0</listen_host>Canviar el nivell de registre de traça a depuració
depurar
Configuració estàndard de compressió:
min_compress_block_size 65536
max_compress_block_size 1048576Per activar la compressió Zstd, es va aconsellar no tocar la configuració, sinó utilitzar DDL.

No he pogut trobar com utilitzar la compressió zstd mitjançant DDL a Google. Així que ho vaig deixar tal qual.
Col·legues que utilitzen la compressió zstd a Clickhouse, compartiu les instruccions.
Per iniciar el servidor com a dimoni, executeu:
service clickhouse-server startAra passem a configurar Clickhouse
Aneu a Clickhouse
clickhouse-client -h 172.26.10.109 -m172.26.10.109 — IP del servidor on està instal·lat Clickhouse.
Creem una base de dades vectorial
CREATE DATABASE vector;Comprovem que la base de dades existeix.
show databases;Creeu una taula 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;Comprovem que les taules s'han creat. Llançarem clickhouse-client i fer una petició.
Anem a la base de dades vectorials.
use vector;
Ok.
0 rows in set. Elapsed: 0.001 sec.Mirem les taules.
show tables;
┌─name────────────────┐
│ logs │
└─────────────────────┘Instal·lació d'elasticsearch al 4t servidor per enviar les mateixes dades a Elasticsearch per comparar-les amb Clickhouse
Afegiu una clau rpm pública
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearchCreem 2 dipòsits:
/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-mdInstal·leu elasticsearch i kibana
yum install -y kibana elasticsearchCom que estarà en 1 còpia, heu d'afegir el següent al fitxer /etc/elasticsearch/elasticsearch.yml:
discovery.type: single-nodePerquè aquest vector pugui enviar dades a elasticsearch des d'un altre servidor, canviem network.host.
network.host: 0.0.0.0Per connectar-vos a kibana, canvieu el paràmetre server.host al fitxer /etc/kibana/kibana.yml
server.host: "0.0.0.0"Antic i inclou elasticsearch a l'inici automàtic
systemctl enable elasticsearch
systemctl start elasticsearchi kibana
systemctl enable kibana
systemctl start kibanaConfiguració d'Elasticsearch per al mode d'un sol node 1 fragment, 0 rèplica. El més probable és que tingueu un clúster d'un gran nombre de servidors i no cal que ho feu.
Per a índexs futurs, actualitzeu la plantilla predeterminada:
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"}}' Instal · lació com a reemplaçament de Logstash al servidor 2
yum install -y https://packages.timber.io/vector/0.9.X/vector-x86_64.rpm mc httpd-tools screenConfigurem Vector com a substitut de Logstash. Editant el fitxer /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"Podeu ajustar la secció transforms.nginx_parse_add_defaults.
Com utilitza aquestes configuracions per a un CDN petit i hi pot haver diversos valors a upstream_*
Per exemple:
"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 aquesta no és la vostra situació, aquesta secció es pot simplificar
Creem la configuració del servei per a 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.targetDesprés de crear les taules, podeu executar Vector
systemctl enable vector
systemctl start vectorEls registres vectorials es poden veure així:
journalctl -f -u vectorHi hauria d'haver entrades com aquesta als registres
INFO vector::topology::builder: Healthcheck: Passed.
INFO vector::topology::builder: Healthcheck: Passed.Al client (servidor web) - 1r servidor
Al servidor amb nginx, heu de desactivar ipv6, ja que la taula de registres de clickhouse utilitza el camp upstream_addr IPv4, ja que no faig servir ipv6 dins de la xarxa. Si ipv6 no està desactivat, hi haurà errors:
DB::Exception: Invalid IPv4 value.: (while read the value of key upstream_addr)Potser lectors, afegiu suport ipv6.
Creeu el fitxer /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 = 1Aplicant la configuració
sysctl --systemInstal·lem nginx.
S'ha afegit el fitxer del repositori 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=trueInstal·leu el paquet nginx
yum install -y nginxPrimer, hem de configurar el format de registre a Nginx al fitxer /etc/nginx/nginx.conf
user nginx;
# you must set worker processes based on your CPU cores, nginx does not benefit from setting more than that
worker_processes auto; #some last versions calculate it automatically
# number of file descriptors used for nginx
# the limit for the maximum FDs on the server is usually set by the OS.
# if you don't set FD's then OS settings will be used which is by default 2000
worker_rlimit_nofile 100000;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# provides the configuration file context in which the directives that affect connection processing are specified.
events {
# determines how much clients will be served per worker
# max clients = worker_connections * worker_processes
# max clients is also limited by the number of socket connections available on the system (~64k)
worker_connections 4000;
# optimized to serve many clients with each thread, essential for linux -- for testing environment
use epoll;
# accept as many connections as possible, may flood worker connections if set too low -- for testing environment
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; # Новый лог в формате json
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}Per no trencar la vostra configuració actual, Nginx us permet tenir diverses directives access_log
access_log /var/log/nginx/access.log main; # Стандартный лог
access_log /var/log/nginx/access.json.log vector; # Новый лог в формате jsonNo oblideu afegir una regla a logrotate per als registres nous (si el fitxer de registre no acaba amb .log)
Elimina default.conf de /etc/nginx/conf.d/
rm -f /etc/nginx/conf.d/default.confAfegiu l'amfitrió virtual /etc/nginx/conf.d/vhost1.conf
server {
listen 80;
server_name vhost1;
location / {
proxy_pass http://172.26.10.106:8080;
}
}Afegiu l'amfitrió virtual /etc/nginx/conf.d/vhost2.conf
server {
listen 80;
server_name vhost2;
location / {
proxy_pass http://172.26.10.108:8080;
}
}Afegiu l'amfitrió virtual /etc/nginx/conf.d/vhost3.conf
server {
listen 80;
server_name vhost3;
location / {
proxy_pass http://172.26.10.109:8080;
}
}Afegiu l'amfitrió virtual /etc/nginx/conf.d/vhost4.conf
server {
listen 80;
server_name vhost4;
location / {
proxy_pass http://172.26.10.116:8080;
}
}Afegiu hosts virtuals (172.26.10.106 ip del servidor on està instal·lat nginx) a tots els servidors al fitxer /etc/hosts:
172.26.10.106 vhost1
172.26.10.106 vhost2
172.26.10.106 vhost3
172.26.10.106 vhost4I si tot està preparat aleshores
nginx -t
systemctl restart nginxAra instal·lem-lo nosaltres mateixos
yum install -y https://packages.timber.io/vector/0.9.X/vector-x86_64.rpmCreem un fitxer de configuració per a 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.targetI configureu el reemplaçament de Filebeat a la configuració /etc/vector/vector.toml. L'adreça IP 172.26.10.108 és l'adreça IP del servidor de registre (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 us oblideu d'afegir el vector d'usuari al grup adequat perquè pugui llegir els fitxers de registre. Per exemple, nginx a centos crea registres amb drets de grup d'administrador.
usermod -a -G adm vectorComencem el servei vectorial
systemctl enable vector
systemctl start vectorEls registres vectorials es poden veure així:
journalctl -f -u vectorHi hauria d'haver una entrada com aquesta als registres
INFO vector::topology::builder: Healthcheck: Passed.Proves d'estrès
Realitzem proves amb Apache benchmark.
El paquet httpd-tools es va instal·lar a tots els servidors
Comencem a provar amb Apache benchmark de 4 servidors diferents a la pantalla. Primer, iniciem el multiplexor del terminal de pantalla i, a continuació, comencem a provar amb el punt de referència d'Apache. Com treballar amb la pantalla es pot trobar a .
Del 1r servidor
while true; do ab -H "User-Agent: 1server" -c 100 -n 10 -t 10 http://vhost1/; sleep 1; doneDel 2r servidor
while true; do ab -H "User-Agent: 2server" -c 100 -n 10 -t 10 http://vhost2/; sleep 1; doneDel 3r servidor
while true; do ab -H "User-Agent: 3server" -c 100 -n 10 -t 10 http://vhost3/; sleep 1; doneDel 4r servidor
while true; do ab -H "User-Agent: 4server" -c 100 -n 10 -t 10 http://vhost4/; sleep 1; doneComprovem les dades a Clickhouse
Aneu a Clickhouse
clickhouse-client -h 172.26.10.109 -mRealització d'una consulta SQL
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 │ │
└──────────────┴─────────────────────┴─────────────┴─────────┴────────────────┴────────────────────┴───────────────────┴─────────────┴────────────────┴────────────────┴────────────────┴──────────────┴──────────────────┴─────────────────┴──────────────────────────┴───────────────────────┴───────────────┴─────────────┴─────────────┴───────────────┴───────────────┴─────────────────────────┴─────────────────────┴───────────────────────┴───────────────────────┴──────────────────────┴──────────────────────────┴────────────────────────┴─────────────────┴───────────────────────Descobriu la mida de les taules a 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;Descobrim quants registres van ocupar Clickhouse.

La mida de la taula de registres és de 857.19 MB.

La mida de les mateixes dades a l'índex a Elasticsearch és de 4,5 GB.
Si no especifiqueu dades al vector als paràmetres, Clickhouse triga 4500/857.19 = 5.24 vegades menys que a Elasticsearch.
En vector, el camp de compressió s'utilitza per defecte.
Xateja de Telegram per
Xateja de Telegram per
Xat de Telegram per ""
Font: www.habr.com
