Al estar escrito en lenguaje Rust, se caracteriza por un alto rendimiento y un bajo consumo de RAM en comparación con sus análogos. Además, se presta mucha atención a las funciones relacionadas con la corrección, en particular, la capacidad de guardar eventos no enviados en un búfer del disco y rotar archivos.
Arquitectónicamente, Vector es un enrutador de eventos que recibe mensajes de uno o más de fuentes, aplicándose opcionalmente sobre estos mensajes transformacionesy enviarlos a uno o más desagües.
Vector es un reemplazo de filebeat y logstash, puede actuar en ambos roles (recibir y enviar registros), más detalles sobre ellos sitio web.
Si en Logstash la cadena se construye como entrada → filtro → salida, entonces en Vector es fuentes → transformadas → sumideros
Se pueden encontrar ejemplos en la documentación.
Esta instrucción es una instrucción revisada de Viacheslav Rakhinsky. Las instrucciones originales contienen procesamiento geoip. Al probar geoip desde una red interna, vector dio 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=30
Si alguien necesita procesar geoip, consulte las instrucciones originales de Viacheslav Rakhinsky.
Configuraremos la combinación de Nginx (Registros de acceso) → Vector (Cliente | Filebeat) → Vector (Servidor | Logstash) → por separado en Clickhouse y por separado en Elasticsearch. Instalaremos 4 servidores. Aunque puedes evitarlo con 3 servidores.
El esquema es algo como esto.
Deshabilite Selinux en todos sus servidores
sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
reboot
Instalamos un emulador de servidor HTTP + utilidades en todos los servidores.
ClickHouse utiliza el conjunto de instrucciones SSE 4.2, por lo que, a menos que se especifique lo contrario, su compatibilidad en el procesador utilizado se convierte en un requisito adicional del sistema. Aquí está el comando para verificar si el procesador actual es compatible con SSE 4.2:
Configuración de Elasticsearch para modo de nodo único 1 fragmento, 0 réplica. Lo más probable es que tenga un clúster de una gran cantidad de servidores y no es necesario que haga esto.
Para índices futuros, actualice la plantilla predeterminada:
Después de crear las tablas, puede ejecutar Vector
systemctl enable vector
systemctl start vector
Los registros vectoriales se pueden ver así:
journalctl -f -u vector
Debería haber entradas como esta en los registros.
INFO vector::topology::builder: Healthcheck: Passed.
INFO vector::topology::builder: Healthcheck: Passed.
En el cliente (servidor web) - 1er servidor
En el servidor con nginx, debe deshabilitar ipv6, ya que la tabla de registros en clickhouse usa el campo upstream_addr IPv4, ya que no uso ipv6 dentro de la red. Si ipv6 no está desactivado, habrá errores:
DB::Exception: Invalid IPv4 value.: (while read the value of key upstream_addr)
Quizás lectores, agreguen soporte para ipv6.
Cree el archivo /etc/sysctl.d/98-disable-ipv6.conf
Primero, necesitamos configurar el formato de registro en Nginx en el archivo /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;
}
Para no romper su configuración actual, Nginx le permite tener varias directivas access_log
access_log /var/log/nginx/access.log main; # Стандартный лог
access_log /var/log/nginx/access.json.log vector; # Новый лог в формате json
No olvide agregar una regla a logrotate para registros nuevos (si el archivo de registro no termina en .log)
Y configure el reemplazo 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 registro (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 olvide agregar el usuario del vector al grupo requerido para que pueda leer los archivos de registro. Por ejemplo, nginx en centos crea registros con derechos de grupo adm.
usermod -a -G adm vector
Comencemos el servicio de vectores.
systemctl enable vector
systemctl start vector
Los registros vectoriales se pueden ver así:
journalctl -f -u vector
Debería haber una entrada como esta en los registros.
INFO vector::topology::builder: Healthcheck: Passed.
Pruebas de estrés
Realizamos pruebas utilizando el benchmark Apache.
El paquete httpd-tools se instaló en todos los servidores.
Comenzamos las pruebas usando el benchmark Apache desde 4 servidores diferentes en pantalla. Primero, iniciamos el multiplexor del terminal de pantalla y luego comenzamos a realizar pruebas utilizando el punto de referencia de Apache. Cómo trabajar con la pantalla lo puedes encontrar en статье.
Del 1er servidor
while true; do ab -H "User-Agent: 1server" -c 100 -n 10 -t 10 http://vhost1/; sleep 1; done
Del 2er servidor
while true; do ab -H "User-Agent: 2server" -c 100 -n 10 -t 10 http://vhost2/; sleep 1; done
Del 3er servidor
while true; do ab -H "User-Agent: 3server" -c 100 -n 10 -t 10 http://vhost3/; sleep 1; done
Del 4er servidor
while true; do ab -H "User-Agent: 4server" -c 100 -n 10 -t 10 http://vhost4/; sleep 1; done
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;
Averigüemos cuántos registros ocuparon en Clickhouse.
El tamaño de la tabla de registros es 857.19 MB.
El tamaño de los mismos datos en el índice en Elasticsearch es de 4,5 GB.
Si no especifica datos en el vector en los parámetros, Clickhouse toma 4500/857.19 = 5.24 veces menos que en Elasticsearch.
En vector, el campo de compresión se utiliza de forma predeterminada.