Aleksey Lizunov, hoofd van de competentiecentra voor afstandskanalen van de informatietechnologiesectie bij MKB

Als alternatief voor de ELK-stack (ElasticSearch, Logstash, Kibana) doen we onderzoek naar het gebruik van de ClickHouse-database als gegevensopslag voor logs.
In dit artikel willen we onze ervaringen met de ClickHouse-database delen en de voorlopige resultaten van de pilotfase bespreken. Het is belangrijk om meteen op te merken dat de resultaten indrukwekkend zijn.

Daarna zullen we in detail beschrijven hoe ons systeem is ingesteld en uit welke componenten het bestaat. Maar nu willen we eerst iets vertellen over deze database in het algemeen en waarom deze aandacht verdient. De ClickHouse-database is een zeer krachtige analytische kolom-database van Yandex. Het wordt gebruikt in de diensten van Yandex, oorspronkelijk als de belangrijkste gegevensopslag voor Yandex.Metrica. Het systeem is open-source en gratis. Vanuit ontwikkelaarsperspectief vond ik het altijd interessant om te zien hoe ze het hebben gerealiseerd, want ze werken met fantasieachtig grote gegevens. En de gebruikersinterface van Metrica is zeer flexibel en werkt snel. Bij de eerste kennismaking met deze database is de indruk: 'Eindelijk! Het is gemaakt
voor mensen'! Vanaf het installatieproces tot aan het versturen van verzoeken.
Over ons logs verzamelingssysteem
Voor het verzamelen van informatie worden logbestanden van IIS-webapplicaties in een standaardformaat gebruikt (we zijn momenteel ook bezig met het parseren van applicatielogs, maar het hoofddoel in de testfase is het verzamelen van IIS-logs).
We hebben om verschillende redenen niet volledig afscheid kunnen nemen van de ELK-stack, en we blijven de componenten LogStash en Filebeat gebruiken, die goed bewezen hebben en betrouwbaar en voorspelbaar werken.
Het algemene schema van loggen is weergegeven in de afbeelding hieronder:

