Aleksey Lizunov, MKBko Informazio Teknologien Zuzendaritzako Urruneko Zerbitzu Kanaletarako Konpetentzia Zentroko burua.
ELK pila (ElasticSearch, Logstash, Kibana) alternatiba gisa, ClickHouse datu-basea erregistroetarako datu biltegi gisa erabiltzeko ikerketa egiten ari gara.
Artikulu honetan, ClickHouse datu-basea erabiltzeko dugun esperientziaz eta operazio pilotuaren aurretiazko emaitzei buruz hitz egin nahi dugu. Berehala esan behar da emaitzak ikusgarriak izan zirela.
Jarraian, gure sistema nola konfiguratuta dagoen eta zer osagaiz osatuta dagoen deskribatuko dugu zehatzago. Baina orain datu-base honi buruz apur bat hitz egin nahiko nuke bere osotasunean, eta zergatik merezi duen arreta jartzea. ClickHouse datu-basea Yandex-en errendimendu handiko zutabe-datu-base analitikoa da. Yandex zerbitzuetan erabiltzen da, hasieran Yandex.Metrica-ren datu biltegiratze nagusia da. Kode irekiko sistema, doakoa. Garatzaile baten ikuspuntutik, beti galdetu izan diot nola inplementatu zuten, datu izugarri handiak daudelako. Eta Metrica-ren erabiltzaile-interfazea bera oso malgua eta azkarra da. Datu-base hau lehen ezagutzean, inpresioa hauxe da: “Beno, azkenean! Herriarentzat egina! Instalazio prozesutik hasi eta eskaerak bidaltzen amaitu.
Datu-base honek sarrera-atalase oso baxua du. Batez besteko trebea den garatzaile batek ere datu-base hau instalatu dezake minutu gutxitan eta erabiltzen hasi. Dena argi eta garbi funtzionatzen du. Linux-en berriak diren pertsonek ere azkar kudeatu dezakete instalazioa eta eragiketa errazenak egin. Lehenago, Big Data, Hadoop, Google BigTable, HDFS hitzekin, garatzaile arrunt batek terabyte batzuei buruz, petabytei buruz, supergizaki batzuek sistema hauen ezarpenetan eta garapenean parte hartzen duten ideiak bazituen, orduan ClickHouse-ren etorrerarekin. datu-basea, tresna sinple eta ulergarri bat lortu dugu, zeinekin aurrez lortu ezin diren zeregin sorta bat ebazteko. Batez besteko makina bat eta bost minutu besterik ez dira behar instalatzeko. Hau da, adibidez, MySql bezalako datu-base bat lortu dugu, baina soilik milioika erregistro gordetzeko! SQL lengoaia duen super-artxibotzaile jakin bat. Jendeari atzerritarren armak eman zizkioten bezala da.
Gure erregistro-sistemari buruz
Informazioa biltzeko, formatu estandarreko web aplikazioen IIS erregistro-fitxategiak erabiltzen dira (gaur egun aplikazioen erregistroak aztertzen ari gara, baina fase pilotuan helburu nagusia IIS erregistroak biltzea da).
Hainbat arrazoirengatik, ezin izan dugu ELK pila erabat alde batera utzi, eta LogStash eta Filebeat osagaiak erabiltzen jarraitzen dugu, ondo frogatu duten eta nahiko fidagarri eta aurreikusteko funtzionatzen dutenak.
Erregistro-eskema orokorra beheko irudian ageri da:
ClickHouse datu-basean datuak idazteko ezaugarri bat sarritan (segundoko behin) erregistroak lote handietan sartzea da. Hau da, itxuraz, ClickHouse datu-basearekin lan egiten duzunean aurkitzen duzun zatirik "problematikoena": eskema pixka bat konplikatu egiten da.
ClickHouse-n datuak zuzenean txertatzen dituen LogStash-en pluginak asko lagundu zuen hemen. Osagai hau datu-basearen beraren zerbitzari berean zabaltzen da. Beraz, oro har, ez da gomendagarria egitea, ikuspuntu praktikotik baizik, zerbitzari berean hedatuta dagoen bitartean zerbitzari bereiziak ez sortzeko. Ez dugu datu-basearekin hutsegiterik edo baliabide-gatazkarik ikusi. Horrez gain, kontuan izan behar da pluginak akatsen kasuan berriro saiatzeko mekanismoa duela. Eta akatsen kasuan, pluginak txertatu ezin diren datu sorta bat idazten du diskoan (fitxategiaren formatua komeni da: editatu ondoren, erraz txertatu dezakezu zuzendutako sorta clickhouse-client erabiliz).
Eskeman erabilitako software-zerrenda osoa taulan aurkezten da:
Erabilitako software-zerrenda
Izena
Description
Banaketa esteka
nginx
Alderantzizko proxy portuen sarbidea mugatzeko eta baimena antolatzeko
Gaur egun ez da eskeman erabiltzen
FileBeat
Fitxategien erregistroen transferentzia.
logstash
Erregistro-biltzailea.
FileBeat-en erregistroak biltzeko erabiltzen da, baita RabbitMQ ilararen erregistroak biltzeko ere (DMZn dauden zerbitzarietarako).
Logstash-output-clickhouse
Loagstash plugina erregistroak ClickHouse datu-basera loteka transferitzeko
/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
Erregistro biltegiratzea
Ohar. 2018ko abuztutik aurrera, RHEL-erako rpm eraikitze "normalak" Yandex biltegian agertu ziren, haiek erabiltzen saia zaitezke. Instalazio garaian, Altinity-k eraikitako paketeak erabiltzen ari ginen.
Grafana
Erregistroen bistaratzea. Aginte-panelak konfiguratzea
Redhat & Centos (64 bit) - azken bertsioa
ClickHouse datu-iturria Grafana 4.6+erako
Grafanarako plugina ClickHouse datu-iturburuarekin
logstash
Erregistratu bideratzailea FileBeat-etik RabbitMQ ilarara.
Ohar. Zoritxarrez, FileBeat-ek ez du zuzenean ateratzen RabbitMQ-ra, beraz, Logstash moduko tarteko esteka bat behar da
RabbitMQ
mezu-ilara. Hau DMZko erregistro-buffera da
Erlang Runtime (Derrigorrezkoa RabbitMQ-rako)
Erlang exekuzioa. Beharrezkoa da RabbitMQ-k funtziona dezan
ClickHouse datu-basearekin zerbitzariaren konfigurazioa taula honetan aurkezten da:
Izena
Balio
Kontuan izan
konfigurazioa
Diskoa: 40 GB
RAM: 8GB
Prozesadorea: Core 2 2Ghz
ClickHouse datu-basea funtzionatzeko aholkuei erreparatu behar zaie (
Sistema orokorraren softwarea
OS: Red Hat Enterprise Linux Server (Maipo)
JRE (Java 8)
Ikus dezakezunez, lan-estazio arrunt bat da.
Erregistroak gordetzeko taularen egitura honakoa da:
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;
Partizio lehenetsia (hilabeteka) eta indizearen granulartasuna erabiltzen ditugu. Eremu guztiak ia IIS erregistroko sarrerei dagozkie http eskaerak erregistratzeko. Bereiz, ohartzen gara utm-tags gordetzeko eremu bereiziak daudela (kontsulta-katearen eremutik taulan txertatzeko fasean analizatzen dira).
Era berean, sistemaren hainbat eremu gehitu dira taulara sistemei, osagaiei, zerbitzariei buruzko informazioa gordetzeko. Ikus beheko taula eremu hauen deskribapena lortzeko. Taula batean, hainbat sistemaren erregistroak gordetzen ditugu.
Izena
Description
Adibidea
fld_app_izena
Aplikazio/sistemaren izena
Baliozko balioak:
- site1.domain.com Kanpoko gunea 1
- site2.domain.com Kanpoko gunea 2
- barne-gunea1.domeinua.local Barne-gunea 1
gune1.domeinua.com
fld_app_module
Sistemaren modulua
Baliozko balioak:
- web - Webgunea
- svc - Webgunearen zerbitzua
- intgr - Integrazio Web Zerbitzua
- bo - Administratzailea (BackOffice)
web
fld_webgune_izena
Gunearen izena IISen
Hainbat sistema inplementa daitezke zerbitzari batean, edo baita sistema modulu bateko hainbat instantzia ere
web nagusia
fld_zerbitzari_izena
Zerbitzariaren izena
web1.domeinua.com
fld_log_file_name
Zerbitzariko erregistro-fitxategirako bidea
C:inetpublogsLogFiles
W3SVC1u_ex190711.log
Horri esker, grafikoak eraginkortasunez eraiki ditzakezu Grafanan. Adibidez, ikusi sistema jakin baten frontend-eko eskaerak. Yandex.Metrica-ko gune-kontagailuaren antzekoa da.
Hona hemen bi hilabetez datu-basearen erabilerari buruzko estatistika batzuk.
Sistemen eta haien osagaien arabera banatutako erregistro kopurua
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.)
Diskoan dagoen datu kopurua
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.
Datuen konpresio-maila zutabeetan
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.
Erabilitako osagaien deskribapena
FileBeat. Fitxategien erregistroak transferitzea
Osagai honek erregistro-fitxategien aldaketen jarraipena egiten du diskoan eta informazioa LogStash-era pasatzen du. Erregistro fitxategiak idazten diren zerbitzari guztietan instalatuta (normalean IIS). Buztan moduan funtzionatzen du (hau da, gehitutako erregistroak fitxategira soilik transferitzen ditu). Baina bereizita fitxategi osoak transferitzeko konfigura daiteke. Hau erabilgarria da aurreko hilabeteetako datuak deskargatu behar dituzunean. Jarri erregistro-fitxategia karpeta batean eta osorik irakurriko du.
Zerbitzua gelditzen denean, datuak ez dira gehiago biltegiratzera transferitzen.
Konfigurazio adibide bat honelakoa da:
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. Erregistro-biltzailea
Osagai hau FileBeat-etik (edo RabbitMQ ilararen bidez) erregistro-sarrerak jasotzeko diseinatuta dago, ClickHouse datu-basean loteak analizatuz eta txertatuz.
ClickHousen txertatzeko, Logstash-output-clickhouse plugina erabiltzen da. Logstash pluginak eskaera berriro saiatzeko mekanismoa du, baina ohiko itzaliarekin, hobe da zerbitzua bera geldiaraztea. Gelditzen denean, mezuak RabbitMQ ilaran pilatuko dira, beraz, geldialdia denbora luzez bada, hobe da Filebeats-ek zerbitzarietan gelditzea. RabbitMQ erabiltzen ez den eskema batean (sare lokalean, Filebeat-ek zuzenean Logstash-era bidaltzen ditu erregistroak), Filebeats-ek nahiko onargarri eta seguru funtzionatzen du, beraz, beraientzat irteeraren erabilgarritasunik eza ondoriorik gabe pasatzen da.
Konfigurazio adibide bat honelakoa da:
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"
}
}
}
hodiak.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. Erregistro biltegiratzea
Sistema guztien erregistroak taula batean gordetzen dira (ikus artikuluaren hasieran). Eskaerei buruzko informazioa gordetzeko xedea da: parametro guztiak antzekoak dira formatu desberdinetarako, hala nola IIS erregistroak, apache eta nginx erregistroak. Aplikazioen erregistroetarako, zeinetan, adibidez, akatsak, informazio-mezuak, abisuak erregistratzen diren, egitura egokia duen taula bereizi bat emango da (gaur egun diseinu-fasean).
Taula bat diseinatzerakoan, oso garrantzitsua da gako nagusia erabakitzea (horren bidez ordenatuko dira datuak biltegiratzean). Datuen konpresio-maila eta kontsulta-abiadura horren araberakoak dira. Gure adibidean, gakoa da
ORDENATU (fld_app_name, fld_app_module, logdatetime)
Hau da, sistemaren izenaren, sistemaren osagaiaren izenaren eta gertaeraren dataren arabera. Hasieran, ekitaldiaren data izan zen lehenengo. Azken tokira eraman ondoren, kontsultak bi aldiz azkarrago hasi ziren lanean. Gako nagusia aldatzeko, taula birsortu eta datuak berriro kargatu beharko dira, ClickHouse-k datuak diskoan berriro ordenatu ditzan. Eragiketa astuna da, beraz, ideia ona da ordenatzeko gakoan zer sartu behar den asko pentsatzea.
Kontuan izan behar da, gainera, LowCardinality datu-mota nahiko agertu dela azken bertsioetan. Erabiltzean, konprimitutako datuen tamaina izugarri murrizten da kardinaltasun txikia duten eremuetarako (aukera gutxi).
19.6 bertsioa erabiltzen ari da eta azken bertsiora eguneratzen saiatzeko asmoa dugu. Ezaugarri zoragarriak dituzte, esaterako, Adaptive Granularity, Skipping indexes eta DoubleDelta codec-a, adibidez.
Lehenespenez, instalazioan zehar, erregistro-maila trazatzeko ezartzen da. Erregistroak biratu eta artxibatu egiten dira, baina aldi berean gigabyte batera hedatzen dira. Beharrik ez badago, abisu-maila ezar dezakezu, orduan erregistroaren tamaina ikaragarri murriztuko da. Erregistroaren ezarpena config.xml fitxategian ezartzen da:
<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger. h#L105 -->
<level>warning</level>
Komando erabilgarria batzuk
Поскольку оригинальные пакеты установки собираются по 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. Erregistratu bideratzailea FileBeat-etik RabbitMQ ilarara
Osagai hau FileBeat-etik datozen erregistroak RabbitMQ ilara bideratzeko erabiltzen da. Hemen bi puntu daude:
- Zoritxarrez, FileBeat-ek ez du irteerako pluginik RabbitMQ-ra zuzenean idazteko. Eta funtzionaltasun hori, beren github-eko arazoaren arabera, ez dago inplementatzeko aurreikusita. Kafkarako plugin bat dago, baina arrazoiren batengatik ezin dugu etxean erabili.
- DMZn erregistroak biltzeko baldintzak daude. Horietan oinarrituta, erregistroak ilarara gehitu behar dira lehenik eta, ondoren, LogStash-ek ilarako sarrerak kanpotik irakurtzen ditu.
Hori dela eta, zerbitzariak DMZn kokatuta dauden kasuetarako da halako eskema apur bat konplikatua erabili behar dela. Konfigurazio adibide bat honelakoa da:
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. mezu-ilara
Osagai hau DMZko erregistro-sarrerak gordetzeko erabiltzen da. Grabaketa Filebeat → LogStash multzo baten bidez egiten da. Irakurketa DMZ kanpotik egiten da LogStash bidez. RabboitMQ bidez jarduten denean, segundoko 4 mila mezu inguru prozesatzen dira.
Mezuen bideratzea sistemaren izenaren arabera konfiguratzen da, hau da, FileBeat-en konfigurazio-datuetan oinarrituta. Mezu guztiak ilara batera joaten dira. Arrazoiren batengatik ilaran zerbitzua gelditzen bada, horrek ez du mezuak galtzea ekarriko: FileBeats-ek konexio akatsak jasoko ditu eta bidalketa aldi baterako etengo du. Eta ilaratik irakurtzen duen LogStash-ek sareko akatsak ere jasoko ditu eta konexioa leheneratu arte itxarongo du. Kasu honetan, datuak, noski, ez dira gehiago datu-basean idatziko.
Ilarak sortzeko eta konfiguratzeko jarraibide hauek erabiltzen dira:
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. Aginte-panelak
Osagai hau monitorizazio datuak ikusteko erabiltzen da. Kasu honetan, Grafana 4.6+ pluginerako ClickHouse datu-iturria instalatu behar duzu. Apur bat moldatu behar izan dugu aginte-paneleko SQL iragazkiak prozesatzeko eraginkortasuna hobetzeko.
Esaterako, aldagaiak erabiltzen ditugu, eta iragazkien eremuan ezartzen ez badira, nahi genuke baldintzarik ez sortzea formularioko NON-AN ( uriStem = » ETA uriStem != » ). Kasu honetan, ClickHousek uriStem zutabea irakurriko du. Oro har, aukera desberdinak probatu ditugu eta azkenean plugina ($valueIfEmpty makroa) zuzendu dugu, hutsik dagoen balio baten kasuan 1 itzultzeko, zutabea bera aipatu gabe.
Eta orain kontsulta hau erabil dezakezu grafikorako
$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')
SQL honetara itzultzen dena (kontuan izan uriStem eremu hutsak 1era soilik bihurtu direla)
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
Ondorioa
ClickHouse datu-basearen agerpena merkatuan mugarri bihurtu da. Zaila zen imajinatzea, guztiz dohainik, istant batean big data-ekin lan egiteko tresna indartsu eta praktiko batekin armatuta geundela. Jakina, beharrak gero eta handiagoak direnez (adibidez, zatiketa eta zerbitzari anitzetan erreplikatzea), eskema zailagoa izango da. Baina lehen inpresioetan, datu-base honekin lan egitea oso atsegina da. Produktua "pertsonentzako" egina dagoela ikus daiteke.
ElasticSearch-ekin alderatuta, erregistroak gordetzeko eta prozesatzeko kostua bost edo hamar aldiz murriztuko dela kalkulatzen da. Beste era batera esanda, uneko datu kopururako hainbat makina multzo bat konfiguratu beharko bagenu, ClickHouse erabiltzean, potentzia baxuko makina bat nahikoa da guretzat. Bai, noski, ElasticSearch-ek ere baditu diskoan datuak konprimitzeko mekanismoak eta baliabideen kontsumoa nabarmen murrizteko beste ezaugarri batzuk, baina ClickHouse-rekin alderatuta, hori garestiagoa izango da.
Gure aldetik optimizazio berezirik gabe, ezarpen lehenetsietan, datuak kargatu eta datu-basetik aukeratzeak abiadura harrigarrian funtzionatzen du. Oraindik ez dugu datu askorik (200 milioi erregistro inguru), baina zerbitzaria bera ahula da. Etorkizunean tresna hau erregistroak gordetzearekin zerikusia ez duten beste helburu batzuetarako erabil dezakegu. Adibidez, muturreko analisirako, segurtasunaren arloan, ikaskuntza automatikoa.
Bukaeran, alde onak eta txarrak buruz pixka bat.
Cons
- Erregistroak lote handietan kargatzen. Alde batetik, ezaugarri bat da, baina oraindik osagai osagarriak erabili behar dituzu erregistroak buffererako. Zeregin hau ez da beti erraza, baina oraindik konpon daiteke. Eta eskema sinplifikatu nahiko nuke.
- Funtzionalitate exotiko batzuk edo eginbide berri batzuk askotan hautsi egiten dira bertsio berrietan. Horrek kezka eragiten du, bertsio berri batera eguneratzeko gogoa murrizten du. Adibidez, Kafka taula-motorra oso funtzio erabilgarria da, Kafka-ren gertaerak zuzenean irakurtzeko aukera ematen duena, kontsumitzaileak ezarri gabe. Baina github-eko Arazo kopuruaren arabera, oraindik kontuz ibiltzen gara motor hau ekoizpenean ez erabiltzeko. Hala ere, alborako bat-bateko keinurik egiten ez baduzu eta funtzionalitate nagusia erabiltzen ez baduzu, egonkor funtzionatzen du.
Pros
- Ez du moteltzen.
- Sarrera atalase baxua.
- Kode irekia.
- Doan.
- Ondo eskalatzen da (zatiketa/erreplikatzea kutxatik kanpo)
- Komunikazio Ministerioak gomendatutako Errusiako softwarearen erregistroan sartuta dago.
- Yandex-en laguntza ofizialaren presentzia.
Iturria: www.habr.com