Alexey Lizunov, capu di u centru di cumpetenza per i canali di serviziu remoti di a Direzzione di Tecnulugia di l'Informazione di l'ICB
Cum'è una alternativa à a pila ELK (ElasticSearch, Logstash, Kibana), facemu ricerche nantu à l'usu di a basa di dati ClickHouse cum'è un almacenamentu di dati per i logs.
In questu articulu, vulemu parlà di a nostra sperienza cù a basa di dati ClickHouse è i risultati preliminari da l'operazione pilota. Hè da nutà subitu chì i risultati eranu impressiunanti.
In seguitu, descriveremu in più dettagliu cumu u nostru sistema hè cunfiguratu è di quali cumpunenti hè custituitu. Ma avà vogliu parlà un pocu di sta basa di dati in tuttu, è perchè vale a pena attente. A basa di dati ClickHouse hè una basa di dati di columnare analitica di altu rendiment da Yandex. Adupratu in i servizii Yandex, inizialmente questu hè u principale almacenamiento di dati per Yandex.Metrica. Sistema open source, gratuitu. Da u puntu di vista di u sviluppatore, aghju sempre dumandatu cumu implementanu questu, perchè ci sò dati fantastichi grandi. È l'interfaccia d'utilizatore di Metrica stessu hè assai flexible è travaglia rapidamente. Quandu avete prima familiarizatu cù sta basa di dati, avete l'impressione: "Bè, finalmente! Fattu "per u populu"! Da u prucessu di stallazione à l'inviu di e dumande ".
Sta basa di dati hà una barriera d'entrata assai bassa. Ancu un sviluppatore mediu pò installà sta basa di dati in pochi minuti è cumincià à aduprà. Tuttu travaglia bè. Ancu e persone chì sò novi in Linux ponu affruntà rapidamente a stallazione è fà operazioni simplici. Se prima, à sente e parolle Big Data, Hadoop, Google BigTable, HDFS, u sviluppatore mediu hà avutu l'idea chì si parlava di qualchi terabyte, petabyte, chì certi superumani eranu implicati in l'installazione è u sviluppu di sti sistemi, allora cù u L'avventu di a basa di dati ClickHouse avemu un strumentu simplice è comprensibile cù quale pudete risolve una gamma di prublemi prima inaccessibile. Tuttu ciò chì ci vole hè una macchina abbastanza media è cinque minuti per installà. Questu hè, avemu una basa di dati cum'è, per esempiu, MySql, ma solu per almacenà miliardi di dischi! Un tipu di superarchiver cù lingua SQL. Hè cum'è e persone anu datu armi straniere.
Circa u nostru sistema di cullizzioni di log
Per cullà l'infurmazioni, i fugliali di log IIS di l'applicazioni web di formatu standard sò usati (simu ancu impegnati in l'analisi di logs di l'applicazioni, ma u nostru scopu principale in u stadiu pilotu hè di cullà i logs IIS).
Ùn pudemu micca abbandunà cumplettamente a pila ELK per diversi motivi, è cuntinuemu à aduprà i cumpunenti LogStash è Filebeat, chì anu pruvatu bè è travaglianu abbastanza affidabile è prevedibile.
U schema generale di logging hè mostratu in a figura sottu:
Una funzione di arregistramentu di dati in a basa di dati ClickHouse hè l'inserzione pocu frequente (una volta per seconda) di registri in grandi batch. Questu, apparentemente, hè a parte più "problematica" chì avete scontru quandu u travagliu cù a basa di dati ClickHouse per a prima volta: u schema diventa un pocu più cumplicatu.
U plugin per LogStash, chì inserisce direttamente dati in ClickHouse, hà aiutatu assai quì. Stu cumpunente hè implementatu nantu à u stessu servitore cum'è a basa di dati stessu. Dunque, in generale, ùn hè micca cunsigliatu per fà questu, ma da un puntu di vista praticu, per ùn creà servitori separati mentre hè implementatu in u stessu servitore. Ùn avemu micca osservatu fallimenti o cunflitti di risorse cù a basa di dati. Inoltre, deve esse nutatu chì u plugin hà un mecanismu di retray in casu d'errore. È in casu d'errore, u plugin scrive à u discu un batch di dati chì ùn pò micca esse inseritu (u furmatu di u schedariu hè cunvenutu: dopu à edità, pudete facilmente inserisce u batch currected usendu clickhouse-client).
Una lista cumpleta di u software utilizatu in u schema hè presentata in a tabella:
Lista di u software utilizatu
Titulu
discrizzione
Link à a distribuzione
NGINX
Reverse-proxy per limità l'accessu da u portu è l'autorizazione d'urganizazione
Attualmente micca usatu in u schema
FileBeat
Trasferimentu di file logs.
LogStash
Collettore di log.
Adupratu per cullà logs da FileBeat, è ancu per cullà logs da a fila RabbitMQ (per i servitori chì si trovanu in a DMZ.)
Logstash-output-clickhouse
Loagstash plugin per trasferisce logs à a basa di dati ClickHouse in batch
/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
CliccaCasa
Log storage
Nota. A partesi da Aostu 2018, e custruzzioni di rpm "normali" per RHEL apparsu in u repository Yandex, cusì pudete pruvà à aduprà. À u mumentu di a stallazione, avemu usatu pacchetti compilati da Altinity.
Grafana
Visualizazione di logs. Configurazione di dashboards
Redhat & Centos (64 Bit) - l'ultima versione
Fonte di dati ClickHouse per Grafana 4.6+
Plugin per Grafana cù fonte di dati ClickHouse
LogStash
Log router da FileBeat à RabbitMQ queue.
Nota. Sfortunatamente, FileBeat ùn hà micca output direttamente à RabbitMQ, cusì hè necessariu un ligame intermediu in forma di Logstash.
Rabbit MQ
Coda di messagi. Questu hè un buffer di entrate di log in a DMZ
Erlang Runtime (Nessariu per RabbitMQ)
Erlang runtime. Hè necessariu per RabbitMQ per travaglià
A cunfigurazione di u servitore cù a basa di dati ClickHouse hè presentata in a tabella seguente:
Titulu
valore
Vita
Cunfigurazione
HDD: 40 GB
RAM: 8GB
Processore: Core 2 2Ghz
Avete da esse attentu à i cunsiglii per utilizà a basa di dati ClickHouse (
U software in tuttu u sistema
OS: Red Hat Enterprise Linux Server (Maipo)
JRE (Java 8)
Comu pudete vede, questu hè una stazione di travagliu regulare.
A struttura di a tavula per almacenà i logs hè a siguenti:
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;
Utilizemu valori predeterminati per a partizione (mensile) è a granularità di l'indici. Tutti i campi praticamente currispondenu à e voci di log IIS per a registrazione di e richieste http. Separatamente, avemu nutatu chì ci sò campi separati per almacenà tag utm (sò analizati in a tappa di inserisce in a tavula da u campu di stringa di query).
Inoltre, parechji campi di u sistema sò stati aghjuntu à a tavula per almacenà infurmazione nantu à i sistemi, cumpunenti è servitori. Per una descrizzione di sti campi, vede a tabella sottu. In una tavula guardemu logs per parechji sistemi.
Titulu
discrizzione
Esempiu:
fld_app_name
Nome di l'applicazione / sistema
Valori validi:
- site1.domain.com Situ esternu 1
- site2.domain.com Situ esternu 2
- internal-site1.domain.local Situ internu 1
site1.domain.com
fld_app_module
Modulu di sistema
Valori validi:
- web - situ web
- svc - serviziu web di u situ web
- intgr - serviziu di integrazione Web
- bo - Amministratore (BackOffice)
Web
fld_website_name
Nome di u situ in IIS
Diversi sistemi ponu esse implementati in un servitore, o ancu parechji casi di un modulu di sistema
web-main
fld_server_name
Nome di u servitore
web1.domain.com
fld_log_file_name
Path à u schedariu di log in u servitore
Da:inetpublogsLogFiles
W3SVC1u_ex190711.log
Questu permette di custruisce in modu efficiente grafici in Grafana. Per esempiu, vede e dumande da u front end di un sistema specificu. Questu hè simile à u cuntatore di u situ in Yandex.Metrica.
Eccu alcune statistiche nantu à l'usu di basa di dati per dui mesi.
Numero di registri per sistema è cumpunenti
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.)
Volumi di dati di discu
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.
Rapportu di cumpressione di dati di colonna
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.
Descrizzione di cumpunenti utilizati
FileBeat. Trasferimentu di logs di schedari
Stu cumpunente monitoreghja i cambiamenti à i schedarii di log in u discu è passa l'infurmazioni à LogStash. Installatu nantu à tutti i servitori induve i schedarii di log sò scritti (di solitu IIS). Funziona in modu di coda (vale à dì, trasferisce solu i registri aghjuntu à u schedariu). Ma pudete cunfigurà separatamente per trasferisce i schedari sanu. Questu hè convenientu quandu avete bisognu di scaricà dati per i mesi precedenti. Basta à mette u schedariu di log in un cartulare è vi leghje in tuttu.
Quandu u serviziu si ferma, i dati ùn sò più trasferiti à u almacenamiento.
Un esempiu di cunfigurazione hè cusì:
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. Collettore di log
Stu cumpunente hè pensatu per riceve i registri di log da FileBeat (o attraversu una fila RabbitMQ), analizà è inserisci in batch in a basa di dati ClickHouse.
Per inserisce in ClickHouse, utilizate u plugin Logstash-output-clickhouse. U plugin Logstash hà un mecanismu per rinvià e dumande, ma durante un arrestu regulare, hè megliu piantà u serviziu stessu. Quandu si ferma, i missaghji s'acumuleranu in a fila di RabbitMQ, perchè se u stop hè per un bellu pezzu, allora hè megliu piantà Filebeats in i servitori. In un schema induve RabbitMQ ùn hè micca utilizatu (nantu à a reta locale Filebeat manda direttamente logs à Logstash), Filebeats funziona abbastanza accettabile è sicuru, cusì per elli l'indisponibilità di a pruduzzioni ùn hà micca cunsequenze.
Un esempiu di cunfigurazione hè cusì:
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"
Clicca House. Log storage
I logs per tutti i sistemi sò salvati in una tavola (vede à u principiu di l'articulu). Hè pensatu per almacenà infurmazioni nantu à e dumande: tutti i paràmetri sò simili per diversi formati, per esempiu logs IIS, logs apache è nginx. Per i logs di l'applicazioni in quale, per esempiu, l'errore, i missaghji d'informazioni, l'avvertimenti sò registrati, una tavola separata serà furnita cù a struttura adatta (attualmente in u stadiu di cuncepimentu).
Quandu u disignu di una tavula, hè assai impurtante di decide nantu à a chjave primaria (da quale i dati seranu ordinati durante u almacenamiento). U gradu di cumpressione di dati è a velocità di dumanda dipendenu da questu. In u nostru esempiu, a chjave hè
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Questu hè, da u nome di u sistema, u nome di u cumpunente di u sistema è a data di l'avvenimentu. In principiu, a data di l'avvenimentu hè stata prima. Dopu avè spustatu à l'ultimu locu, e dumande cuminciaru à travaglià circa duie volte più veloce. U cambiamentu di a chjave primaria hà bisognu di ricreà a tavula è di re-uploading the data in modu chì ClickHouse hà da ri-sortà i dati nantu à u discu. Questa hè una operazione difficiuli, per quessa, hè cunsigliu di pensà cun cura in anticipu nantu à ciò chì deve esse inclusu in a chjave di sorte.
Hè ancu esse nutatu chì u tipu di dati LowCardinality apparsu in versioni relativamente recenti. Quandu l'utilizanu, a dimensione di dati cumpressi hè ridutta drasticamente per quelli campi chì anu una cardinalità bassa (pochi opzioni).
Attualmente usemu a versione 19.6 è pensamu di pruvà à aghjurnà à l'ultima versione. Hanu caratteristiche maravigliose cum'è Adaptive Granularity, Skipping indexes è u codec DoubleDelta, per esempiu.
Per automaticamente, durante a stallazione, u livellu di logging di cunfigurazione hè stabilitu per traccia. I logs sò rotati è archiviati, ma à u stessu tempu si allarganu finu à un gigabyte. Se ùn ci hè micca bisognu, pudete stabilisce u nivellu à l'avvisu, allora a dimensione di u logu diminuirà drasticamente. I paràmetri di logging sò specificati in u schedariu config.xml:
<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger. h#L105 -->
<level>warning</level>
Certi cumandamenti utili
Поскольку оригинальные пакеты установки собираются по 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. Log router da FileBeat à RabbitMQ queue
Stu cumpunente hè utilizatu per indirizzà i logs chì venenu da FileBeat à a fila RabbitMQ. Ci sò dui punti quì:
- Sfortunatamente, FileBeat ùn hà micca un plugin di output per scrive direttamente à RabbitMQ. E tali funziunalità, à ghjudicà da u postu nantu à u so github, ùn hè micca pianificatu per l'implementazione. Ci hè un plugin per Kafka, ma per certi mutivi ùn pudemu micca aduprà noi stessi.
- Ci sò esigenze per a cullizzioni di logs in a DMZ. Basatu nantu à elli, i logs devenu esse prima in fila è dopu LogStash leghje i registri da a fila esternamente.
Per quessa, specificamente per u casu di servitori situati in una DMZ, hè necessariu di utilizà un tali schema pocu complicatu. Un esempiu di cunfigurazione hè cusì:
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. Coda di missaghji
Stu cumpunente hè utilizatu per buffer l'entrate di log in a DMZ. A registrazione hè fatta attraversu u ligame Filebeat → LogStash. A lettura hè fatta da fora di a DMZ via LogStash. Quandu operanu attraversu RabbitMQ, circa 4 mila missaghji per seconda sò trattati.
U routing di u messagiu hè cunfiguratu da u nome di u sistema, vale à dì, basatu nantu à e dati di cunfigurazione FileBeat. Tutti i missaghji vanu in una fila. Se per una certa ragione u serviziu di fila hè firmatu, questu ùn hà micca purtatu à a perdita di missaghju: FileBeats riceverà errori di cunnessione è cesserà temporaneamente di mandà. È LogStash, chì leghje da a fila, riceverà ancu errori di rete è aspittà chì a cunnessione sia restaurata. In questu casu, sicuru, i dati ùn saranu più scritti in a basa di dati.
I seguenti struzzioni sò usati per creà è cunfigurà file:
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. Dashboards
Stu cumpunente hè utilizatu per visualizà i dati di surviglianza. In questu casu, avete bisognu di stallà a fonte di dati ClickHouse per u plugin Grafana 4.6+. Avemu avutu à aghjustà un pocu per migliurà l'efficienza di processà i filtri SQL in u dashboard.
Per esempiu, avemu usatu variàbbili, è s'ellu ùn sò micca specificatu in u campu di filtru, allora vulemu chì ùn generà micca una cundizione in WHERE di a forma ( uriStem = "AND uriStem ! = "). In questu casu, ClickHouse leghje a colonna uriStem. Allora, avemu pruvatu diverse opzioni è infine riparatu u plugin (a macro $valueIfEmpty) per rinvià 1 in casu di un valore viotu, senza mintuvà a colonna stessu.
È avà pudete aduprà sta dumanda per u graficu
$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')
chì hè cunvertitu in SQL cusì (nota chì i campi uriStem vacanti sò cunvertiti in solu 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
cunchiusioni
L'apparizione di a basa di dati ClickHouse hè diventata un avvenimentu di riferimentu in u mercatu. Era difficiuli d'imagine chì in un istante, cumplettamente gratuitu, eramu armati cù un strumentu putente è praticu per travaglià cù big data. Di sicuru, cum'è i bisogni aumentanu (per esempiu, sharding è replicazione à parechji servitori), u schema diventerà più cumplessu. Ma sicondu i primi impressioni, travaglià cù sta basa di dati hè assai piacevule. Hè chjaru chì u pruduttu hè fattu "per e persone".
Paragunatu à ElasticSearch, u costu di almacenà è di trasfurmazioni di logs, secondu l'estimi preliminari, hè ridutta da cinque à deci volte. In altri palori, se per u voluminu attuale di dati avemu bisognu di stallà un cluster di parechje macchine, allora quandu usendu ClickHouse avemu bisognu solu una macchina di bassa putenza. Iè, sicuru, ElasticSearch hà ancu meccanismi di cumpressione di dati nantu à u discu è altre funziunalità chì ponu riduce significativamente u cunsumu di risorse, ma paragunatu à ClickHouse questu richiederà più costi.
Senza alcuna ottimisazione speciale da a nostra parte, cù paràmetri predeterminati, caricate dati è ricuperazione di dati da a basa di dati travaglia à una velocità incredibile. Ùn avemu micca assai dati ancu (circa 200 million records), ma u servitore stessu hè debule. Puderemu aduprà sta strumentu in u futuru per altri scopi chì ùn sò micca ligati à l'almacenamiento di logs. Per esempiu, per l'analitiche end-to-end, in u campu di sicurità, machine learning.
À a fine, un pocu nantu à i pro è i contra.
Минусы
- Caricà i dischi in grandi lotti. Da una banda, questa hè una funzione, ma avete sempre aduprà cumpunenti supplementari per buffer records. Stu compitu ùn hè micca sempre simplice, ma sempre risolvibile. E vogliu simplificà u schema.
- Alcune funzionalità esotiche o funzioni novi si rompenu spessu in e versioni novi. Questu suscita preoccupazioni, riducendu u desideriu di aghjurnà à una nova versione. Per esempiu, u mutore di table Kafka hè una funzione assai utile chì vi permette di leghje direttamente l'avvenimenti da Kafka, senza implementà i cunsumatori. Ma à ghjudicà da u numeru di Issues nantu à Github, simu sempre attenti à aduprà stu mutore in a produzzione. Tuttavia, s'ellu ùn fate micca muvimenti bruschi à u latu è utilizate a funziunalità di basa, allora u travagliu stabile.
Плюсы
- Ùn rallenta.
- Soglia di entrata bassa.
- fonte aperta.
- Gratuitu.
- Scalable (sharding / replicazione fora di a scatula)
- Inclusu in u registru di u software russu cunsigliatu da u Ministeru di a Comunicazione.
- Disponibilità di supportu ufficiale da Yandex.
Source: www.habr.com