ClickHouse Database for Humans ehk tulnukate tehnoloogiad

Aleksei Lizunov, MKB infotehnoloogia direktoraadi kaugteeninduskanalite kompetentsikeskuse juhataja

ClickHouse Database for Humans ehk tulnukate tehnoloogiad

Alternatiivina ELK virnale (ElasticSearch, Logstash, Kibana) teeme uuringuid ClickHouse andmebaasi kasutamise kohta logide andmehoidlana.

Selles artiklis räägime oma ClickHouse'i andmebaasi kasutamise kogemusest ja pilootoperatsiooni esialgsetest tulemustest. Tuleb kohe märkida, et tulemused olid muljetavaldavad.


ClickHouse Database for Humans ehk tulnukate tehnoloogiad

Järgmisena kirjeldame üksikasjalikumalt, kuidas meie süsteem on konfigureeritud ja millistest komponentidest see koosneb. Aga nüüd räägiksin veidi sellest andmebaasist kui tervikust ja sellest, miks tasub sellele tähelepanu pöörata. ClickHouse'i andmebaas on Yandexi suure jõudlusega analüütiline veergude andmebaas. Seda kasutatakse Yandexi teenustes, esialgu on see Yandex.Metrica peamine andmesalvestus. Avatud lähtekoodiga süsteem, tasuta. Arendaja vaatevinklist olen alati mõelnud, kuidas nad seda rakendasid, sest seal on fantastiliselt suured andmed. Ja Metrica kasutajaliides ise on väga paindlik ja kiire. Esimesel tutvumisel selle andmebaasiga jääb mulje: “No lõpuks ometi! Inimeste jaoks loodud! Alustades installiprotsessist ja lõpetades päringute saatmisega.

Sellel andmebaasil on väga madal sisenemislävi. Isegi keskmise kvalifikatsiooniga arendaja suudab selle andmebaasi mõne minutiga installida ja kasutama hakata. Kõik toimib selgelt. Isegi inimesed, kes pole Linuxit kasutanud, saavad installimisega kiiresti hakkama ja teha lihtsamaid toiminguid. Kui varem, sõnadega Big Data, Hadoop, Google BigTable, HDFS, tekkis tavalisel arendajal ideid, et jutt käib mõnest terabaidist, petabaidist, et mingid üliinimesed tegelevad nende süsteemide seadistamise ja arendusega, siis ClickHouse’i tulekuga. andmebaasi, saime lihtsa ja arusaadava tööriista, mille abil saate lahendada seni saavutamatuid ülesandeid. Selle paigaldamiseks kulub vaid üks üsna keskmine masin ja viis minutit. See tähendab, et saime sellise andmebaasi nagu näiteks MySql, kuid ainult miljardite kirjete salvestamiseks! Teatud super-arhiveerija SQL-keelega. See on nagu inimestele ulatatud tulnukate relvad.

Meie logimissüsteemi kohta

Info kogumiseks kasutatakse standardvormingus veebirakenduste IIS-i logifaile (praegu parsitakse ka rakenduste logisid, kuid pilootfaasis on põhieesmärk koguda IIS-i logisid).

Erinevatel põhjustel ei saanud me ELK stäkist täielikult loobuda ning kasutame jätkuvalt LogStash ja Filebeat komponente, mis on end hästi tõestanud ning töötavad üsna usaldusväärselt ja etteaimatavalt.

Üldine logimisskeem on näidatud alloleval joonisel:

ClickHouse Database for Humans ehk tulnukate tehnoloogiad

