Aleksey Lizunov, vedoucí kompetenčního centra pro kanály vzdálené služby Ředitelství informačních technologií MKB
Jako alternativu k ELK stacku (ElasticSearch, Logstash, Kibana) provádíme výzkum využití databáze ClickHouse jako úložiště dat pro protokoly.
V tomto článku bychom rádi hovořili o našich zkušenostech s používáním databáze ClickHouse a o předběžných výsledcích pilotního provozu. Je třeba hned poznamenat, že výsledky byly působivé.
Dále si podrobněji popíšeme, jak je náš systém nakonfigurován a z jakých komponent se skládá. Nyní bych ale rád pohovořil trochu o této databázi jako celku a proč stojí za to jí věnovat pozornost. Databáze ClickHouse je vysoce výkonná analytická sloupcová databáze od společnosti Yandex. Používá se ve službách Yandex, zpočátku je to hlavní úložiště dat pro Yandex.Metrica. Open-source systém, zdarma. Z pohledu vývojáře mě vždy zajímalo, jak to implementovali, protože jsou tam fantasticky velká data. A samotné uživatelské rozhraní Metricy je velmi flexibilní a rychlé. Při prvním seznámení s touto databází je dojem: „No konečně! Vyrobeno pro lidi! Počínaje procesem instalace a konče odesláním požadavků.
Tato databáze má velmi nízký vstupní práh. Tuto databázi zvládne nainstalovat i průměrně zdatný vývojář během pár minut a začít ji používat. Vše funguje přehledně. Dokonce i lidé, kteří jsou v Linuxu noví, zvládnou instalaci rychle a provedou ty nejjednodušší operace. Pokud dříve, se slovy Big Data, Hadoop, Google BigTable, HDFS, měl obyčejný vývojář představy, že jde o nějaké terabajty, petabajty, že se na nastavení a vývoji těchto systémů podílejí nějací nadlidé, pak s příchodem ClickHouse databáze, dostali jsme jednoduchý, srozumitelný nástroj, se kterým můžete řešit dříve nedosažitelné spektrum úkolů. Instalace trvá pouze jeden poměrně průměrný stroj a pět minut. To znamená, že jsme získali takovou databázi, jako je například MySql, ale pouze pro ukládání miliard záznamů! Jistý super-archivátor s jazykem SQL. Je to, jako by lidem byly předány zbraně mimozemšťanů.
O našem logovacím systému
Ke sběru informací se používají soubory protokolu IIS webových aplikací standardního formátu (v současné době také zpracováváme protokoly aplikací, ale hlavním cílem v pilotní fázi je shromažďovat protokoly IIS).
Z různých důvodů jsme nemohli úplně opustit ELK stack a nadále používáme komponenty LogStash a Filebeat, které se osvědčily a fungují celkem spolehlivě a předvídatelně.
Obecné schéma protokolování je znázorněno na obrázku níže:
Funkce zápisu dat do databáze ClickHouse je zřídka (jednou za sekundu) vkládání záznamů ve velkých dávkách. Toto je zjevně nejproblematičtější část, se kterou se setkáte, když poprvé zažijete práci s databází ClickHouse: schéma se trochu zkomplikuje.
Zde hodně pomohl plugin pro LogStash, který přímo vkládá data do ClickHouse. Tato komponenta je nasazena na stejném serveru jako samotná databáze. Obecně řečeno, nedoporučuje se to dělat, ale z praktického hlediska, aby se nevyráběly samostatné servery, když je nasazen na stejném serveru. Nezaznamenali jsme žádné selhání nebo konflikty zdrojů s databází. Kromě toho je třeba poznamenat, že plugin má mechanismus opakování v případě chyb. A v případě chyb plugin zapíše na disk dávku dat, která se nepodařilo vložit (formát souboru je pohodlný: po úpravě můžete snadno vložit opravenou dávku pomocí clickhouse-client).
Kompletní seznam softwaru použitého ve schématu je uveden v tabulce:
Seznam použitého softwaru
Jméno
popis
Distribuční odkaz
Nginx
Reverzní proxy pro omezení přístupu podle portů a organizaci autorizace
V současné době se ve schématu nepoužívá
FileBeat
Přenos protokolů souborů.
logstash
Sběratel kulatiny.
Používá se ke shromažďování protokolů z FileBeat a také ke shromažďování protokolů z fronty RabbitMQ (pro servery, které jsou v DMZ.)
Logstash-output-clickhouse
Zásuvný modul Loagstash pro přenos logů do databáze ClickHouse v dávkách
/usr/share/logstash/bin/logstash-plugin nainstalovat logstash-output-clickhouse
/usr/share/logstash/bin/logstash-plugin nainstalovat logstash-filter-prune
/usr/share/logstash/bin/logstash-plugin nainstalovat logstash-filter-multiline
clickhouse
Ukládání protokolů
Poznámka. Od srpna 2018 se v úložišti Yandex objevily „normální“ sestavení otáček za minutu pro RHEL, takže je můžete zkusit použít. V době instalace jsme používali balíčky vytvořené Altinity.
grafana
Vizualizace logu. Nastavení řídicích panelů
Redhat & Centos (64 Bit) - nejnovější verze
Zdroj dat ClickHouse pro Grafana 4.6+
Plugin pro Grafana se zdrojem dat ClickHouse
logstash
Log router z FileBeat do RabbitMQ fronty.
Poznámka. FileBeat bohužel nemá výstup přímo do RabbitMQ, takže je vyžadován mezilehlý odkaz ve formě Logstash
RabbitMQ
fronta zpráv. Toto je vyrovnávací paměť protokolu v DMZ
Erlang Runtime (vyžadováno pro RabbitMQ)
Runtime Erlang. Vyžadováno pro fungování RabbitMQ
Konfigurace serveru s databází ClickHouse je uvedena v následující tabulce:
Jméno
Hodnota
Poznámka
Konfigurace
HDD: 40GB
RAM: 8GB
Procesor: Core 2 2 GHz
Je třeba věnovat pozornost tipům pro obsluhu databáze ClickHouse (
Obecný systémový software
OS: Red Hat Enterprise Linux Server (Maipo)
JRE (Java 8)
Jak vidíte, jedná se o obyčejnou pracovní stanici.
Struktura tabulky pro ukládání protokolů je následující:
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;
Používáme výchozí rozdělení (podle měsíce) a granularitu indexu. Všechna pole prakticky odpovídají položkám protokolu IIS pro protokolování požadavků http. Samostatně si všimneme, že existují samostatná pole pro ukládání utm-tagů (jsou analyzovány ve fázi vkládání do tabulky z pole řetězce dotazu).
Do tabulky bylo také přidáno několik systémových polí pro ukládání informací o systémech, komponentách, serverech. Popis těchto polí naleznete v tabulce níže. V jedné tabulce ukládáme protokoly pro více systémů.
Jméno
popis
příklad
fld_app_name
Název aplikace/systému
Platné hodnoty:
- site1.domain.com Externí web 1
- site2.domain.com Externí web 2
- internal-site1.domain.local Interní web 1
site1.domena.com
fld_app_module
Systémový modul
Platné hodnoty:
- web - Web
- svc – služba webových stránek
- intgr - Integrační webová služba
- bo - správce (BackOffice)
web
fld_website_name
Název webu ve službě IIS
Na jednom serveru může být nasazeno několik systémů nebo dokonce několik instancí jednoho systémového modulu
hlavní web
název_fld_serveru
Název serveru
web1.domena.com
fld_log_file_name
Cesta k souboru protokolu na serveru
C:inetpublogsLogFiles
W3SVC1u_ex190711.log
To vám umožní efektivně vytvářet grafy v Grafaně. Například zobrazit požadavky z frontendu konkrétního systému. Je to podobné jako počítadlo stránek v Yandex.Metrica.
Zde je několik statistik o používání databáze za dva měsíce.
Počet záznamů v členění podle systémů a jejich součástí
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.)
Množství dat na disku
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.
Stupeň komprese dat ve sloupcích
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.
Popis použitých komponentů
FileBeat. Přenos protokolů souborů
Tato součást sleduje změny v souborech protokolu na disku a předává informace do LogStash. Instalováno na všech serverech, kde se zapisují soubory protokolu (obvykle IIS). Pracuje v režimu tail (tj. přenáší pouze přidané záznamy do souboru). Ale samostatně jej lze nakonfigurovat pro přenos celých souborů. To je užitečné, když potřebujete stáhnout data z předchozích měsíců. Stačí vložit soubor protokolu do složky a přečte jej celý.
Když je služba zastavena, data se již nepřenášejí dále do úložiště.
Příklad konfigurace vypadá takto:
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. Sběratel logů
Tato komponenta je navržena tak, aby přijímala položky protokolu z FileBeat (nebo prostřednictvím fronty RabbitMQ), analyzovala a vkládala dávky do databáze ClickHouse.
Pro vložení do ClickHouse se používá plugin Logstash-output-clickhouse. Plugin Logstash má mechanismus opakování požadavku, ale při pravidelném vypínání je lepší zastavit samotnou službu. Po zastavení se budou zprávy hromadit ve frontě RabbitMQ, takže pokud je zastavení na dlouhou dobu, je lepší zastavit Filebeats na serverech. Ve schématu, kde se nepoužívá RabbitMQ (v lokální síti Filebeat posílá logy přímo do Logstashe), Filebeats fungují celkem přijatelně a bezpečně, takže pro ně nedostupnost výstupu prochází bez následků.
Příklad konfigurace vypadá takto:
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"
}
}
}
potrubí.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. Ukládání protokolů
Logy pro všechny systémy jsou uloženy v jedné tabulce (viz na začátku článku). Je určen k ukládání informací o požadavcích: všechny parametry jsou podobné pro různé formáty, jako jsou protokoly IIS, protokoly Apache a nginx. Pro aplikační logy, do kterých se zaznamenávají např. chyby, informační zprávy, varování, bude k dispozici samostatná tabulka s příslušnou strukturou (aktuálně ve fázi návrhu).
Při návrhu tabulky je velmi důležité rozhodnout se pro primární klíč (podle kterého se budou data při ukládání třídit). Na tom závisí stupeň komprese dat a rychlost dotazu. V našem příkladu je klíč
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Tedy podle názvu systému, názvu systémové komponenty a data události. Zpočátku bylo na prvním místě datum akce. Po přesunutí na poslední místo začaly dotazy fungovat zhruba dvakrát rychleji. Změna primárního klíče bude vyžadovat opětovné vytvoření tabulky a opětovné načtení dat, aby ClickHouse znovu seřadil data na disku. Jedná se o náročnou operaci, takže je dobré hodně přemýšlet o tom, co by mělo obsahovat klíč řazení.
Je třeba také poznamenat, že datový typ LowCardinality se objevil v relativně nedávných verzích. Při jeho použití se velikost komprimovaných dat drasticky zmenší u těch polí, která mají nízkou mohutnost (málo možností).
Momentálně se používá verze 19.6 a plánujeme zkusit aktualizaci na nejnovější verzi. Mají tak skvělé funkce, jako je například adaptivní granularita, indexy přeskakování a kodek DoubleDelta.
Ve výchozím nastavení je během instalace úroveň protokolování nastavena na trasování. Logy se otáčejí a archivují, ale zároveň se roztahují až na gigabajt. Pokud to není potřeba, můžete nastavit úroveň varování, pak se velikost protokolu drasticky sníží. Nastavení protokolování se nastavuje v souboru config.xml:
<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger. h#L105 -->
<level>warning</level>
Některé užitečné příkazy
Поскольку оригинальные пакеты установки собираются по 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 z FileBeat do RabbitMQ fronty
Tato komponenta se používá ke směrování protokolů přicházejících z FileBeat do fronty RabbitMQ. Jsou zde dva body:
- FileBeat bohužel nemá výstupní plugin pro zápis přímo do RabbitMQ. A taková funkčnost, soudě podle problému na jejich githubu, není plánována k implementaci. Pro Kafku existuje plugin, ale z nějakého důvodu jej nemůžeme používat doma.
- Na sběr logů v DMZ jsou kladeny požadavky. Na jejich základě musí být logy nejprve přidány do fronty a poté LogStash čte záznamy z fronty zvenčí.
Proto je pro případ, kdy jsou servery umístěny v DMZ, použít takové trochu komplikované schéma. Příklad konfigurace vypadá takto:
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. fronta zpráv
Tato komponenta se používá k ukládání záznamů protokolu v DMZ. Nahrávání se provádí pomocí sady Filebeat → LogStash. Čtení se provádí zvenčí DMZ přes LogStash. Při provozu přes RabboitMQ se zpracovává asi 4 tisíce zpráv za sekundu.
Směrování zpráv je konfigurováno podle názvu systému, tj. na základě konfiguračních dat FileBeat. Všechny zprávy jdou do jedné fronty. Pokud je z nějakého důvodu služba řazení do fronty zastavena, nepovede to ke ztrátě zpráv: FileBeats obdrží chyby připojení a dočasně pozastaví odesílání. A LogStash, který čte z fronty, také obdrží chyby sítě a počká na obnovení připojení. V tomto případě se data samozřejmě již nebudou zapisovat do databáze.
K vytvoření a konfiguraci front se používají následující pokyny:
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. Řídicí panely
Tato komponenta se používá k vizualizaci monitorovacích dat. V tomto případě musíte nainstalovat zdroj dat ClickHouse pro plugin Grafana 4.6+. Museli jsme to trochu upravit, abychom zlepšili efektivitu zpracování SQL filtrů na dashboardu.
Například používáme proměnné, a pokud nejsou nastaveny v poli filtru, pak bychom chtěli, aby negenerovalo podmínku v WHERE formuláře ( uriStem = » AND uriStem != » ). V tomto případě bude ClickHouse číst sloupec uriStem. Obecně jsme zkoušeli různé možnosti a nakonec jsme plugin (makro $valueIfEmpty) opravili tak, aby v případě prázdné hodnoty vrátil 1, aniž bychom zmínili samotný sloupec.
A nyní můžete tento dotaz použít pro graf
$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')
což se překládá do tohoto SQL (všimněte si, že prázdná pole uriStem byla převedena pouze na 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
Závěr
Vzhled databáze ClickHouse se stal mezníkem na trhu. Bylo těžké si představit, že zcela zdarma jsme byli během okamžiku vyzbrojeni výkonným a praktickým nástrojem pro práci s velkými daty. Samozřejmě, s rostoucími potřebami (například sdílení a replikace na více serverů) bude schéma složitější. Na první dojmy je ale práce s touto databází velmi příjemná. Je vidět, že produkt je dělaný „pro lidi“.
Ve srovnání s ElasticSearch se odhaduje, že náklady na ukládání a zpracování protokolů se sníží pětkrát až desetkrát. Jinými slovy, pokud bychom pro aktuální objem dat museli nastavit cluster více strojů, tak nám při použití ClickHouse stačí jeden nízkopříkonový stroj. Ano, samozřejmě, ElasticSearch má také mechanismy pro kompresi dat na disku a další funkce, které mohou výrazně snížit spotřebu zdrojů, ale ve srovnání s ClickHouse to bude dražší.
Bez jakýchkoliv speciálních optimalizací z naší strany, ve výchozím nastavení funguje načítání dat a výběr z databáze úžasnou rychlostí. Zatím nemáme moc dat (asi 200 milionů záznamů), ale samotný server je slabý. Tento nástroj můžeme v budoucnu použít pro jiné účely, které nesouvisejí s ukládáním protokolů. Například pro end-to-end analytiku v oblasti bezpečnosti, strojového učení.
Na závěr něco málo o pro a proti.
Zápory
- Načítání záznamů ve velkých dávkách. Na jednu stranu je to funkce, ale stále musíte používat další komponenty pro ukládání záznamů do vyrovnávací paměti. Tento úkol není vždy snadný, ale přesto řešitelný. A rád bych schéma zjednodušil.
- Některé exotické funkce nebo nové funkce často v nových verzích přestanou fungovat. To vyvolává obavy a snižuje potřebu upgradovat na novou verzi. Například tabulkový engine Kafka je velmi užitečná funkce, která vám umožňuje přímo číst události z Kafky, bez implementace spotřebitelů. Ale soudě podle počtu Issues na githubu jsme stále opatrní, abychom tento engine nepoužili ve výrobě. Pokud však neděláte náhlá gesta do strany a používáte hlavní funkcionalitu, pak funguje stabilně.
Pros
- Nezpomaluje.
- Nízký vstupní práh.
- open source.
- Je to zdarma.
- Dobře se škáluje (sharding/replikace po vybalení)
- Zahrnuto v registru ruského softwaru doporučeného ministerstvem komunikací.
- Přítomnost oficiální podpory od společnosti Yandex.
Zdroj: www.habr.com