Base de datos ClickHouse para humanos, o Alien Technology

Alexey Lizunov, jefe del centro de competencia de canales de servicios remotos de la Dirección de Tecnologías de la Información del ICD



Como alternativa a la pila ELK (ElasticSearch, Logstash, Kibana), estamos realizando investigaciones sobre el uso de la base de datos ClickHouse como un almacén de datos para registros.

En este artículo, nos gustaría hablar sobre nuestra experiencia en el uso de la base de datos ClickHouse y sobre los resultados preliminares de la operación piloto. Cabe señalar de inmediato que los resultados fueron impresionantes.




A continuación, describiremos con más detalle cómo está configurado nuestro sistema y en qué componentes consta. Pero ahora me gustaría hablar un poco sobre esta base de datos en su conjunto, y por qué debería prestarle atención. La base de datos ClickHouse es una base de datos de columnas analíticas de alto rendimiento de Yandex. Se utiliza en los servicios de Yandex, inicialmente es el almacén de datos principal de Yandex.Metrica. El sistema de código abierto es gratuito. Desde el punto de vista del desarrollador, siempre me interesó cómo lo implementaron, porque hay datos increíblemente grandes. Y la interfaz de usuario métrica en sí es muy flexible y rápida. Al primer contacto con esta base de datos, la impresión: “¡Bueno, finalmente! Hecho "para personas"! Comenzando desde el proceso de instalación y terminando con el envío de solicitudes ".

Esta base de datos tiene un umbral de entrada muy bajo. Incluso un desarrollador experto promedio puede instalar esta base de datos en unos minutos y comenzar a usarla. Todo funciona con claridad. Incluso las personas que son nuevas en Linux pueden completar rápidamente la instalación y realizar operaciones simples. Anteriormente, cuando la palabra Big Data, Hadoop, Google BigTable, HDFS, el desarrollador habitual tenía la idea de que estaban hablando de algunos terabytes, petabytes, que algunos superhumanos estaban involucrados en la configuración y el desarrollo de estos sistemas, luego con el advenimiento de la base de datos ClickHouse obtuvimos Una herramienta simple y comprensible con la que puede resolver el rango de tareas previamente inalcanzable. Solo un automóvil bastante promedio y cinco minutos para instalar. Es decir, tenemos una base de datos como, por ejemplo, MySql, ¡pero solo para almacenar miles de millones de registros! Algún tipo de supervisor SQL. Es como si a las personas se les dieran armas de extraterrestres.

Sobre nuestro sistema de recopilación de registros


Para recopilar información, se utilizan archivos de registro IIS de aplicaciones web de formato estándar (también estamos involucrados en analizar registros de aplicaciones, pero el objetivo principal en la etapa de operación piloto con nosotros es recopilar registros IIS).

Por varias razones, no pudimos abandonar completamente la pila ELK, y continuamos usando los componentes LogStash y Filebeat, que han demostrado ser buenos y funcionan de manera bastante confiable y predecible.

El esquema general de registro se presenta en la siguiente figura:



Una característica de escribir datos en la base de datos ClickHouse es la inserción infrecuente (una vez por segundo) de registros en grandes lotes. Aparentemente, esta es la parte más "problemática" que encuentra la primera vez que trabaja con la base de datos ClickHouse: el esquema es un poco complicado.
El complemento LogStash ayudó mucho aquí, que inserta datos directamente en ClickHouse. Este componente se implementa en el mismo servidor que la base de datos en sí. Por lo tanto, en términos generales, no se recomienda hacerlo, sino desde un punto de vista práctico, para no producir servidores separados mientras se implementa en el mismo servidor. No observamos fallas o conflictos de recursos con la base de datos. Además, debe tenerse en cuenta que el complemento tiene un mecanismo de retransmisión en caso de errores. Y en caso de errores, el complemento escribe en el disco un paquete de datos que no se pudo insertar (el formato de archivo es conveniente: después de la edición, puede insertar fácilmente el paquete corregido usando clickhouse-client).

La lista completa de software utilizado en el esquema se presenta en la tabla:

Lista de software usado
Titulo
Descripción
Enlace de distribución

Nginx


Reverse-proxy para restringir el acceso al puerto y la autorización



Actualmente no se usa en el circuito.


https://nginx.org/en/download.html


https://nginx.org/download/nginx-1.16.0.tar.gz