Andmete ClickHouse'i andmebaasi kirjutamise funktsioon on kirjete harva (üks kord sekundis) sisestamine suurte partiidena. Ilmselt on see kõige "probleemsem" osa, millega kohtate esimest korda ClickHouse'i andmebaasiga töötades: skeem muutub veidi keerulisemaks.
Siin aitas palju kaasa LogStashi pistikprogramm, mis sisestab andmed otse ClickHouse'i. See komponent on juurutatud andmebaasiga samas serveris. Nii et üldiselt ei soovita seda teha, vaid praktilisest vaatenurgast, et mitte toota eraldi servereid, kui see on samas serveris juurutatud. Me ei täheldanud andmebaasiga tõrkeid ega ressursside konflikte. Lisaks tuleb märkida, et pistikprogrammil on vigade korral uuesti proovimise mehhanism. Ja vigade korral kirjutab pistikprogramm kettale hulga andmeid, mida ei saanud sisestada (failivorming on mugav: pärast redigeerimist saate parandatud partii hõlpsasti sisestada, kasutades nuppu Clickhouse-client).

Skeemis kasutatud tarkvara täielik loetelu on esitatud tabelis:

Kasutatud tarkvara nimekiri

nimi

Kirjeldus

Levitamise link

nginx

Pöördpuhverserver, et piirata juurdepääsu portidele ja korraldada autoriseerimist

Hetkel skeemis ei kasutata

https://nginx.org/ru/download.html

https://nginx.org/download/nginx-1.16.0.tar.gz

FileBeat

Faililogide edastamine.

https://www.elastic.co/downloads/beats/filebeat (levikomplekt Windows 64bit jaoks).

https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.3.0-windows-x86_64.zip

logstash

Palgikoguja.

Kasutatakse FileBeati logide kogumiseks, samuti logide kogumiseks RabbitMQ järjekorrast (DMZ-s olevate serverite jaoks).

https://www.elastic.co/products/logstash

https://artifacts.elastic.co/downloads/logstash/logstash-7.0.1.rpm

Logstash-output-clickhouse

Loagstash plugin logide edastamiseks ClickHouse'i andmebaasi partiidena

https://github.com/mikechris/logstash-output-clickhouse

/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

Klõpsake nuppu Maja

Palkide ladustamine https://clickhouse.yandex/docs/ru/

https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-19.5.3.8-1.el7.x86_64.rpm

https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-client-19.5.3.8-1.el7.x86_64.rpm

Märge. Alates 2018. aasta augustist ilmusid Yandexi hoidlasse RHELi "tavalised" pöörete minutis versioonid, nii et võite proovida neid kasutada. Paigaldamise ajal kasutasime Altinity loodud pakette.

grafana

Logi visualiseerimine. Armatuurlaudade seadistamine

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64-bitine) – uusim versioon

ClickHouse'i andmeallikas Grafana 4.6+ jaoks

Grafana plugin koos ClickHouse'i andmeallikaga

https://grafana.com/plugins/vertamedia-clickhouse-datasource

https://grafana.com/api/plugins/vertamedia-clickhouse-datasource/versions/1.8.1/download

logstash

Logi ruuter FileBeatist RabbitMQ järjekorda.

Märge. Kahjuks ei väljasta FileBeat otse RabbitMQ-le, seega on vaja vahelinki Logstashi kujul

https://www.elastic.co/products/logstash

https://artifacts.elastic.co/downloads/logstash/logstash-7.0.1.rpm

JänesMQ

sõnumite järjekord. See on DMZ logipuhver

https://www.rabbitmq.com/download.html

https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.14/rabbitmq-server-3.7.14-1.el7.noarch.rpm

Erlangi käitusaeg (nõutav RabbitMQ jaoks)

Erlangi käitusaeg. RabbitMQ töötamiseks on vajalik

http://www.erlang.org/download.html

https://www.rabbitmq.com/install-rpm.html#install-erlang http://www.erlang.org/downloads/21.3

Serveri konfiguratsioon ClickHouse'i andmebaasiga on esitatud järgmises tabelis:

nimi

Väärtus

Märkus

Konfiguratsioon

HDD: 40 GB
RAM: 8GB
Protsessor: Core 2 2GHz

Tähelepanu tuleb pöörata ClickHouse'i andmebaasi käitamise näpunäidetele (https://clickhouse.yandex/docs/ru/operations/tips/)

Üldine süsteemitarkvara

OS: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Nagu näete, on see tavaline tööjaam.

