Alexey Lizunov, cap del centre de competència per a canals de servei remot de la Direcció de Tecnologies de la Informació de l'ICB
Com a alternativa a la pila ELK (ElasticSearch, Logstash, Kibana), estem realitzant investigacions sobre l'ús de la base de dades ClickHouse com a emmagatzematge de dades per als registres.
En aquest article ens agradaria parlar de la nostra experiència amb la base de dades ClickHouse i dels resultats preliminars de l'operació pilot. Val la pena assenyalar de seguida que els resultats van ser impressionants.
A continuació descriurem amb més detall com està configurat el nostre sistema i de quins components consta. Però ara m'agradaria parlar una mica d'aquesta base de dades en el seu conjunt i per què val la pena parar-hi atenció. La base de dades ClickHouse és una base de dades columnar analítica d'alt rendiment de Yandex. S'utilitza als serveis Yandex, inicialment aquest és l'emmagatzematge de dades principal per a Yandex.Metrica. Sistema de codi obert, gratuït. Des del punt de vista d'un desenvolupador, sempre em vaig preguntar com ho van implementar, perquè hi ha dades fantàsticament grans. I la interfície d'usuari de Metrica és molt flexible i funciona ràpidament. Quan us familiaritzeu amb aquesta base de dades, teniu la impressió: “Bé, per fi! Fet "per al poble"! Des del procés d'instal·lació fins a l'enviament de sol·licituds."
Aquesta base de dades té una barrera d'entrada molt baixa. Fins i tot un desenvolupador mitjà pot instal·lar aquesta base de dades en pocs minuts i començar a utilitzar-la. Tot funciona sense problemes. Fins i tot les persones que són noves a Linux poden fer front ràpidament a la instal·lació i fer operacions senzilles. Si abans, en escoltar les paraules Big Data, Hadoop, Google BigTable, HDFS, el desenvolupador mitjà tenia la idea que parlaven d'uns terabytes, petabytes, que alguns superhumans estaven implicats en la configuració i desenvolupament d'aquests sistemes, llavors amb l'arribada de la base de dades ClickHouse tenim una eina senzilla i entenedora amb la qual podeu resoldre una sèrie de problemes abans inabastables. Tot el que es necessita és una màquina bastant mitjana i cinc minuts per instal·lar-se. És a dir, tenim una base de dades com, per exemple, MySql, però només per emmagatzemar milers de milions de registres! Una mena de superarxiu amb llenguatge SQL. És com si a la gent li donessin armes alienígenes.
Sobre el nostre sistema de recollida de registres
Per recopilar informació, s'utilitzen fitxers de registre d'IIS d'aplicacions web de format estàndard (actualment també ens dediquem a analitzar els registres d'aplicacions, però el nostre objectiu principal a l'etapa pilot és recollir registres d'IIS).
No hem pogut abandonar completament la pila ELK per diversos motius, i seguim utilitzant els components LogStash i Filebeat, que han demostrat ser bons i funcionen de manera bastant fiable i previsible.
L'esquema general de registre es mostra a la figura següent:
Una característica de l'enregistrament de dades a la base de dades ClickHouse és la inserció poc freqüent (un cop per segon) de registres en grans lots. Aquesta, aparentment, és la part més "problemàtica" que trobeu quan treballeu amb la base de dades ClickHouse per primera vegada: l'esquema es complica una mica.
El connector per a LogStash, que insereix dades directament a ClickHouse, va ajudar molt aquí. Aquest component es desplega al mateix servidor que la pròpia base de dades. Així doncs, en general, no es recomana fer-ho, sinó des d'un punt de vista pràctic, per no crear servidors separats mentre es desplega al mateix servidor. No vam observar cap error ni conflicte de recursos amb la base de dades. A més, cal tenir en compte que el connector té un mecanisme de retransmissió en cas d'error. I en cas d'error, el connector escriu al disc un lot de dades que no s'han pogut inserir (el format del fitxer és convenient: després de l'edició, podeu inserir fàcilment el lot corregit mitjançant clickhouse-client).
A la taula es presenta una llista completa del programari utilitzat en l'esquema:
Llista de programari utilitzat
Nom
Descripció
Enllaç a la distribució
NGINX
Proxy invers per restringir l'accés per port i organitzar l'autorització
Actualment no s'utilitza en l'esquema
FileBeat
Transferència de registres de fitxers.
LogStash
Recollidor de troncs.
S'utilitza per recopilar registres de FileBeat, així com per recopilar registres de la cua RabbitMQ (per als servidors que es troben a la DMZ).
Logstash - sortida - clickhouse
Connector Loagstash per transferir registres a la base de dades ClickHouse per lots
/usr/share/logstash/bin/logstash-plugin install logstash-output-clickhouse
/usr/share/logstash/bin/logstash-plugin instal·lar logstash-filter-prune
/usr/share/logstash/bin/logstash-plugin instal·lar logstash-filter-multiline
Feu clic a Casa
Emmagatzematge de registres
Nota. A partir de l'agost de 2018, les compilacions de rpm "normals" per a RHEL van aparèixer al repositori Yandex, de manera que podeu provar d'utilitzar-les. En el moment de la instal·lació estàvem utilitzant paquets compilats per Altinity.
Grafana
Visualització de registres. Configuració de taulers de control
Redhat i Centos (64 bits): darrera versió
Font de dades ClickHouse per a Grafana 4.6+
Connector per a Grafana amb font de dades ClickHouse
LogStash
Registra l'encaminador de FileBeat a la cua RabbitMQ.
Nota. Malauradament, FileBeat no té sortida directament a RabbitMQ, de manera que es requereix un enllaç intermedi en forma de Logstash
ConillMQ
Cua de missatges. Aquest és un buffer d'entrades de registre a la DMZ
Temps d'execució Erlang (necessari per a RabbitMQ)
Temps d'execució Erlang. Necessari perquè RabbitMQ funcioni
La configuració del servidor amb la base de dades ClickHouse es presenta a la taula següent:
Nom
Valor
Nota
Configuració
Disc dur: 40 GB
RAM: 8GB
Processador: Core 2 2Ghz
Heu de parar atenció als consells per utilitzar la base de dades ClickHouse (
Programari per a tot el sistema
Sistema operatiu: Red Hat Enterprise Linux Server (Maipo)
JRE (Java 8)
Com podeu veure, aquesta és una estació de treball normal.
L'estructura de la taula per emmagatzemar els registres és la següent:
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;
Utilitzem valors predeterminats per a la partició (mensual) i la granularitat de l'índex. Tots els camps corresponen pràcticament a les entrades de registre d'IIS per registrar les sol·licituds http. Per separat, observem que hi ha camps separats per emmagatzemar etiquetes utm (s'analitzen en l'etapa d'inserció a la taula des del camp de la cadena de consulta).
A més, s'han afegit diversos camps del sistema a la taula per emmagatzemar informació sobre sistemes, components i servidors. Per obtenir una descripció d'aquests camps, consulteu la taula següent. En una taula emmagatzemem els registres de diversos sistemes.
Nom
Descripció
Exemple
fld_app_name
Nom de l'aplicació/sistema
Valors vàlids:
- lloc1.domini.com Lloc extern 1
- lloc2.domini.com Lloc extern 2
- lloc intern1.domini.local Lloc intern 1
lloc1.domini.com
fld_app_module
Mòdul del sistema
Valors vàlids:
- web - Lloc web
- svc — Servei web del lloc web
- intgr — Servei d'integració web
- bo — Administrador (BackOffice)
web
fld_nom_website
Nom del lloc a IIS
Es poden desplegar diversos sistemes en un servidor, o fins i tot diverses instàncies d'un mòdul del sistema
web-principal
fld_server_name
Nom del servidor
web1.domini.com
fld_log_file_name
Ruta al fitxer de registre al servidor
Des de:inetpublogsLogFiles
W3SVC1u_ex190711.log
Això us permet crear gràfics de manera eficient a Grafana. Per exemple, visualitzeu les sol·licituds des de la part frontal d'un sistema específic. Això és similar al comptador del lloc a Yandex.Metrica.
Aquí teniu algunes estadístiques sobre l'ús de la base de dades durant dos mesos.
Nombre de registres per sistema i component
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.)
Volum de dades del disc
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.
Relació de compressió de dades de columna
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ó dels components utilitzats
FileBeat. Transferència de registres de fitxers
Aquest component supervisa els canvis als fitxers de registre del disc i passa la informació a LogStash. Instal·lat a tots els servidors on s'escriuen fitxers de registre (normalment IIS). Funciona en mode de cua (és a dir, només transfereix registres afegits al fitxer). Però podeu configurar-lo per separat per transferir fitxers sencers. Això és convenient quan necessiteu descarregar dades dels mesos anteriors. Només cal posar el fitxer de registre en una carpeta i el llegirà sencer.
Quan el servei s'atura, les dades es deixen de transferir a l'emmagatzematge.
Un exemple de configuració és el següent:
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. Col·lector de registres
Aquest component està dissenyat per rebre registres de registre de FileBeat (o mitjançant una cua RabbitMQ), analitzar-los i inserir-los per lots a la base de dades ClickHouse.
Per inserir-lo a ClickHouse, utilitzeu el connector Logstash-output-clickhouse. El connector Logstash té un mecanisme per recuperar les sol·licituds, però durant un tancament regular, és millor aturar el servei en si. Quan s'atura, els missatges s'acumularan a la cua RabbitMQ, de manera que si l'aturada és durant molt de temps, és millor aturar Filebeats als servidors. En un esquema on RabbitMQ no s'utilitza (a la xarxa local Filebeat envia directament els registres a Logstash), Filebeats funcionen bastant acceptable i segur, de manera que per a ells la indisponibilitat de la sortida no té conseqüències.
Un exemple de configuració és el següent:
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. Emmagatzematge de registres
Els registres de tots els sistemes es guarden en una taula (vegeu al principi de l'article). Està dissenyat per emmagatzemar informació sobre sol·licituds: tots els paràmetres són similars per a diferents formats, per exemple, registres d'IIS, registres d'apache i nginx. Per als registres d'aplicacions en què, per exemple, es registren errors, missatges d'informació i avisos, es proporcionarà una taula separada amb l'estructura adequada (actualment en fase de disseny).
Quan es dissenya una taula, és molt important decidir la clau primària (per la qual s'ordenaran les dades durant l'emmagatzematge). D'això depèn el grau de compressió de dades i la velocitat de consulta. En el nostre exemple, la clau és
ORDER BY (nom_aplicació_fld, mòdul_aplicació_fld, datahora)
És a dir, pel nom del sistema, el nom del component del sistema i la data de l'esdeveniment. Inicialment, la data de l'esdeveniment va ser primer. Després de traslladar-lo a l'últim lloc, les consultes van començar a funcionar aproximadament el doble de ràpid. Per canviar la clau primària caldrà tornar a crear la taula i tornar a carregar les dades perquè ClickHouse torni a ordenar les dades al disc. Aquesta és una operació difícil, per la qual cosa s'aconsella pensar detingudament per endavant què s'ha d'incloure a la clau d'ordenació.
També cal tenir en compte que el tipus de dades LowCardinality va aparèixer en versions relativament recents. Quan s'utilitza, la mida de les dades comprimides es redueix dràsticament per als camps que tenen poca cardinalitat (poques opcions).
Actualment estem utilitzant la versió 19.6 i tenim previst intentar actualitzar-la a la darrera versió. Tenen funcions tan meravelloses com la granularitat adaptativa, els índexs de salt i el còdec DoubleDelta, per exemple.
Per defecte, durant la instal·lació, el nivell de registre de configuració s'estableix com a traça. Els registres es giren i s'arxiven, però al mateix temps s'expandeixen fins a un gigabyte. Si no cal, podeu configurar el nivell d'avís i la mida del registre disminuirà bruscament. La configuració de registre s'especifica al fitxer config.xml:
<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger. h#L105 -->
<level>warning</level>
Algunes ordres útils
Поскольку оригинальные пакеты установки собираются по 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. Registra l'encaminador de FileBeat a la cua RabbitMQ
Aquest component s'utilitza per encaminar els registres procedents de FileBeat a la cua RabbitMQ. Aquí hi ha dos punts:
- Malauradament, FileBeat no té un connector de sortida per escriure directament a RabbitMQ. I aquesta funcionalitat, a jutjar per la publicació del seu github, no està prevista per a la implementació. Hi ha un connector per a Kafka, però per certs motius no el podem utilitzar nosaltres mateixos.
- Hi ha requisits per recopilar registres a la DMZ. En funció d'ells, primer s'han de posar en cua els registres i després LogStash llegeix els registres de la cua externament.
Per tant, específicament per al cas dels servidors situats en una DMZ, cal utilitzar un esquema tan lleugerament complicat. Un exemple de configuració és el següent:
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
}
}
ConillMQ. Cua de missatges
Aquest component s'utilitza per guardar les entrades de registre a la DMZ. La gravació es fa mitjançant l'enllaç Filebeat → LogStash. La lectura es fa des de fora de la DMZ mitjançant LogStash. Quan es treballa a través de RabbitMQ, es processen uns 4 mil missatges per segon.
L'encaminament dels missatges es configura pel nom del sistema, és a dir, en funció de les dades de configuració de FileBeat. Tots els missatges van a una cua. Si per algun motiu el servei de cua s'atura, això no comportarà la pèrdua de missatges: FileBeats rebrà errors de connexió i deixarà d'enviar-se temporalment. I LogStash, que llegeix des de la cua, també rebrà errors de xarxa i esperarà que es restableixi la connexió. En aquest cas, per descomptat, les dades ja no s'escriuran a la base de dades.
Les instruccions següents s'utilitzen per crear i configurar cues:
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. Taulers de control
Aquest component s'utilitza per visualitzar les dades de seguiment. En aquest cas, heu d'instal·lar la font de dades ClickHouse per al connector Grafana 4.6+. Hem hagut de modificar-lo una mica per millorar l'eficiència del processament dels filtres SQL al tauler.
Per exemple, utilitzem variables, i si no s'especifiquen al camp de filtre, voldríem que no generi cap condició en el ON del formulari ( uriStem = "AND uriStem != "). En aquest cas, ClickHouse llegirà la columna uriStem. Així doncs, vam provar diferents opcions i finalment vam arreglar el connector (la macro $valueIfEmpty) perquè retornés 1 en cas d'un valor buit, sense esmentar la pròpia columna.
I ara podeu utilitzar aquesta consulta per al gràfic
$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 es converteix a SQL així (tingueu en compte que els camps uriStem buits es converteixen només en 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ó
L'aparició de la base de dades ClickHouse s'ha convertit en un esdeveniment referent al mercat. Era difícil imaginar que en un instant, de forma totalment gratuïta, estiguéssim armats amb una eina potent i pràctica per treballar amb big data. Per descomptat, a mesura que augmenten les necessitats (per exemple, fragmentació i rèplica a diversos servidors), l'esquema es farà més complex. Però segons les primeres impressions, treballar amb aquesta base de dades és molt agradable. És evident que el producte està fet “per a la gent”.
En comparació amb ElasticSearch, el cost d'emmagatzemar i processar els registres, segons estimacions preliminars, es redueix de cinc a deu vegades. En altres paraules, si per al volum actual de dades hauríem de configurar un clúster de diverses màquines, quan utilitzem ClickHouse només necessitem una màquina de baix consum. Sí, per descomptat, ElasticSearch també té mecanismes de compressió de dades al disc i altres característiques que poden reduir significativament el consum de recursos, però en comparació amb ClickHouse això requerirà costos més grans.
Sense cap optimització especial per part nostra, amb la configuració predeterminada, la càrrega de dades i la recuperació de la base de dades funciona a una velocitat increïble. Encara no tenim moltes dades (uns 200 milions de registres), però el servidor en si és feble. Podem utilitzar aquesta eina en el futur per a altres finalitats no relacionades amb l'emmagatzematge de registres. Per exemple, per a l'anàlisi d'extrem a extrem, en l'àmbit de la seguretat, l'aprenentatge automàtic.
Al final, una mica sobre els pros i els contres.
Contres
- Càrrega de registres en lots grans. D'una banda, aquesta és una característica, però encara heu d'utilitzar components addicionals per guardar els registres. Aquesta tasca no sempre és senzilla, però encara es pot resoldre. I m'agradaria simplificar l'esquema.
- Algunes funcionalitats exòtiques o noves característiques solen trencar-se en les noves versions. Això genera preocupacions, reduint el desig d'actualitzar a una versió nova. Per exemple, el motor de taula de Kafka és una característica molt útil que us permet llegir directament els esdeveniments de Kafka, sense implementar els consumidors. Però a jutjar pel nombre de problemes a Github, encara estem desconfiats d'utilitzar aquest motor en producció. Tanmateix, si no feu moviments bruscos cap al costat i utilitzeu la funcionalitat bàsica, funciona de manera estable.
Pros
- No s'alenteix.
- Llindar d'entrada baix.
- Codi obert.
- Gratuït.
- Escalable (fragmentació/replicació immediata)
- Inclòs al registre de programari rus recomanat pel Ministeri de Comunicacions.
- Disponibilitat de suport oficial de Yandex.
Font: www.habr.com