Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Este artículo discutirá el proyecto. recopilador de registros nginx, que leerá los registros de nginx y los enviará al clúster de Clickhouse. Normalmente, ElasticSearch se utiliza para registros. Clickhouse requiere menos recursos (espacio en disco, RAM, CPU). Clickhouse escribe datos más rápido. Clickhouse comprime los datos, lo que hace que los datos en el disco sean aún más compactos. Los beneficios de Clickhouse se pueden ver en 2 diapositivas del informe Cómo VK inserta datos en ClickHouse desde decenas de miles de servidores.

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Para ver análisis basados ​​en registros, crearemos un panel para Grafana.

Cualquier persona interesada, bienvenido al gato.

Instale nginx, grafana de la forma estándar.

Instalación de un clúster de clickhouse usando ansible-playbook desde Denis Proskurin.

Creando bases de datos y tablas en Clickhouse

En este expediente Se describen consultas SQL para crear bases de datos y tablas para nginx-log-collector en Clickhouse.

Realizamos cada solicitud una por una en cada servidor del cluster de Clickhouse.

Nota IMPORTANTE. En esta línea, logs_cluster debe reemplazarse con el nombre de su clúster del archivo clickhouse_remote_servers.xml entre "remote_servers" y "shard".

ENGINE = Distributed('logs_cluster', 'nginx', 'access_log_shard', rand())

Instalación y configuración de nginx-log-collector-rpm

Nginx-log-collector no tiene rpm. Aquí https://github.com/patsevanton/nginx-log-collector-rpm cree rpm para ello. rpm se construirá usando Copr de Fedora

Instale el paquete rpm nginx-log-collector-rpm

yum -y install yum-plugin-copr
yum copr enable antonpatsev/nginx-log-collector-rpm
yum -y install nginx-log-collector
systemctl start nginx-log-collector

Edite la configuración /etc/nginx-log-collector/config.yaml:

  .......
  upload:
    table: nginx.access_log
    dsn: http://ip-адрес-кластера-clickhouse:8123/

- tag: "nginx_error:"
  format: error  # access | error
  buffer_size: 1048576
  upload:
    table: nginx.error_log
    dsn: http://ip-адрес-кластера-clickhouse:8123/

Configurando nginx

Configuración general de nginx:

user  nginx;
worker_processes  auto;

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

events {
    worker_connections  1024;
}

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 avito_json escape=json
                     '{'
                     '"event_datetime": "$time_iso8601", '
                     '"server_name": "$server_name", '
                     '"remote_addr": "$remote_addr", '
                     '"remote_user": "$remote_user", '
                     '"http_x_real_ip": "$http_x_real_ip", '
                     '"status": "$status", '
                     '"scheme": "$scheme", '
                     '"request_method": "$request_method", '
                     '"request_uri": "$request_uri", '
                     '"server_protocol": "$server_protocol", '
                     '"body_bytes_sent": $body_bytes_sent, '
                     '"http_referer": "$http_referer", '
                     '"http_user_agent": "$http_user_agent", '
                     '"request_bytes": "$request_length", '
                     '"request_time": "$request_time", '
                     '"upstream_addr": "$upstream_addr", '
                     '"upstream_response_time": "$upstream_response_time", '
                     '"hostname": "$hostname", '
                     '"host": "$host"'
                     '}';

    access_log     syslog_server=unix:/var/run/nginx_log.sock,nohostname,tag=nginx avito_json; #ClickHouse
    error_log      syslog_server=unix:/var/run/nginx_log.sock,nohostname,tag=nginx_error; #ClickHouse

    #access_log  /var/log/nginx/access.log  main;

    proxy_ignore_client_abort on;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

Un servidor virtual:

vhost1.conf:

upstream backend {
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
}

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

Agregue hosts virtuales al archivo /etc/hosts:

ip-адрес-сервера-с-nginx vhost1

Emulador de servidor HTTP

Como emulador de servidor HTTP usaremos servidor-stub-nodejs de Máximo Ignatenko

Nodejs-stub-server no tiene rpm. Aquí https://github.com/patsevanton/nodejs-stub-server cree rpm para ello. rpm se construirá usando Copr de Fedora

Instale el paquete nodejs-stub-server en nginx rpm ascendente

yum -y install yum-plugin-copr
yum copr enable antonpatsev/nodejs-stub-server
yum -y install stub_http_server
systemctl start stub_http_server

Pruebas de estrés

Realizamos pruebas utilizando el benchmark Apache.

Instalarlo:

yum install -y httpd-tools

Comenzamos las pruebas usando el benchmark Apache desde 5 servidores diferentes:

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

Configurando Grafana

No encontrará un panel en el sitio web oficial de Grafana.

Por tanto, lo haremos a mano.

Puedes encontrar mi panel guardado aquí.

También necesitas crear una variable de tabla con el contenido. nginx.access_log.
Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Solicitudes totales de Singlestat:

SELECT
 1 as t,
 count(*) as c
 FROM $table
 WHERE $timeFilter GROUP BY t

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Solicitudes fallidas de Singlestat:

SELECT
 1 as t,
 count(*) as c
 FROM $table
 WHERE $timeFilter AND status NOT IN (200, 201, 401) GROUP BY t

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Porcentaje de fallos de Singlestat:

SELECT
 1 as t, (sum(status = 500 or status = 499)/sum(status = 200 or status = 201 or status = 401))*100 FROM $table
 WHERE $timeFilter GROUP BY t

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Tiempo de respuesta promedio de Singlestat:

SELECT
 1, avg(request_time) FROM $table
 WHERE $timeFilter GROUP BY 1

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Tiempo de respuesta máximo de Singlestat:

SELECT
 1 as t, max(request_time) as c
 FROM $table
 WHERE $timeFilter GROUP BY t

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Estado del conteo:

$columns(status, count(*) as c) from $table

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Para generar datos como un pastel, debe instalar el complemento y reiniciar grafana.

grafana-cli plugins install grafana-piechart-panel
service grafana-server restart

Pie TOP 5 Estado:

SELECT
    1, /* fake timestamp value */
    status,
    sum(status) AS Reqs
FROM $table
WHERE $timeFilter
GROUP BY status
ORDER BY Reqs desc
LIMIT 5

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Además daré solicitudes sin capturas de pantalla:

Cuente http_user_agent:

$columns(http_user_agent, count(*) c) FROM $table

Buena tasa/Mala tasa:

$rate(countIf(status = 200) AS good, countIf(status != 200) AS bad) FROM $table

tiempo de respuesta:

$rate(avg(request_time) as request_time) FROM $table

Tiempo de respuesta ascendente (primer tiempo de respuesta ascendente):

$rate(avg(arrayElement(upstream_response_time,1)) as upstream_response_time) FROM $table

Estado del recuento de tablas para todos los vhost:

$columns(status, count(*) as c) from $table

Vista general del tablero

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Comparación de avg() y cuantil()

promedio()
Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse
cuantil()
Utilidad Nginx-log-collector de Avito para enviar registros nginx a Clickhouse

Conclusión:

Con suerte, la comunidad se involucrará en el desarrollo/prueba y uso de nginx-log-collector.
Y cuando alguien implemente nginx-log-collector, le dirá cuánto ahorró en disco, RAM y CPU.

Canales de Telegram:

Milisegundos:

A quien le importan los milisegundos, por favor escriba o vote en este .

Fuente: habr.com

Añadir un comentario