Filebeat


Transferir registros de archivos.


https://www.elastic.co/downloads/beats/filebeat (distribución para Windows de 64 bits).


https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.3.0-windows-x86_64.zip


Logstash


Recolector de troncos.



Se utiliza para recopilar registros de FileBeat, así como para recopilar registros de la cola RabbitMQ (para servidores que están en la DMZ).


https://www.elastic.co/products/logstash


https://artifacts.elastic.co/downloads/logstash/logstash-7.0.1.rpm


Logstash- salida- clickhouse


Complemento Loagstash para transferir registros a la base de datos ClickHouse en lotes


https://github.com/mikechris/logstash-output-clickhouse


/ usr / share / logstash / bin / logstash-plugin install logstash-output-clickhouse


/ usr / share / logstash / bin / logstash-plugin install logstash-filter-prune


/ usr / share / logstash / bin / logstash-plugin install logstash-filter-multiline


Clickhouse


Repositorio de registros https://clickhouse.yandex/docs/ru/


https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-19.5.3.8-1.el7.x86_64.rpm


https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-client-19.5.3.8-1.el7.x86_64.rpm


Nota Desde agosto de 2018, los ensamblajes rpm "normales" para RHEL han aparecido en el repositorio de Yandex, por lo que puede intentar usarlos. En el momento de la instalación, utilizamos paquetes compilados por Altinity.


Grafana


Visualización de registro. Configurar paneles



https://grafana.com/


https://grafana.com/grafana/download



Redhat & Centos (64 Bit) - Última versión


Fuente de datos ClickHouse para Grafana 4.6+


Complemento Grafana con fuente de datos ClickHouse


https://grafana.com/plugins/vertamedia-clickhouse-datasource


https://grafana.com/api/plugins/vertamedia-clickhouse-datasource/versions/1.8.1/download


Logstash


Registre el enrutador de FileBeat en la cola RabbitMQ.


Nota Desafortunadamente, FileBeat no tiene salida directamente en RabbitMQ, por lo que se requiere un enlace intermedio en forma de Logstash


https://www.elastic.co/products/logstash


https://artifacts.elastic.co/downloads/logstash/logstash-7.0.1.rpm


Rabbitmq


Cola de mensajes Este es un búfer de entradas de registro en DMZ


https://www.rabbitmq.com/download.html


https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.14/rabbitmq-server-3.7.14-1.el7.noarch.rpm


Erlang Runtime (requerido para RabbitMQ)


Erlang runtime. Requerido para que RabbitMQ funcione


http://www.erlang.org/download.html


https://www.rabbitmq.com/install-rpm.html#install-erlang http://www.erlang.org/downloads/21.3




La configuración del servidor con la base de datos ClickHouse se presenta en la siguiente tabla:
Titulo
Valor
Nota

Configuracion


HDD: 40 GB
RAM: 8 GB
Procesador: Core 2 2Ghz