Een kenmerk van het schrijven van gegevens naar de ClickHouse-database is de zeldzame (eens per seconde) invoeging van records in grote batches. Dit lijkt de 'probleematische' sectie te zijn waarmee je te maken krijgt bij de eerste ervaring met de ClickHouse-database: het schema wordt iets gecompliceerder.
Hier heeft de plugin voor LogStash een grote rol gespeeld, die gegevens rechtstreeks in ClickHouse invoegt. Deze component draait op dezelfde server als de database zelf. Dit wordt eigenlijk niet aanbevolen, maar vanuit praktisch oogpunt, om niet aparte servers te creΓ«ren, draait het momenteel op dezelfde server. We hebben geen storingen of resourceconflicten met de database waargenomen. Bovendien moet worden opgemerkt dat de plugin een retry-mechanisme biedt in geval van fouten. Bij fouten schrijft de plugin een batch gegevens, die niet konden worden ingevoegd, naar de schijf (het bestandsformaat is handig: na correctie kan de gecorrigeerde batch eenvoudig worden ingevoegd met behulp van clickhouse-client).
De volledige lijst van software die in het schema wordt gebruikt, is weergegeven in de tabel:
Lijst van gebruikte software
Naam
Omschrijving
Link naar de distributie
NGINX
Reverse-proxy voor het beperken van toegang via poorten en het organiseren van autorisatie
Momenteel niet gebruikt in het schema
FileBeat
Overdracht van logbestanden.
(distributie voor Windows 64bit).
LogStash
Logverzamelaar.
Wordt gebruikt om logs van FileBeat te verzamelen, evenals om logs uit de RabbitMQ-queue te verzamelen (voor servers die zich in de DMZ bevinden).
Logstash-output-clickhouse
Logstash-plugin voor het batchgewijs verzenden van logs naar de ClickHouse-database
/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
Logopslag
Opmerking. Sinds augustus 2018 zijn er 'normale' rpm-bundels in de Yandex-repository verschenen voor RHEL, dus het kan de moeite waard zijn om die te gebruiken. Op het moment van installatie gebruikten we pakketten die door Altinity waren samengesteld.
Grafana
Visualisatie van logs. Dashboardconfiguratie
Redhat & Centos (64 Bit) β de nieuwste versie
ClickHouse-datasource voor Grafana 4.6+
Plugin voor Grafana met ClickHouse-datasource
LogStash
Logrouter van FileBeat naar RabbitMQ-queue.
Let op. Helaas heeft FileBeat geen output rechtstreeks naar RabbitMQ, dus er is een tussenlink nodig in de vorm van Logstash.
RabbitMQ
Berichtenqueue. Dit is een buffer voor logrecords in de DMZ.
Erlang-runtime (Vereist voor RabbitMQ)
Erlang-runtime. Vereist voor de werking van RabbitMQ.
De serverconfiguratie met de ClickHouse-database wordt in de volgende tabel weergegeven:
Naam
Waarde
Opmerking
Configuratie
HDD: 40GB
RAM: 8GB
Processor: Core 2 2Ghz
Let op de gebruikstips voor de ClickHouse-database ()
Systeemsoftware
OS: Red Hat Enterprise Linux Server (Maipo)
JRE (Java 8)
Β
Zoals te zien is, is dit een gewone werkplek.
De tabelstructuur voor het opslaan van logs ziet er als volgt uit:
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;We gebruiken standaardinstellingen voor partitionering (per maand) en indexgranulariteit. Alle velden komen praktisch overeen met de logrecords van IIS voor registratie van http-verzoeken. We markeren afzonderlijke velden voor het opslaan van utm-labels (deze worden geparsed tijdens de invoeging in de tabel vanuit het vrageregelveld).
In de tabel zijn ook enkele systeemvelden toegevoegd voor het opslaan van informatie over systemen, componenten en servers. De beschrijving van deze velden staat hieronder in de tabel. In één tabel slaan we logs op van meerdere systemen.
Naam
Omschrijving
Voorbeeld
fld_app_name
Naam van de applicatie/systeem
Toegestane waarden:
- site1.domain.com Externe site 1
- site2.domain.com Externe site 2
- internal-site1.domain.local Interne site 1
site1.domain.com
fld_app_module
Systeemmodule
Toegestane waarden:
- web β Website
- svc β Webservice van de site
- intgr β Integratie-webservice
- bo β Admin (BackOffice)
web
fld_website_name
Naam van de website in IIS
Op één server kunnen meerdere systemen of zelfs meerdere exemplaren van één systeemmodule zijn uitgerold.
web-main
fld_server_name
Servernaam
web1.domain.com
fld_log_file_name
Pad naar het logbestand op de server
C:\inetpub\logs\LogFiles
W3SVC1u_ex190711.log
Dit stelt ons in staat om effectief grafieken in Grafana op te bouwen. Bijvoorbeeld, het bekijken van aanvragen vanaf de frontend van een specifiek systeem. Dit lijkt op een websitecounter in Yandex.Metrica.
Hier is enige statistiek over het gebruik van de database over een periode van twee maanden.
Aantal records opgedeeld naar systemen en hun componenten
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 β
ββββββββββββββββββββ΄βββββββββββββββββ΄βββββββββββββ
Totaal:
ββfld_app_nameββ¬βfld_app_moduleββ¬βrows_countββ
β β β 210522593 β
ββββββββββββββββ΄βββββββββββββββββ΄βββββββββββββ
11 rows in set. Elapsed: 4.874 sec. Processed 210.52 miljoen rows, 421.67 MB (43.19 miljoen rows/s., 86.51 MB/s.)Volume aan gegevens op de schijf
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.De mate van compressie van gegevens in de kolommen
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.Omschrijving van de gebruikte componenten
FileBeat. Bestanden logverzending
Deze component houdt wijzigingen in logbestanden op de schijf bij en verzendt informatie naar LogStash. Het wordt geΓ―nstalleerd op alle servers waar logbestanden worden geschreven (meestal IIS). Het werkt in tail-modus (dat wil zeggen, het verzendt alleen de toegevoegde Π·Π°ΠΏΠΈΡΠΈ naar het bestand). Maar het kan ook afzonderlijk worden ingesteld om gehele bestanden te verzenden. Dit is handig wanneer gegevens van voorgaande maanden moeten worden geladen. Leg simpelweg het logbestand in de map en het zal het volledige bestand zelf lezen.
Bij het stoppen van de service, stopt de doorgifte van gegevens naar de opslag.
Een voorbeeldconfiguratie ziet er als volgt uit:
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.nl"
fld_app_name: "site1.domain.nl"
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.nl"
fld_app_name: "site2.domain.nl"
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.nl.cer"
ssl.key: "C:/filebeat/certs/site1.domain.nl.key"
#================================ Processors =====================================
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~LogStash. Logverzamelaar
Dit component is bedoeld voor het ontvangen van logrecords van FileBeat (of via een RabbitMQ-queue), het parseren en het in batches invoegen in de ClickHouse-database.
Voor invoeging in ClickHouse wordt de Logstash-output-clickhouse-plugin gebruikt. Logstash heeft een mechanisme voor het opnieuw proberen van verzoeken, maar bij een normale stop, is het beter om de service daadwerkelijk te stoppen. Bij een stop zullen de berichten zich ophopen in de RabbitMQ-queue, dus als de stop voor langere tijd duurt, is het beter om de Filebeat-instanties op de servers te stoppen. In een schema waar RabbitMQ niet wordt gebruikt (Filebeat stuurt de logs direct naar Logstash in het lokale netwerk), functioneren de Filebeat-instanties goed en veilig, dus voor hen heeft een onderbreking van de output geen gevolgen.
Een voorbeeldconfiguratie ziet er als volgt uit:
log_web__filebeat_clickhouse.conf
invoer {
beats {
port => 5044
type => 'iis'
ssl => waar
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 => "wachtwoord"
queue => "web_log"
heartbeat => 30
durable => waar
ssl => waar
#ssl_certificate_path => "/etc/logstash/certs/server.p12"
#ssl_certificate_password => "wachtwoord"
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]}"
}
}
}
filt {
als [bericht] =~ "^#" {
drop {}
}
als [fld_logformat] == "logformat__iis_with_xrealip" {
grok {
match => ["bericht", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:methode} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMMER:port} %{NOTSPACE:gebruikersnaam} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMMER:response} %{NUMMER:subresponse} %{NUMMER:win32response} %{NUMMER:timetaken} %{NOTSPACE:xrealIP} %{NOTSPACE:xforwarderfor}"]
}
} anders {
grok {
match => ["bericht", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:methode} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMMER:port} %{NOTSPACE:gebruikersnaam} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMMER:response} %{NUMMER:subresponse} %{NUMMER:win32response} %{NUMMER:timetaken}"]
}
}
datum {
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'))"
}
als [bytesSent] {
ruby {
code => "event['kilobytesSent'] = event['bytesSent'].to_i / 1024.0"
}
}
als [bytesReceived] {
ruby {
code => "event['kilobytesReceived'] = event['bytesReceived'].to_i / 1024.0"
}
}
ruby {
code => "event.set('clientRealIP', event.get('clientIP'))"
}
als [xrealIP] {
ruby {
code => "event.set('clientRealIP', event.get('xrealIP'))"
}
}
als [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" => "," }
}
}
uitvoer {
#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"
"methode" => "method"
"uriStem" => "uriStem"
"uriQuery" => "uriQuery"
"port" => "port"
"gebruikersnaam" => "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. Log opslag
Logs van alle systemen worden in één tabel opgeslagen (zie het begin van het artikel). Deze tabel is bedoeld voor het opslaan van informatie over verzoeken: alle parameters zijn vergelijkbaar voor verschillende formaten, zoals IIS-logs, Apache- en Nginx-logs. Voor applicatielogs, waarin bijvoorbeeld fouten, informatieve berichten en waarschuwingen worden geregistreerd, zal een aparte tabel worden voorzien met de bijbehorende structuur (momenteel in ontwerpfase).
Bij het ontwerpen van de tabel is het erg belangrijk om te bepalen wat de primaire sleutel is (waarop de gegevens worden gesorteerd bij opslag). Dit beΓ―nvloedt de mate van compressie van de gegevens en de snelheid van de verzoeken. In ons voorbeeld is de sleutel
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Dat wil zeggen, op basis van de naam van het systeem, de naam van de systeemcomponent en de datum van het evenement. Oorspronkelijk stond de datum van het evenement op de eerste plaats. Na deze naar de laatste plaats te hebben verplaatst, werkten de verzoeken ongeveer twee keer sneller. Het wijzigen van de primaire sleutel vereist het opnieuw aanmaken van de tabel en het opnieuw laden van de gegevens, zodat ClickHouse de gegevens op de harde schijf opnieuw sorteert. Dit is een zware operatie, dus het is wenselijk om vroeg na te denken over wat in de sorteersleutel moet worden opgenomen.
Daarnaast moet worden opgemerkt dat er in de laatste versies een datatypen LowCardinality is toegevoegd. Bij gebruik hiervan wordt de grootte van de gecomprimeerde gegevens voor velden met lage cardinaliteit (weinig opties) aanzienlijk verminderd.
Momenteel gebruiken we versie 19.6 en we zijn van plan om de versie te upgraden naar de laatste. Deze versies bevatten geweldige functies zoals Adaptive Granularity, Skipping indices en de codec DoubleDelta, bijvoorbeeld.
Standaard wordt bij de installatie in de configuratie het logniveau 'trace' ingesteld. Logs worden geroteerd en gearchiveerd, maar worden uitgebreid tot een gigabyte. Als dit niet nodig is, kan het logniveau op 'warning' worden ingesteld, waardoor de loggrootte drastisch wordt verkleind. De logging-configuratie wordt ingesteld in het bestand config.xml:
<!-- Mogelijke niveaus: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger.h#L105 -->
<level>warning</level>Enkele nuttige commando's
Aangezien de oorspronkelijke installaties worden samengesteld op basis van Debian, moeten voor andere versies van Linux de pakketten worden gebruikt die door Altinity zijn samengesteld.
Hier is de link naar instructies met links naar hun repository: https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse
sudo yum search clickhouse-server
sudo yum install clickhouse-server.noarch
1. controleer de status
sudo systemctl status clickhouse-server
2. stop de server
sudo systemctl stop clickhouse-server
3. start de server
sudo systemctl start clickhouse-server
Starten voor het uitvoeren van aanvragen in meerdere regels (uitvoering na het teken ";")
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
De ClickHouse-plugin voor Logstash slaat bij een fout in één regel het hele pakket op in bestand /tmp/log_web_failed.json
Dit bestand kan handmatig worden gecorrigeerd en opnieuw in de database worden geΓ―mporteerd:
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
verlaat de commandoregel
quit;
## TLS-configuratie
https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2
openssl s_client -connect log.domain.com:9440 < /dev/nullLogStash. De logrouter van FileBeat naar de RabbitMQ-queue
Deze component wordt gebruikt voor de routering van logs die van FileBeat naar de RabbitMQ-queue komen. Hier zijn twee punten:
- Helaas heeft FileBeat geen output-plugin om rechtstreeks naar RabbitMQ te schrijven. En deze functionaliteit wordt, gelet op de issues op hun GitHub, niet gepland. Er is een plugin voor Kafka, maar om bepaalde redenen kunnen we deze hier niet gebruiken.
- Er zijn vereisten voor het verzamelen van logs in de DMZ. Op basis daarvan moeten logs eerst in de queue worden opgeslagen en vervolgens leest LogStash extern data uit de queue.
Daarom moeten we voor de situatie waarbij servers in de DMZ zijn geplaatst een iets complexer schema gebruiken. Een voorbeeldconfiguratie ziet er als volgt uit:
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. Berichtqueue
Deze component wordt gebruikt voor het bufferen van logrecords in de DMZ. De registratie vindt plaats via de combinatie van Filebeat β LogStash. Lezen gebeurt van buiten de DMZ via LogStash. Bij gebruik via RabbitMQ worden ongeveer 4000 berichten per seconde verwerkt.
Berichtroutering is ingesteld op basis van de systeemnaam, dat wil zeggen, op basis van gegevens uit de FileBeat-configuratie. Alle berichten komen in één queue terecht. Als om welke reden dan ook de queue-service wordt gestopt, heeft dit geen gevolgen voor de berichten: FileBeat zal verbindingsfouten ontvangen en tijdelijk de verzending stopzetten. LogStash, dat uit de queue leest, ontvangt ook netwerkfouten en wacht tot de verbinding hersteld is. In dat geval worden de gegevens natuurlijk niet meer in de database geschreven.
De volgende instructies worden gebruikt om queues te creΓ«ren en in te stellen:
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
Deze component wordt gebruikt voor het visualiseren van monitoringgegevens. Hiervoor moet de ClickHouse-datasource-plugin voor Grafana 4.6+ worden geΓ―nstalleerd. We moesten het een beetje aanpassen om de efficiΓ«ntie van de SQL-filterverwerking op het dashboard te verbeteren.
Bijvoorbeeld, we gebruiken variabelen, en als ze niet zijn ingesteld in het filterveld, willen we dat het geen voorwaarde in de WHERE genereert die eruitziet als (uriStem = Β» EN uriStem != Β»). In dat geval zal ClickHouse de kolom uriStem lezen. Over het algemeen hebben we verschillende opties geprobeerd en uiteindelijk de plugin aangepast (macro $valueIfEmpty) zodat hij bij een lege waarde 1 teruggeeft, zonder de kolom zelf te vermelden.
En nu kan een dergelijke query voor de grafiek worden gebruikt.
$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')dat wordt omgezet in de volgende SQL (let op dat lege velden uriStem eenvoudigweg zijn omgezet in 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 ASCConclusie
De verschijning van de ClickHouse-database was een belangrijk moment op de markt. Het was moeilijk voor te stellen dat we in een oogwenk een krachtige en praktische tool voor big data-verwerking volledig gratis ter beschikking hadden. Natuurlijk zal de structuur complexer worden naarmate de behoeften toenemen (bijvoorbeeld sharding en replicatie naar meerdere servers). Maar in eerste instantie is het zeer prettig om met deze database te werken. Het is duidelijk dat het product 'voor mensen' is gemaakt.
In vergelijking met ElasticSearch worden de kosten voor het opslaan en verwerken van logs naar schatting vijf tot tien keer verlaagd. Met andere woorden, als we voor de huidige hoeveelheid data een cluster van meerdere machines zouden moeten instellen, volstaat bij gebruik van ClickHouse één zwakke machine. Ja, ElasticSearch heeft ook mechanismen voor datacompressie op schijf en andere functies die het gebruik van bronnen aanzienlijk verlagen, maar vergeleken met ClickHouse vereist dit hogere kosten.
Zonder speciale optimalisaties van onze kant en met de standaardinstellingen, werkt het laden van gegevens en het ophalen uit de database met verbazingwekkende snelheid. We hebben voorlopig nog maar een kleine hoeveelheid data (ongeveer 200 miljoen records), maar de server is zwak. Deze tool kunnen we in de toekomst ook voor andere doeleinden gebruiken die niet met logopslag te maken hebben, zoals end-to-end analytics, beveiliging en machine learning.
Eindigend met een paar nadelen en voordelen.
Nadelen
- Het laden van records in grote batches. Enerzijds is dit een functie, maar het vereist toch extra componenten voor bufferisatie van records. Deze taak is niet altijd eenvoudig, maar nog steeds oplosbaar. En het zou fijn zijn om de structuur te vereenvoudigen.
- Sommige exotische functies of nieuwe features zijn vaak gebroken in nieuwe versies. Dit roept bezorgdheid op en vermindert de bereidheid om te upgraden naar de nieuwe versie. Bijvoorbeeld, de Kafka-tabelmotor is een zeer nuttige functie die het mogelijk maakt om evenementen direct uit Kafka te lezen, zonder het implementeren van consumenten. Maar gezien het aantal problemen op GitHub, zijn we nog steeds voorzichtig met het gebruik van deze motor in productie. Echter, als je geen drastische bewegingen maakt en de basisfunctionaliteit gebruikt, werkt het stabiel.
Voordelen
- Vertraagt niet.
- Lage instapdrempel.
- Open-source.
- Gratis.
- Schaalt goed (sharding/replicatie 'out of the box')
- Maakt deel uit van het register van Russische software, aanbevolen door het ministerie van Communicatie.
- OfficiΓ«le ondersteuning van Yandex.
Bron: habr.com