Palkide salvestamise tabeli struktuur on järgmine:

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;

Kasutame vaikepartitsioneerimist (kuu järgi) ja indeksi detailsust. Kõik väljad vastavad praktiliselt IIS-i logikirjetele http-päringute logimiseks. Eraldi märgime, et utm-siltide salvestamiseks on eraldi väljad (need sõelutakse päringustringi väljalt tabelisse sisestamise etapis).

Samuti on tabelisse lisatud mitmed süsteemiväljad, mis salvestavad teavet süsteemide, komponentide, serverite kohta. Nende väljade kirjelduse leiate allolevast tabelist. Ühte tabelisse salvestame mitme süsteemi logid.

nimi

Kirjeldus

Näide

fld_app_name

Rakenduse/süsteemi nimi
Kehtivad väärtused:

  • site1.domain.com Väline sait 1
  • site2.domain.com Väline sait 2
  • sisemine-sait1.domain.local 1. sisesait

sait1.domain.com

fld_app_module

Süsteemi moodul
Kehtivad väärtused:

  • veeb – veebisait
  • svc – veebisaidi teenus
  • intgr – integratsiooni veebiteenus
  • bo – administraator (BackOffice)

web

fld_website_name

Saidi nimi IIS-is

Ühes serveris saab juurutada mitut süsteemi või isegi ühe süsteemimooduli mitu eksemplari

veebi põhi

fld_serveri_nimi

Serveri nimi

web1.domain.com

fld_log_file_name

Serveris oleva logifaili tee

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

See võimaldab teil Grafanas tõhusalt graafikuid koostada. Näiteks vaadata päringuid konkreetse süsteemi esiservast. See sarnaneb saidi loenduriga Yandex.Metricas.

Siin on veidi statistikat andmebaasi kasutamise kohta kahe kuu jooksul.

Kirjete arv süsteemide ja nende komponentide lõikes

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.)

Ketta andmete hulk

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.

Andmete tihendamise aste veergudes

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.

Kasutatud komponentide kirjeldus

FileBeat. Faililogide ülekandmine

See komponent jälgib kettal olevate logifailide muudatusi ja edastab teabe LogStashile. Installitud kõikidesse serveritesse, kuhu logifaile kirjutatakse (tavaliselt IIS). Töötab sabarežiimis (st kannab faili ainult lisatud kirjed). Kuid eraldi saab seda konfigureerida tervete failide ülekandmiseks. See on kasulik, kui peate alla laadima eelmiste kuude andmeid. Lihtsalt pange logifail kausta ja see loeb selle tervikuna.

Kui teenus on peatatud, ei edastata andmeid enam salvestusruumi.

Konfiguratsiooni näide näeb välja selline:

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. Palgikoguja

See komponent on loodud FileBeati (või RabbitMQ järjekorra kaudu) logikirjete vastuvõtmiseks, partiide parsimiseks ja sisestamiseks ClickHouse'i andmebaasi.

ClickHouse'i sisestamiseks kasutatakse pluginat Logstash-output-clickhouse. Logstashi pistikprogrammil on uuesti proovimise mehhanism, kuid tavalise väljalülitamise korral on parem teenus ise peatada. Peatamisel kogunevad sõnumid RabbitMQ järjekorda, nii et kui peatus on pikka aega, on parem Filebeats serverites peatada. Skeemis, kus RabbitMQ-d ei kasutata (kohalikus võrgus saadab Filebeat logid otse Logstashi), töötab Filebeats üsna vastuvõetavalt ja turvaliselt, nii et nende jaoks möödub väljundi kättesaamatus tagajärgedeta.

Konfiguratsiooni näide näeb välja selline:

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"
        }
    }
 
}

torujuhtmed.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. Palkide ladustamine

Kõigi süsteemide logid on salvestatud ühte tabelisse (vt artikli alguses). See on mõeldud päringute teabe salvestamiseks: kõik parameetrid on erinevate vormingute jaoks sarnased, nagu IIS-i logid, apache ja nginxi logid. Rakenduste logide jaoks, kuhu on salvestatud näiteks vead, infoteated, hoiatused, antakse vastava struktuuriga eraldi tabel (praegu projekteerimise staadiumis).