Es necesario prestar atención a los consejos sobre el funcionamiento de la base de datos ClickHouse ( https://clickhouse.yandex/docs/ru/operations/tips/ )


Software de todo el sistema


Sistema operativo: Red Hat Enterprise Linux Server (Maipo)


JRE (Java 8)




Como puede ver, esta es una estación de trabajo normal.

La estructura de la tabla para almacenar registros es la siguiente:

log_web.sql
CREATE TABLE log_web ( logdate Date, logdatetime DateTime CODEC(Delta, LZ4HC), fld_log_file_name LowCardinality( String ), fld_server_name LowCardinality( String ), fld_app_name LowCardinality( String ), fld_app_module LowCardinality( String ), fld_website_name LowCardinality( String ), serverIP LowCardinality( String ), method LowCardinality( String ), uriStem String, uriQuery String, port UInt32, username LowCardinality( String ), clientIP String, clientRealIP String, userAgent String, referer String, response String, subresponse String, win32response String, timetaken UInt64 , uriQuery__utm_medium String , uriQuery__utm_source String , uriQuery__utm_campaign String , uriQuery__utm_term String , uriQuery__utm_content String , uriQuery__yclid String , uriQuery__region String ) Engine = MergeTree() PARTITION BY toYYYYMM(logdate) ORDER BY (fld_app_name, fld_app_module, logdatetime) SETTINGS index_granularity = 8192; 


Utilizamos valores predeterminados para la partición (por meses) y la granularidad del índice. Todos los campos corresponden prácticamente a las entradas de registro de IIS para registrar solicitudes http. Por separado, campos separados para almacenar etiquetas utm (se analizan en la etapa de inserción en la tabla desde el campo de cadena de consulta).

También en la tabla se agregan varios campos del sistema para almacenar información sobre sistemas, componentes, servidores. Consulte la tabla a continuación para obtener una descripción de estos campos. En una tabla, almacenamos registros para varios sistemas.

Titulo
Descripción
Ejemplo

fld_app_name


Nombre de aplicación / sistema
Valores válidos:


  • site1.domain.com Sitio externo 1
  • site2.domain.com Sitio externo 2
  • internal-site1.domain.local Sitio interno 1

site1.domain.com

fld_app_module


Módulo del sistema
Valores válidos:


  • web - Sitio web
  • svc - Servicio de sitio web
  • intgr - Servicio de integración web
  • bo - Admin (BackOffice)

web


fld_website_name


Nombre del sitio web en IIS


Se pueden implementar varios sistemas en un servidor, o incluso varias instancias de un módulo de sistema


web-main


fld_server_name


Nombre del servidor


web1.domain.com


fld_log_file_name


La ruta al archivo de registro en el servidor


C: \ inetpub \ logs \ LogFiles
\ W3SVC1 \ u_ex190711.log

Esto le permite construir gráficos de manera efectiva en Grafana. Por ejemplo, vea las solicitudes de la interfaz de un sistema específico. Esto es similar al contador del sitio en Yandex.Metrica.

Aquí hay algunas estadísticas sobre el uso de la base de datos durante dos meses.

Número de registros por sistema y componente.
 SELECT fld_app_name, fld_app_module, count(fld_app_name) AS rows_count FROM log_web GROUP BY fld_app_name, fld_app_module WITH TOTALS ORDER BY fld_app_name ASC, rows_count DESC ┌─fld_app_name─────┬─fld_app_module─┬─rows_count─┐ │ site1.domain.ru │ web │ 131441 │ │ site2.domain.ru │ web │ 1751081 │ │ site3.domain.ru │ web │ 106887543 │ │ site3.domain.ru │ svc │ 44908603 │ │ site3.domain.ru │ intgr │ 9813911 │ │ site4.domain.ru │ web │ 772095 │ │ site5.domain.ru │ web │ 17037221 │ │ site5.domain.ru │ intgr │ 838559 │ │ site5.domain.ru │ bo │ 7404 │ │ site6.domain.ru │ web │ 595877 │ │ site7.domain.ru │ web │ 27778858 │ └──────────────────┴────────────────┴────────────┘ Totals: ┌─fld_app_name─┬─fld_app_module─┬─rows_count─┐ │ │ │ 210522593 │ └──────────────┴────────────────┴────────────┘ 11 rows in set. Elapsed: 4.874 sec. Processed 210.52 million rows, 421.67 MB (43.19 million rows/s., 86.51 MB/s.) 

La cantidad de datos en el disco.
 SELECT formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed, formatReadableSize(sum(data_compressed_bytes)) AS compressed, sum(rows) AS total_rows FROM system.parts WHERE table = 'log_web' ┌─uncompressed─┬─compressed─┬─total_rows─┐ │ 54.50 GiB │ 4.86 GiB │ 211427094 │ └──────────────┴────────────┴────────────┘ 1 rows in set. Elapsed: 0.035 sec. 

El grado de compresión de datos en columnas.
 SELECT name, formatReadableSize(data_uncompressed_bytes) AS uncompressed, formatReadableSize(data_compressed_bytes) AS compressed, data_uncompressed_bytes / data_compressed_bytes AS compress_ratio FROM system.columns WHERE table = 'log_web' ┌─name───────────────────┬─uncompressed─┬─compressed─┬─────compress_ratio─┐ │ logdate │ 401.53 MiB │ 1.80 MiB │ 223.16665968777315 │ │ logdatetime │ 803.06 MiB │ 35.91 MiB │ 22.363966401202305 │ │ fld_log_file_name │ 220.66 MiB │ 2.60 MiB │ 84.99905736932571 │ │ fld_server_name │ 201.54 MiB │ 50.63 MiB │ 3.980924816977078 │ │ fld_app_name │ 201.17 MiB │ 969.17 KiB │ 212.55518183686877 │ │ fld_app_module │ 201.17 MiB │ 968.60 KiB │ 212.67805817411906 │ │ fld_website_name │ 201.54 MiB │ 1.24 MiB │ 162.7204926761546 │ │ serverIP │ 201.54 MiB │ 50.25 MiB │ 4.010824061219731 │ │ method │ 201.53 MiB │ 43.64 MiB │ 4.617721053304486 │ │ uriStem │ 5.13 GiB │ 832.51 MiB │ 6.311522291936919 │ │ uriQuery │ 2.58 GiB │ 501.06 MiB │ 5.269731450124478 │ │ port │ 803.06 MiB │ 3.98 MiB │ 201.91673864241824 │ │ username │ 318.08 MiB │ 26.93 MiB │ 11.812513794583598 │ │ clientIP │ 2.35 GiB │ 82.59 MiB │ 29.132328640073343 │ │ clientRealIP │ 2.49 GiB │ 465.05 MiB │ 5.478382297052563 │ │ userAgent │ 18.34 GiB │ 764.08 MiB │ 24.57905114484208 │ │ referer │ 14.71 GiB │ 1.37 GiB │ 10.736792723669906 │ │ response │ 803.06 MiB │ 83.81 MiB │ 9.582334090987247 │ │ subresponse │ 399.87 MiB │ 1.83 MiB │ 218.4831068635027 │ │ win32response │ 407.86 MiB │ 7.41 MiB │ 55.050315514606815 │ │ timetaken │ 1.57 GiB │ 402.06 MiB │ 3.9947395692010637 │ │ uriQuery__utm_medium │ 208.17 MiB │ 12.29 MiB │ 16.936148912472955 │ │ uriQuery__utm_source │ 215.18 MiB │ 13.00 MiB │ 16.548367623199912 │ │ uriQuery__utm_campaign │ 381.46 MiB │ 37.94 MiB │ 10.055156353418509 │ │ uriQuery__utm_term │ 231.82 MiB │ 10.78 MiB │ 21.502540454070672 │ │ uriQuery__utm_content │ 441.34 MiB │ 87.60 MiB │ 5.038260760449327 │ │ uriQuery__yclid │ 216.88 MiB │ 16.58 MiB │ 13.07721335008116 │ │ uriQuery__region │ 204.35 MiB │ 9.49 MiB │ 21.52661903446796 │ └────────────────────────┴──────────────┴────────────┴────────────────────┘ 28 rows in set. Elapsed: 0.005 sec. 


Descripción de los componentes utilizados.

FileBeat. Transferencia de registro de archivos


Este componente supervisa los cambios en los archivos de registro en el disco y transfiere información a LogStash. Se instala en todos los servidores donde se escriben los archivos de registro (generalmente IIS). Funciona en modo de cola (es decir, solo transfiere registros agregados a un archivo). Pero por separado, puede configurar toda la transferencia de archivos. Esto es útil cuando necesita descargar datos de meses anteriores. Simplemente coloque el archivo de registro en una carpeta y él lo leerá en su totalidad.

Cuando el servicio se detiene, los datos dejan de transferirse al almacenamiento.

Un ejemplo de configuración es el siguiente:

filebeat.yml
 filebeat.inputs: - type: log enabled: true paths: - C:/inetpub/logs/LogFiles/W3SVC1/*.log exclude_files: ['.gz$','.zip$'] tail_files: true ignore_older: 24h fields: fld_server_name: "site1.domain.ru" fld_app_name: "site1.domain.ru" fld_app_module: "web" fld_website_name: "web-main" - type: log enabled: true paths: - C:/inetpub/logs/LogFiles/__Import/access_log-* exclude_files: ['.gz$','.zip$'] tail_files: false fields: fld_server_name: "site2.domain.ru" fld_app_name: "site2.domain.ru" fld_app_module: "web" fld_website_name: "web-main" fld_logformat: "logformat__apache" filebeat.config.modules: path: ${path.config}/modules.d/*.yml reload.enabled: false reload.period: 2s output.logstash: hosts: ["log.domain.com:5044"] ssl.enabled: true ssl.certificate_authorities: ["C:/filebeat/certs/ca.pem", "C:/filebeat/certs/ca-issuing.pem"] ssl.certificate: "C:/filebeat/certs/site1.domain.ru.cer" ssl.key: "C:/filebeat/certs/site1.domain.ru.key" #================================ Processors ===================================== processors: - add_host_metadata: ~ - add_cloud_metadata: ~ 


LogStash Colector de registro


Este componente está diseñado para recibir entradas de registro de FileBeat (o a través de la cola RabbitMQ), analizar e insertar paquetes en la base de datos ClickHouse.

Para insertar en ClickHouse, se utiliza el complemento Logstash-output-clickhouse. El complemento Logstash tiene un mecanismo para recuperar solicitudes, pero con un apagado regular, es mejor detener el servicio en sí. Cuando se detiene, los mensajes se acumularán en la cola RabbitMQ, por lo que si se detiene durante un tiempo prolongado, es mejor detener Filebeats en los servidores. En un esquema donde RabbitMQ no se usa (en la red local, Filebeat envía registros directamente a Logstash), Filebeats funciona de manera bastante aceptable y segura, por lo que para ellos la inaccesibilidad de la salida no tiene consecuencias.

Un ejemplo de configuración es el siguiente:

log_web__filebeat_clickhouse.conf
 input { beats { port => 5044 type => 'iis' ssl => true ssl_certificate_authorities => ["/etc/logstash/certs/ca.cer", "/etc/logstash/certs/ca-issuing.cer"] ssl_certificate => "/etc/logstash/certs/server.cer" ssl_key => "/etc/logstash/certs/server-pkcs8.key" ssl_verify_mode => "peer" add_field => { "fld_server_name" => "%{[fields][fld_server_name]}" "fld_app_name" => "%{[fields][fld_app_name]}" "fld_app_module" => "%{[fields][fld_app_module]}" "fld_website_name" => "%{[fields][fld_website_name]}" "fld_log_file_name" => "%{source}" "fld_logformat" => "%{[fields][fld_logformat]}" } } rabbitmq { host => "queue.domain.com" port => 5671 user => "q-reader" password => "password" queue => "web_log" heartbeat => 30 durable => true ssl => true #ssl_certificate_path => "/etc/logstash/certs/server.p12" #ssl_certificate_password => "password" add_field => { "fld_server_name" => "%{[fields][fld_server_name]}" "fld_app_name" => "%{[fields][fld_app_name]}" "fld_app_module" => "%{[fields][fld_app_module]}" "fld_website_name" => "%{[fields][fld_website_name]}" "fld_log_file_name" => "%{source}" "fld_logformat" => "%{[fields][fld_logformat]}" } } } filter { if [message] =~ "^#" { drop {} } if [fld_logformat] == "logformat__iis_with_xrealip" { grok { match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken} %{NOTSPACE:xrealIP} %{NOTSPACE:xforwarderfor}"] } } else { grok { match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken}"] } } date { match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ] timezone => "Etc/UTC" remove_field => [ "log_timestamp", "@timestamp" ] target => [ "log_timestamp2" ] } ruby { code => "tstamp = event.get('log_timestamp2').to_i event.set('logdatetime', Time.at(tstamp).strftime('%Y-%m-%d %H:%M:%S')) event.set('logdate', Time.at(tstamp).strftime('%Y-%m-%d'))" } if [bytesSent] { ruby { code => "event['kilobytesSent'] = event['bytesSent'].to_i / 1024.0" } } if [bytesReceived] { ruby { code => "event['kilobytesReceived'] = event['bytesReceived'].to_i / 1024.0" } } ruby { code => "event.set('clientRealIP', event.get('clientIP'))" } if [xrealIP] { ruby { code => "event.set('clientRealIP', event.get('xrealIP'))" } } if [xforwarderfor] { ruby { code => "event.set('clientRealIP', event.get('xforwarderfor'))" } } mutate { convert => ["bytesSent", "integer"] convert => ["bytesReceived", "integer"] convert => ["timetaken", "integer"] convert => ["port", "integer"] add_field => { "clientHostname" => "%{clientIP}" } } useragent { source=> "useragent" prefix=> "browser" } kv { source => "uriQuery" prefix => "uriQuery__" allow_duplicate_values => false field_split => "&" include_keys => [ "utm_medium", "utm_source", "utm_campaign", "utm_term", "utm_content", "yclid", "region" ] } mutate { join => { "uriQuery__utm_source" => "," } join => { "uriQuery__utm_medium" => "," } join => { "uriQuery__utm_campaign" => "," } join => { "uriQuery__utm_term" => "," } join => { "uriQuery__utm_content" => "," } join => { "uriQuery__yclid" => "," } join => { "uriQuery__region" => "," } } } output { #stdout {codec => rubydebug} clickhouse { headers => ["Authorization", "Basic abcdsfks..."] http_hosts => ["http://127.0.0.1:8123"] save_dir => "/etc/logstash/tmp" table => "log_web" request_tolerance => 1 flush_size => 10000 idle_flush_time => 1 mutations => { "fld_log_file_name" => "fld_log_file_name" "fld_server_name" => "fld_server_name" "fld_app_name" => "fld_app_name" "fld_app_module" => "fld_app_module" "fld_website_name" => "fld_website_name" "logdatetime" => "logdatetime" "logdate" => "logdate" "serverIP" => "serverIP" "method" => "method" "uriStem" => "uriStem" "uriQuery" => "uriQuery" "port" => "port" "username" => "username" "clientIP" => "clientIP" "clientRealIP" => "clientRealIP" "userAgent" => "userAgent" "referer" => "referer" "response" => "response" "subresponse" => "subresponse" "win32response" => "win32response" "timetaken" => "timetaken" "uriQuery__utm_medium" => "uriQuery__utm_medium" "uriQuery__utm_source" => "uriQuery__utm_source" "uriQuery__utm_campaign" => "uriQuery__utm_campaign" "uriQuery__utm_term" => "uriQuery__utm_term" "uriQuery__utm_content" => "uriQuery__utm_content" "uriQuery__yclid" => "uriQuery__yclid" "uriQuery__region" => "uriQuery__region" } } } 

pipelines.yml
 # This file is where you define your pipelines. You can define multiple. # For more information on multiple pipelines, see the documentation: # https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html - pipeline.id: log_web__filebeat_clickhouse path.config: "/etc/logstash/log_web__filebeat_clickhouse.conf" 


ClickHouse. Almacenamiento de registro


Los registros de todos los sistemas se guardan en una tabla (consulte el comienzo del artículo). Está destinado a almacenar información sobre solicitudes: todos los parámetros son similares para diferentes formatos, por ejemplo, registros IIS, registros apache y nginx. Para los registros de aplicaciones en los que, por ejemplo, se registran errores, mensajes informativos, advertencias, se proporcionará una tabla separada con la estructura correspondiente (ahora en la etapa de diseño).

Al diseñar una tabla, es muy importante determinar la clave primaria (por la cual los datos se ordenarán durante el almacenamiento). El grado de compresión de datos y la velocidad de consulta dependen de esto. En nuestro ejemplo, la clave es
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Es decir, por el nombre del sistema, el nombre del componente del sistema y la fecha del evento. La fecha original del evento fue en primer lugar. Después de moverlo al último lugar, las consultas comenzaron a funcionar aproximadamente dos veces más rápido. Cambiar la clave principal requerirá volver a crear la tabla y volver a cargar los datos para que ClickHouse vuelva a ordenar los datos en el disco. Esta es una operación difícil, por lo que es aconsejable pensar con anticipación qué debe incluirse en la clave de clasificación.

También debe tenerse en cuenta que relativamente en las versiones recientes ha aparecido el tipo de datos LowCardinality Al usarlo, el tamaño de los datos comprimidos se reduce drásticamente para aquellos campos que tienen baja cardinalidad (pocas opciones).

Ahora se usa la versión 19.6, y planeamos intentar actualizar la versión a la última. Incluyeron características tan maravillosas como Adaptive Granularity, Skipping indices y el códec DoubleDelta, por ejemplo.

De forma predeterminada, durante la instalación, el nivel de registro de configuración está configurado para rastrear. Los registros se rotan y archivan, pero se expanden a un gigabyte. Si no es necesario, puede establecer el nivel de advertencia, luego el tamaño del registro disminuye drásticamente. La configuración de registro se establece en el archivo config.xml:

 <!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger. h#L105 --> <level>warning</level> 

Algunos comandos útiles
       Debian,     Linux      Altinity.           : https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse sudo yum search clickhouse-server sudo yum install clickhouse-server.noarch 1.   sudo systemctl status clickhouse-server 2.   sudo systemctl stop clickhouse-server 3.   sudo systemctl start clickhouse-server        (   ";") clickhouse-client --multiline clickhouse-client --multiline --host 127.0.0.1 --password pa55w0rd clickhouse-client --multiline --host 127.0.0.1 --port 9440 --secure --user default --password pa55w0rd                /tmp/log_web_failed.json            : clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /tmp/log_web_failed__fixed.json sudo mv /etc/logstash/tmp/log_web_failed.json /etc/logstash/tmp/log_web_failed__fixed.json sudo chown user_dev /etc/logstash/tmp/log_web_failed__fixed.json sudo clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /etc/logstash/tmp/log_web_failed__fixed.json sudo mv /etc/logstash/tmp/log_web_failed__fixed.json /etc/logstash/tmp/log_web_failed__fixed_.json     quit; ##  TLS https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2 openssl s_client -connect log.domain.com:9440 < /dev/null 


LogStash FileBeat log router a la cola RabbitMQ


Este componente se utiliza para enrutar registros que vienen de FileBeat a la cola RabbitMQ. Hay dos puntos:

  1. Desafortunadamente, FileBeat no tiene un complemento de salida para escribir directamente en RabbitMQ. Y tal funcionalidad, a juzgar por el ish en su github, no está planificada para su implementación. Hay un complemento para Kafka, pero por alguna razón no podemos usarlo en casa.
  2. Hay requisitos para recopilar registros en la DMZ. En función de ellos, los registros primero deben agregarse a la cola y luego LogStash desde el exterior lee las entradas de la cola.

Por lo tanto, es precisamente para el caso de la ubicación del servidor en la DMZ que debe usar un esquema tan ligeramente complicado. Un ejemplo de configuración es el siguiente:

iis_w3c_logs__filebeat_rabbitmq.conf
 input { beats { port => 5044 type => 'iis' ssl => true ssl_certificate_authorities => ["/etc/pki/tls/certs/app/ca.pem", "/etc/pki/tls/certs/app/ca-issuing.pem"] ssl_certificate => "/etc/pki/tls/certs/app/queue.domain.com.cer" ssl_key => "/etc/pki/tls/certs/app/queue.domain.com-pkcs8.key" ssl_verify_mode => "peer" } } output { #stdout {codec => rubydebug} rabbitmq { host => "127.0.0.1" port => 5672 exchange => "monitor.direct" exchange_type => "direct" key => "%{[fields][fld_app_name]}" user => "q-writer" password => "password" ssl => false } } 


RabbitMQ. Cola de mensajes


Este componente se utiliza para almacenar las entradas de registro en la DMZ. La grabación se realiza a través de un montón de Filebeat → LogStash. La lectura se realiza desde fuera de la DMZ a través de LogStash. Cuando se opera a través de RabboitMQ, se procesan aproximadamente 4 mil mensajes por segundo.

El enrutamiento de mensajes se configura según el nombre del sistema, es decir, según los datos de configuración de FileBeat. Todos los mensajes caen en una cola. Si, por alguna razón, el servicio de cola se detiene, esto no conducirá a la pérdida de mensajes: FileBeats recibirá errores de conexión y suspenderá el envío temporal. Y LogStash, que lee desde la cola, también recibirá errores de red y esperará a que se reanude la conexión. Los datos en este caso, por supuesto, ya no se escribirán en la base de datos.

Las siguientes instrucciones se utilizan para crear y configurar colas:

 sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin declare exchange --vhost=/ name=monitor.direct type=direct sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin declare queue --vhost=/ name=web_log durable=true sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin --vhost="/" declare binding source="monitor.direct" destination_type="queue" destination="web_log" routing_key="site1.domain.ru" sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin --vhost="/" declare binding source="monitor.direct" destination_type="queue" destination="web_log" routing_key="site2.domain.ru" 

Grafana Tableros


Este componente se utiliza para visualizar datos de monitoreo. En este caso, debe instalar la fuente de datos ClickHouse para el complemento Grafana 4.6+. Tuvimos que ajustarlo un poco para aumentar la eficiencia del procesamiento de los filtros SQL en un tablero.

Por ejemplo, usamos variables, y si no están establecidas en el campo de filtro, nos gustaría que no genere una condición en la forma WHERE (uriStem = `` AND uriStem! = ''). En este caso, ClickHouse leerá la columna uriStem. En general, probamos diferentes opciones y finalmente arreglamos el complemento (macro $ valueIfEmpty) para que, en caso de un valor vacío, devuelva 1, sin mencionar la columna en sí.

Y ahora puedes usar esta consulta para el gráfico

 $columns(response, count(*) c) from $table where $adhoc and $valueIfEmpty($fld_app_name, 1, fld_app_name = '$fld_app_name') and $valueIfEmpty($fld_app_module, 1, fld_app_module = '$fld_app_module') and $valueIfEmpty($fld_server_name, 1, fld_server_name = '$fld_server_name') and $valueIfEmpty($uriStem, 1, uriStem like '%$uriStem%') and $valueIfEmpty($clientRealIP, 1, clientRealIP = '$clientRealIP') 

que se convierte a dicho SQL (tenga en cuenta que los campos uriStem vacíos se convirtieron a solo 1)

 SELECT t, groupArray((response, c)) AS groupArr FROM ( SELECT (intDiv(toUInt32(logdatetime), 60) * 60) * 1000 AS t, response, count(*) AS c FROM default.log_web WHERE (logdate >= toDate(1565061982)) AND (logdatetime >= toDateTime(1565061982)) AND 1 AND (fld_app_name = 'site1.domain.ru') AND (fld_app_module = 'web') AND 1 AND 1 AND 1 GROUP BY t, response ORDER BY t ASC, response ASC ) GROUP BY t ORDER BY t ASC 

Conclusión


La aparición de la base de datos ClickHouse se ha convertido en un evento histórico en el mercado. Era difícil imaginar que de forma gratuita en un instante, estuviéramos armados con una herramienta poderosa y práctica para trabajar con big data. Por supuesto, con las crecientes necesidades (por ejemplo, fragmentación y replicación en múltiples servidores), el esquema se volverá más complejo. Pero a primera vista, trabajar con esta base de datos es muy bueno. Se puede ver que el producto está hecho "para personas".

En comparación con ElasticSearch, el costo de almacenar y procesar registros, según estimaciones preliminares, se reduce de cinco a diez veces. En otras palabras, si para la cantidad actual de datos tendríamos que configurar un clúster de varias máquinas, cuando usemos ClickHouse solo necesitamos una máquina de bajo consumo. Sí, por supuesto, ElasticSearch también tiene mecanismos para comprimir datos en el disco y otras características que pueden reducir significativamente el consumo de recursos, pero en comparación con ClickHouse, esto será costoso.

Sin ninguna optimización especial por su parte, en la configuración predeterminada, cargar datos y recuperar datos de la base de datos funciona a una velocidad sorprendente. Hasta ahora tenemos algunos datos (alrededor de 200 millones de registros), pero el servidor en sí es débil. En el futuro, podemos usar esta herramienta para otros fines no relacionados con el almacenamiento de registros. Por ejemplo, para análisis de extremo a extremo, en el campo de la seguridad, el aprendizaje automático.

Al final, un poco sobre los pros y los contras.

Contras


  1. Descarga de registros en grandes paquetes. Esto, por un lado, es una característica, pero aún debe usar componentes adicionales para almacenar registros. Esta tarea no siempre es simple, pero aún tiene solución. Y me gustaría simplificar el esquema.
  2. Algunas funciones exóticas o nuevas características a menudo se rompen en nuevas versiones. Esto plantea preocupaciones, reduciendo el deseo de actualizar a una nueva versión. Por ejemplo, el motor de tabla Kafka es una característica muy útil que le permite leer directamente eventos de Kafka, sin la implementación de los consumidores. Pero a juzgar por la cantidad de problemas en el github, aún desconfiamos de usar este motor en la producción. Sin embargo, si no realiza movimientos bruscos hacia un lado y utiliza la funcionalidad básica, entonces funciona de manera estable.

Pros


  1. No se ralentiza.
  2. Umbral de entrada bajo.
  3. Código abierto
  4. Es gratis
  5. Escala bien (fragmentación / replicación de fábrica)
  6. Está incluido en el registro de software ruso recomendado por el Ministerio de Comunicaciones.
  7. La presencia de apoyo oficial de Yandex.

Source: https://habr.com/ru/post/472912/


All Articles