Tabeli kujundamisel on väga oluline otsustada primaarvõtme üle (mille järgi andmed salvestamise ajal sorteeritakse). Sellest sõltub andmete tihendamise aste ja päringu kiirus. Meie näites on võti
ORDER (TELLIMISE) (fld_app_name, fld_app_module, logdatetime)
See tähendab süsteemi nime, süsteemikomponendi nime ja sündmuse kuupäeva järgi. Esialgu oli sündmuse kuupäev esikohal. Pärast selle viimasele kohale viimist hakkasid päringud töötama umbes kaks korda kiiremini. Primaarvõtme muutmiseks tuleb tabel uuesti luua ja andmed uuesti laadida, nii et ClickHouse sorteerib kettal olevad andmed ümber. See on raske toiming, seega on hea mõte palju mõelda, mida sortimisvõtmesse lisada.

Samuti tuleb märkida, et LowCardinality andmetüüp on ilmunud suhteliselt viimastes versioonides. Selle kasutamisel väheneb tihendatud andmete maht drastiliselt nende väljade puhul, millel on madal kardinaalsus (vähe valikuid).

Praegu on kasutusel versioon 19.6 ja kavatseme proovida värskendada uusimale versioonile. Neil on näiteks sellised imelised funktsioonid nagu Adaptive Granularity, Skipping indeksid ja DoubleDelta koodek.

Vaikimisi on installimise ajal logimise tase määratud jälgimiseks. Logisid pööratakse ja arhiveeritakse, kuid samal ajal laienevad need kuni gigabaidini. Kui pole vajadust, saate seada hoiatustaseme, siis väheneb palgi suurus drastiliselt. Logimise säte on määratud failis config.xml:

<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger. h#L105 -->
<level>warning</level>

Mõned kasulikud käsud

Поскольку оригинальные пакеты установки собираются по 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. Logi ruuter FileBeatist RabbitMQ järjekorda

Seda komponenti kasutatakse FileBeatist tulevate logide suunamiseks RabbitMQ järjekorda. Siin on kaks punkti:

  1. Kahjuks pole FileBeatil väljundpluginat, mida saaks otse RabbitMQ-sse kirjutada. Ja sellist funktsionaalsust, otsustades nende githubis oleva probleemi põhjal, ei plaanita juurutada. Kafka jaoks on plugin olemas, kuid millegipärast ei saa me seda kodus kasutada.
  2. DMZ-s on logide kogumise nõuded. Nende põhjal tuleb esmalt logid järjekorda lisada ning seejärel loeb LogStash väljastpoolt järjekorras olevad kirjed.

Seetõttu tuleb sellist veidi keerulist skeemi kasutada juhul, kui serverid asuvad DMZ-s. Konfiguratsiooni näide näeb välja selline:

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. sõnumite järjekord

Seda komponenti kasutatakse logikirjete puhverdamiseks DMZ-s. Salvestamine toimub läbi hulga Filebeat → LogStash. Lugemine toimub väljastpoolt DMZ-d LogStashi kaudu. RabboitMQ kaudu töötades töödeldakse umbes 4 tuhat sõnumit sekundis.

Sõnumite suunamine on konfigureeritud süsteemi nime järgi, st FileBeati konfiguratsiooniandmete põhjal. Kõik kirjad lähevad ühte järjekorda. Kui järjekorrateenus mingil põhjusel peatatakse, ei too see kaasa sõnumite kadumist: FileBeats saab ühenduse vead ja peatab ajutiselt saatmise. Ja järjekorrast lugev LogStash saab ka võrguvead ja ootab ühenduse taastamist. Sel juhul andmeid loomulikult enam andmebaasi ei kirjutata.

Järjekordade loomiseks ja konfigureerimiseks kasutatakse järgmisi juhiseid.

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. Armatuurlauad

Seda komponenti kasutatakse seireandmete visualiseerimiseks. Sel juhul peate Grafana 4.6+ pistikprogrammi jaoks installima ClickHouse'i andmeallika. Pidime seda natuke kohandama, et parandada armatuurlaual SQL-filtrite töötlemise tõhusust.

Näiteks kasutame muutujaid ja kui need pole filtriväljal määratud, siis soovime, et see ei genereeriks vormi WHERE tingimust ( uriStem = » AND uriStem != » ). Sel juhul loeb ClickHouse veergu uriStem. Üldiselt proovisime erinevaid võimalusi ja lõpuks parandasime pistikprogrammi (makro $valueIfEmpty) nii, et tühja väärtuse korral tagastab see 1, veergu ennast mainimata.

Ja nüüd saate seda päringut graafiku jaoks kasutada

$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')

mis tähendab seda SQL-i (pange tähele, et tühjad uriStem väljad on teisendatud vaid 1-ks)

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

Järeldus

ClickHouse'i andmebaasi ilmumisest on saanud turul märgiline sündmus. Raske oli ette kujutada, et täiesti tasuta olime hetkega relvastatud võimsa ja praktilise tööriistaga suurandmetega töötamiseks. Muidugi, kasvavate vajaduste tõttu (näiteks jagamine ja replikatsioon mitmele serverile) muutub skeem keerulisemaks. Kuid esmamulje põhjal on selle andmebaasiga töötamine väga meeldiv. On näha, et toode on valmistatud "inimestele".

Võrreldes ElasticSearchiga vähenevad logide säilitamise ja töötlemise kulud hinnanguliselt viis kuni kümme korda. Ehk kui praeguse andmemahu jaoks peaksime üles panema mitmest masinast koosneva klastri, siis ClickHouse’i kasutamisel piisab meile ühest väikese võimsusega masinast. Jah, loomulikult on ElasticSearchil ka kettal andmete tihendamise mehhanismid ja muud võimalused, mis võivad ressursikulu oluliselt vähendada, kuid võrreldes ClickHouse'iga läheb see kallimaks.

Ilma eriliste optimeerimisteta töötavad vaikeseaded, andmete laadimine ja andmebaasist valimine hämmastava kiirusega. Meil pole veel palju andmeid (umbes 200 miljonit kirjet), kuid server ise on nõrk. Saame seda tööriista tulevikus kasutada ka muudel eesmärkidel, mis ei ole seotud logide salvestamisega. Näiteks otsast lõpuni analüütika jaoks, turvalisuse, masinõppe valdkonnas.

Lõpetuseks natuke plusse ja miinuseid.

Miinused

  1. Kirjete laadimine suurte partiidena. Ühest küljest on see funktsioon, kuid kirjete puhverdamiseks peate siiski kasutama lisakomponente. See ülesanne pole alati lihtne, kuid siiski lahendatav. Ja ma tahaksin skeemi lihtsustada.
  2. Mõned eksootilised funktsioonid või uued funktsioonid purunevad sageli uutes versioonides. See tekitab muret, vähendades soovi minna üle uuele versioonile. Näiteks Kafka tabelimootor on väga kasulik funktsioon, mis võimaldab teil lugeda Kafka sündmusi otse ilma tarbijaid rakendamata. Kuid Githubis olevate probleemide arvu järgi otsustades oleme siiski ettevaatlikud, et seda mootorit tootmises mitte kasutada. Kui aga äkilisi žeste kõrvale ei tee ja põhifunktsionaalsust kasutad, siis see toimib stabiilselt.

Plusse

  1. Ei aeglusta.
  2. Madal sisenemiskünnis.
  3. Avatud lähtekoodiga.
  4. Tasuta.
  5. Skaalab hästi (killustamine/paljundamine karbist välja)
  6. Kaasatud kommunikatsiooniministeeriumi soovitatud Venemaa tarkvara registrisse.
  7. Yandexi ametliku toe olemasolu.

Allikas: www.habr.com

Lisa kommentaar