Databáza ClickHouse pre ľudí alebo mimozemské technológie

Aleksey Lizunov, vedúci kompetenčného centra pre kanály diaľkových služieb Riaditeľstva informačných technológií MKB

Databáza ClickHouse pre ľudí alebo mimozemské technológie

Ako alternatívu k zásobníku ELK (ElasticSearch, Logstash, Kibana) robíme výskum o použití databázy ClickHouse ako úložiska údajov pre protokoly.

V tomto článku by sme radi porozprávali o našich skúsenostiach s používaním databázy ClickHouse a predbežných výsledkoch pilotnej prevádzky. Hneď je potrebné poznamenať, že výsledky boli pôsobivé.


Databáza ClickHouse pre ľudí alebo mimozemské technológie

Ďalej si podrobnejšie popíšeme, ako je náš systém nakonfigurovaný a z akých komponentov sa skladá. Ale teraz by som rád povedal trochu o tejto databáze ako celku a prečo sa jej oplatí venovať pozornosť. Databáza ClickHouse je vysoko výkonná analytická stĺpcová databáza od spoločnosti Yandex. Používa sa v službách Yandex, spočiatku je to hlavné úložisko údajov pre Yandex.Metrica. Open source systém, zadarmo. Z pohľadu vývojárov ma vždy zaujímalo, ako to implementovali, pretože sú tam fantasticky veľké dáta. A samotné používateľské rozhranie Metrica je veľmi flexibilné a rýchle. Pri prvom zoznámení sa s touto databázou je dojem: „No konečne! Vyrobené pre ľudí! Počnúc procesom inštalácie a končiac odoslaním požiadaviek.

Táto databáza má veľmi nízky vstupný prah. Túto databázu zvládne nainštalovať za pár minút aj priemerne zdatný vývojár a začať ju používať. Všetko funguje prehľadne. Dokonca aj ľudia, ktorí sú v Linuxe noví, dokážu rýchlo zvládnuť inštaláciu a vykonať tie najjednoduchšie operácie. Ak skôr, so slovami Big Data, Hadoop, Google BigTable, HDFS, bežný vývojár mal predstavy, že ide o nejaké terabajty, petabajty, že niektorí nadľudia sa zaoberajú nastavením a vývojom týchto systémov, potom s príchodom ClickHouse databázou sme dostali jednoduchý, zrozumiteľný nástroj, pomocou ktorého môžete vyriešiť predtým nedosiahnuteľný rozsah úloh. Inštalácia trvá len jeden pomerne priemerný stroj a päť minút. To znamená, že sme dostali takú databázu, ako je napríklad MySql, ale iba na ukladanie miliárd záznamov! Istý super-archivér s jazykom SQL. Je to ako keby ľudia dostali zbrane mimozemšťanov.

O našom systéme prihlasovania

Na zber informácií sa používajú protokolové súbory IIS webových aplikácií štandardného formátu (v súčasnosti tiež analyzujeme protokoly aplikácií, ale hlavným cieľom v pilotnej fáze je zhromažďovať protokoly IIS).

Z rôznych dôvodov sme nemohli úplne opustiť zásobník ELK a naďalej používame komponenty LogStash a Filebeat, ktoré sa osvedčili a fungujú celkom spoľahlivo a predvídateľne.

Všeobecná schéma protokolovania je znázornená na obrázku nižšie:

Databáza ClickHouse pre ľudí alebo mimozemské technológie

Funkciou zapisovania údajov do databázy ClickHouse je zriedkavé (raz za sekundu) vkladanie záznamov vo veľkých dávkach. Toto je zjavne tá „najproblematickejšia“ časť, s ktorou sa stretnete, keď prvýkrát zažijete prácu s databázou ClickHouse: schéma sa trochu skomplikuje.
Tu veľmi pomohol plugin pre LogStash, ktorý priamo vkladá dáta do ClickHouse. Tento komponent je nasadený na rovnakom serveri ako samotná databáza. Takže vo všeobecnosti sa to neodporúča robiť, ale z praktického hľadiska, aby sa nevyrábali samostatné servery, kým je nasadený na tom istom serveri. Nezaznamenali sme žiadne zlyhania alebo konflikty zdrojov s databázou. Okrem toho je potrebné poznamenať, že doplnok má mechanizmus opakovania v prípade chýb. A v prípade chýb plugin zapíše na disk dávku dát, ktorú nebolo možné vložiť (formát súboru je pohodlný: po úprave môžete jednoducho vložiť opravenú dávku pomocou clickhouse-client).

Úplný zoznam softvéru použitého v schéme je uvedený v tabuľke:

Zoznam použitého softvéru

názov

Popis

Distribučný odkaz

Nginx

Reverzný proxy na obmedzenie prístupu podľa portov a organizáciu autorizácie

V súčasnosti sa v schéme nepoužíva

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

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

FileBeat

Prenos protokolov súborov.

https://www.elastic.co/downloads/beats/filebeat (distribučná súprava pre Windows 64bit).

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

logstash

Zberač guľatiny.

Používa sa na zhromažďovanie protokolov z FileBeat, ako aj na zhromažďovanie protokolov z frontu RabbitMQ (pre servery, ktoré sú v DMZ.)

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

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

Logstash-output-clickhouse

Zásuvný modul Loagstash na dávkový prenos protokolov do databázy ClickHouse

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

/usr/share/logstash/bin/logstash-plugin nainštalovať logstash-output-clickhouse

/usr/share/logstash/bin/logstash-plugin nainštalovať logstash-filter-prune

/usr/share/logstash/bin/logstash-plugin nainštalovať logstash-filter-multiline

clickhouse

Ukladanie denníka 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

Poznámka. Od augusta 2018 sa v úložisku Yandex objavili „normálne“ zostavy otáčok za minútu pre RHEL, takže ich môžete skúsiť použiť. V čase inštalácie sme používali balíky zostavené spoločnosťou Altinity.

grafana

Vizualizácia denníka. Nastavenie informačných panelov

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 Bit) - najnovšia verzia

Zdroj údajov ClickHouse pre Grafana 4.6+

Plugin pre Grafana so zdrojom údajov ClickHouse

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

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

logstash

Zaznamenajte smerovač z frontu FileBeat do RabbitMQ.

Poznámka. Bohužiaľ, FileBeat nemá výstup priamo do RabbitMQ, takže je potrebný medzičlánok vo forme Logstash

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

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

RabbitMQ

front správ. Toto je vyrovnávacia pamäť denníka v DMZ

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

Erlang Runtime (vyžadované pre RabbitMQ)

Runtime Erlang. Vyžaduje sa pre fungovanie RabbitMQ

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

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

Konfigurácia servera s databázou ClickHouse je uvedená v nasledujúcej tabuľke:

názov

Hodnota

Poznámka

konfigurácia

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

Je potrebné venovať pozornosť tipom na obsluhu databázy ClickHouse (https://clickhouse.yandex/docs/ru/operations/tips/)

Všeobecný systémový softvér

OS: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Ako vidíte, ide o obyčajnú pracovnú stanicu.

Štruktúra tabuľky na ukladanie protokolov je nasledovná:

log_web.sql

CREATE TABLE log_web (
  logdate Date,
  logdatetime DateTime CODEC(Delta, LZ4HC),
   
  fld_log_file_name LowCardinality( String ),
  fld_server_name LowCardinality( String ),
  fld_app_name LowCardinality( String ),
  fld_app_module LowCardinality( String ),
  fld_website_name LowCardinality( String ),
 
  serverIP LowCardinality( String ),
  method LowCardinality( String ),
  uriStem String,
  uriQuery String,
  port UInt32,
  username LowCardinality( String ),
  clientIP String,
  clientRealIP String,
  userAgent String,
  referer String,
  response String,
  subresponse String,
  win32response String,
  timetaken UInt64
   
  , uriQuery__utm_medium String
  , uriQuery__utm_source String
  , uriQuery__utm_campaign String
  , uriQuery__utm_term String
  , uriQuery__utm_content String
  , uriQuery__yclid String
  , uriQuery__region String
 
) Engine = MergeTree()
PARTITION BY toYYYYMM(logdate)
ORDER BY (fld_app_name, fld_app_module, logdatetime)
SETTINGS index_granularity = 8192;

Používame predvolené rozdelenie (podľa mesiaca) a granularitu indexu. Všetky polia prakticky zodpovedajú záznamom protokolu IIS pre protokolovanie požiadaviek http. Samostatne si všimneme, že existujú samostatné polia na ukladanie značiek utm (sú analyzované vo fáze vkladania do tabuľky z poľa reťazca dotazu).

Do tabuľky bolo tiež pridaných niekoľko systémových polí na ukladanie informácií o systémoch, komponentoch, serveroch. Popis týchto polí nájdete v tabuľke nižšie. V jednej tabuľke ukladáme protokoly pre viacero systémov.

názov

Popis

Príklad

fld_app_name

Názov aplikácie/systému
Platné hodnoty:

  • site1.domain.com Externá lokalita 1
  • site2.domain.com Externá lokalita 2
  • interna-stranka1.domena.local Interna lokalita 1

site1.domena.com

fld_app_module

Systémový modul
Platné hodnoty:

  • web - Webová stránka
  • svc - služba webovej stránky
  • intgr - Integračná webová služba
  • bo - Správca (BackOffice)

web

fld_website_name

Názov lokality v službe IIS

Na jednom serveri môže byť nasadených niekoľko systémov alebo dokonca niekoľko inštancií jedného systémového modulu

hlavný web

fld_server_name

Názov servera

web1.domena.com

fld_log_file_name

Cesta k súboru denníka na serveri

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

To vám umožní efektívne vytvárať grafy v Grafane. Napríklad zobraziť požiadavky z frontendu konkrétneho systému. Je to podobné ako počítadlo stránok v Yandex.Metrica.

Tu je niekoľko štatistík o používaní databázy za dva mesiace.

Počet záznamov v členení podľa systémov a ich komponentov

SELECT
    fld_app_name,
    fld_app_module,
    count(fld_app_name) AS rows_count
FROM log_web
GROUP BY
    fld_app_name,
    fld_app_module
    WITH TOTALS
ORDER BY
    fld_app_name ASC,
    rows_count DESC
 
┌─fld_app_name─────┬─fld_app_module─┬─rows_count─┐
│ site1.domain.ru  │ web            │     131441 │
│ site2.domain.ru  │ web            │    1751081 │
│ site3.domain.ru  │ web            │  106887543 │
│ site3.domain.ru  │ svc            │   44908603 │
│ site3.domain.ru  │ intgr          │    9813911 │
│ site4.domain.ru  │ web            │     772095 │
│ site5.domain.ru  │ web            │   17037221 │
│ site5.domain.ru  │ intgr          │     838559 │
│ site5.domain.ru  │ bo             │       7404 │
│ site6.domain.ru  │ web            │     595877 │
│ site7.domain.ru  │ web            │   27778858 │
└──────────────────┴────────────────┴────────────┘
 
Totals:
┌─fld_app_name─┬─fld_app_module─┬─rows_count─┐
│              │                │  210522593 │
└──────────────┴────────────────┴────────────┘
 
11 rows in set. Elapsed: 4.874 sec. Processed 210.52 million rows, 421.67 MB (43.19 million rows/s., 86.51 MB/s.)

Množstvo dát na disku

SELECT
    formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed,
    formatReadableSize(sum(data_compressed_bytes)) AS compressed,
    sum(rows) AS total_rows
FROM system.parts
WHERE table = 'log_web'
 
┌─uncompressed─┬─compressed─┬─total_rows─┐
│ 54.50 GiB    │ 4.86 GiB   │  211427094 │
└──────────────┴────────────┴────────────┘
 
1 rows in set. Elapsed: 0.035 sec.

Stupeň kompresie údajov v stĺpcoch

SELECT
    name,
    formatReadableSize(data_uncompressed_bytes) AS uncompressed,
    formatReadableSize(data_compressed_bytes) AS compressed,
    data_uncompressed_bytes / data_compressed_bytes AS compress_ratio
FROM system.columns
WHERE table = 'log_web'
 
┌─name───────────────────┬─uncompressed─┬─compressed─┬─────compress_ratio─┐
│ logdate                │ 401.53 MiB   │ 1.80 MiB   │ 223.16665968777315 │
│ logdatetime            │ 803.06 MiB   │ 35.91 MiB  │ 22.363966401202305 │
│ fld_log_file_name      │ 220.66 MiB   │ 2.60 MiB   │  84.99905736932571 │
│ fld_server_name        │ 201.54 MiB   │ 50.63 MiB  │  3.980924816977078 │
│ fld_app_name           │ 201.17 MiB   │ 969.17 KiB │ 212.55518183686877 │
│ fld_app_module         │ 201.17 MiB   │ 968.60 KiB │ 212.67805817411906 │
│ fld_website_name       │ 201.54 MiB   │ 1.24 MiB   │  162.7204926761546 │
│ serverIP               │ 201.54 MiB   │ 50.25 MiB  │  4.010824061219731 │
│ method                 │ 201.53 MiB   │ 43.64 MiB  │  4.617721053304486 │
│ uriStem                │ 5.13 GiB     │ 832.51 MiB │  6.311522291936919 │
│ uriQuery               │ 2.58 GiB     │ 501.06 MiB │  5.269731450124478 │
│ port                   │ 803.06 MiB   │ 3.98 MiB   │ 201.91673864241824 │
│ username               │ 318.08 MiB   │ 26.93 MiB  │ 11.812513794583598 │
│ clientIP               │ 2.35 GiB     │ 82.59 MiB  │ 29.132328640073343 │
│ clientRealIP           │ 2.49 GiB     │ 465.05 MiB │  5.478382297052563 │
│ userAgent              │ 18.34 GiB    │ 764.08 MiB │  24.57905114484208 │
│ referer                │ 14.71 GiB    │ 1.37 GiB   │ 10.736792723669906 │
│ response               │ 803.06 MiB   │ 83.81 MiB  │  9.582334090987247 │
│ subresponse            │ 399.87 MiB   │ 1.83 MiB   │  218.4831068635027 │
│ win32response          │ 407.86 MiB   │ 7.41 MiB   │ 55.050315514606815 │
│ timetaken              │ 1.57 GiB     │ 402.06 MiB │ 3.9947395692010637 │
│ uriQuery__utm_medium   │ 208.17 MiB   │ 12.29 MiB  │ 16.936148912472955 │
│ uriQuery__utm_source   │ 215.18 MiB   │ 13.00 MiB  │ 16.548367623199912 │
│ uriQuery__utm_campaign │ 381.46 MiB   │ 37.94 MiB  │ 10.055156353418509 │
│ uriQuery__utm_term     │ 231.82 MiB   │ 10.78 MiB  │ 21.502540454070672 │
│ uriQuery__utm_content  │ 441.34 MiB   │ 87.60 MiB  │  5.038260760449327 │
│ uriQuery__yclid        │ 216.88 MiB   │ 16.58 MiB  │  13.07721335008116 │
│ uriQuery__region       │ 204.35 MiB   │ 9.49 MiB   │  21.52661903446796 │
└────────────────────────┴──────────────┴────────────┴────────────────────┘
 
28 rows in set. Elapsed: 0.005 sec.

Popis použitých komponentov

FileBeat. Prenos protokolov súborov

Tento komponent sleduje zmeny v protokolových súboroch na disku a odovzdáva informácie do LogStash. Nainštalované na všetkých serveroch, kde sa zapisujú protokolové súbory (zvyčajne IIS). Pracuje v režime chvosta (t. j. prenáša len pridané záznamy do súboru). Samostatne ho však možno nakonfigurovať na prenos celých súborov. Je to užitočné, keď potrebujete stiahnuť dáta z predchádzajúcich mesiacov. Stačí vložiť súbor denníka do priečinka a prečíta ho celý.

Keď je služba zastavená, dáta sa už neprenášajú ďalej do úložiska.

Príklad konfigurácie vyzerá takto:

filebeat.yml

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - C:/inetpub/logs/LogFiles/W3SVC1/*.log
  exclude_files: ['.gz$','.zip$']
  tail_files: true
  ignore_older: 24h
  fields:
    fld_server_name: "site1.domain.ru"
    fld_app_name: "site1.domain.ru"
    fld_app_module: "web"
    fld_website_name: "web-main"
 
- type: log
  enabled: true
  paths:
    - C:/inetpub/logs/LogFiles/__Import/access_log-*
  exclude_files: ['.gz$','.zip$']
  tail_files: false
  fields:
    fld_server_name: "site2.domain.ru"
    fld_app_name: "site2.domain.ru"
    fld_app_module: "web"
    fld_website_name: "web-main"
    fld_logformat: "logformat__apache"
 
 
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
  reload.period: 2s
 
output.logstash:
  hosts: ["log.domain.com:5044"]
 
  ssl.enabled: true
  ssl.certificate_authorities: ["C:/filebeat/certs/ca.pem", "C:/filebeat/certs/ca-issuing.pem"]
  ssl.certificate: "C:/filebeat/certs/site1.domain.ru.cer"
  ssl.key: "C:/filebeat/certs/site1.domain.ru.key"
 
#================================ Processors =====================================
 
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~

logstash. Zberateľ guľatiny

Tento komponent je navrhnutý tak, aby prijímal položky protokolu z FileBeat (alebo prostredníctvom frontu RabbitMQ), analyzoval a vložil dávky do databázy ClickHouse.

Na vloženie do ClickHouse sa používa plugin Logstash-output-clickhouse. Doplnok Logstash má mechanizmus opakovania žiadosti, ale pri pravidelnom vypínaní je lepšie zastaviť samotnú službu. Po zastavení sa správy budú hromadiť vo fronte RabbitMQ, takže ak je zastavenie na dlhý čas, je lepšie zastaviť Filebeats na serveroch. V schéme, kde sa nepoužíva RabbitMQ (v lokálnej sieti Filebeat priamo posiela logy do Logstashe), Filebeats fungujú celkom prijateľne a bezpečne, takže pre nich nedostupnosť výstupu prechádza bez následkov.

Príklad konfigurácie vyzerá takto:

log_web__filebeat_clickhouse.conf

input {
 
    beats {
        port => 5044
        type => 'iis'
        ssl => true
        ssl_certificate_authorities => ["/etc/logstash/certs/ca.cer", "/etc/logstash/certs/ca-issuing.cer"]
        ssl_certificate => "/etc/logstash/certs/server.cer"
        ssl_key => "/etc/logstash/certs/server-pkcs8.key"
        ssl_verify_mode => "peer"
 
            add_field => {
                "fld_server_name" => "%{[fields][fld_server_name]}"
                "fld_app_name" => "%{[fields][fld_app_name]}"
                "fld_app_module" => "%{[fields][fld_app_module]}"
                "fld_website_name" => "%{[fields][fld_website_name]}"
                "fld_log_file_name" => "%{source}"
                "fld_logformat" => "%{[fields][fld_logformat]}"
            }
    }
 
    rabbitmq {
        host => "queue.domain.com"
        port => 5671
        user => "q-reader"
        password => "password"
        queue => "web_log"
        heartbeat => 30
        durable => true
        ssl => true
        #ssl_certificate_path => "/etc/logstash/certs/server.p12"
        #ssl_certificate_password => "password"
 
        add_field => {
            "fld_server_name" => "%{[fields][fld_server_name]}"
            "fld_app_name" => "%{[fields][fld_app_name]}"
            "fld_app_module" => "%{[fields][fld_app_module]}"
            "fld_website_name" => "%{[fields][fld_website_name]}"
            "fld_log_file_name" => "%{source}"
            "fld_logformat" => "%{[fields][fld_logformat]}"
        }
    }
 
}
 
filter { 
 
      if [message] =~ "^#" {
        drop {}
      }
 
      if [fld_logformat] == "logformat__iis_with_xrealip" {
     
          grok {
            match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken} %{NOTSPACE:xrealIP} %{NOTSPACE:xforwarderfor}"]
          }
      } else {
   
          grok {
             match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken}"]
          }
 
      }
 
      date {
        match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ]
          timezone => "Etc/UTC"
        remove_field => [ "log_timestamp", "@timestamp" ]
        target => [ "log_timestamp2" ]
      }
 
        ruby {
            code => "tstamp = event.get('log_timestamp2').to_i
                        event.set('logdatetime', Time.at(tstamp).strftime('%Y-%m-%d %H:%M:%S'))
                        event.set('logdate', Time.at(tstamp).strftime('%Y-%m-%d'))"
        }
 
      if [bytesSent] {
        ruby {
          code => "event['kilobytesSent'] = event['bytesSent'].to_i / 1024.0"
        }
      }
 
 
      if [bytesReceived] {
        ruby {
          code => "event['kilobytesReceived'] = event['bytesReceived'].to_i / 1024.0"
        }
      }
 
   
        ruby {
            code => "event.set('clientRealIP', event.get('clientIP'))"
        }
        if [xrealIP] {
            ruby {
                code => "event.set('clientRealIP', event.get('xrealIP'))"
            }
        }
        if [xforwarderfor] {
            ruby {
                code => "event.set('clientRealIP', event.get('xforwarderfor'))"
            }
        }
 
      mutate {
        convert => ["bytesSent", "integer"]
        convert => ["bytesReceived", "integer"]
        convert => ["timetaken", "integer"] 
        convert => ["port", "integer"]
 
        add_field => {
            "clientHostname" => "%{clientIP}"
        }
      }
 
        useragent {
            source=> "useragent"
            prefix=> "browser"
        }
 
        kv {
            source => "uriQuery"
            prefix => "uriQuery__"
            allow_duplicate_values => false
            field_split => "&"
            include_keys => [ "utm_medium", "utm_source", "utm_campaign", "utm_term", "utm_content", "yclid", "region" ]
        }
 
        mutate {
            join => { "uriQuery__utm_source" => "," }
            join => { "uriQuery__utm_medium" => "," }
            join => { "uriQuery__utm_campaign" => "," }
            join => { "uriQuery__utm_term" => "," }
            join => { "uriQuery__utm_content" => "," }
            join => { "uriQuery__yclid" => "," }
            join => { "uriQuery__region" => "," }
        }
 
}
 
output { 
  #stdout {codec => rubydebug}
    clickhouse {
      headers => ["Authorization", "Basic abcdsfks..."]
      http_hosts => ["http://127.0.0.1:8123"]
      save_dir => "/etc/logstash/tmp"
      table => "log_web"
      request_tolerance => 1
      flush_size => 10000
      idle_flush_time => 1
        mutations => {
            "fld_log_file_name" => "fld_log_file_name"
            "fld_server_name" => "fld_server_name"
            "fld_app_name" => "fld_app_name"
            "fld_app_module" => "fld_app_module"
            "fld_website_name" => "fld_website_name"
 
            "logdatetime" => "logdatetime"
            "logdate" => "logdate"
            "serverIP" => "serverIP"
            "method" => "method"
            "uriStem" => "uriStem"
            "uriQuery" => "uriQuery"
            "port" => "port"
            "username" => "username"
            "clientIP" => "clientIP"
            "clientRealIP" => "clientRealIP"
            "userAgent" => "userAgent"
            "referer" => "referer"
            "response" => "response"
            "subresponse" => "subresponse"
            "win32response" => "win32response"
            "timetaken" => "timetaken"
             
            "uriQuery__utm_medium" => "uriQuery__utm_medium"
            "uriQuery__utm_source" => "uriQuery__utm_source"
            "uriQuery__utm_campaign" => "uriQuery__utm_campaign"
            "uriQuery__utm_term" => "uriQuery__utm_term"
            "uriQuery__utm_content" => "uriQuery__utm_content"
            "uriQuery__yclid" => "uriQuery__yclid"
            "uriQuery__region" => "uriQuery__region"
        }
    }
 
}

potrubia.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. Ukladanie denníka

Logy pre všetky systémy sú uložené v jednej tabuľke (viď na začiatku článku). Je určený na ukladanie informácií o požiadavkách: všetky parametre sú podobné pre rôzne formáty, ako sú protokoly IIS, protokoly Apache a nginx. Pre aplikačné protokoly, v ktorých sa zaznamenávajú napríklad chyby, informačné hlásenia, varovania, bude k dispozícii samostatná tabuľka s príslušnou štruktúrou (momentálne v štádiu návrhu).

Pri návrhu tabuľky je veľmi dôležité rozhodnúť sa pre primárny kľúč (podľa ktorého sa budú dáta pri ukladaní triediť). Od toho závisí stupeň kompresie údajov a rýchlosť dotazovania. V našom príklade je kľúč
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Teda názvom systému, názvom komponentu systému a dátumom udalosti. Spočiatku bol na prvom mieste dátum konania. Po presunutí na posledné miesto začali dopyty fungovať asi dvakrát rýchlejšie. Zmena primárneho kľúča bude vyžadovať opätovné vytvorenie tabuľky a opätovné načítanie údajov, aby ClickHouse pretriedil údaje na disku. Ide o náročnú operáciu, preto je dobré veľa premýšľať o tom, čo by malo byť zahrnuté v kľúči triedenia.

Treba tiež poznamenať, že typ údajov LowCardinality sa objavil v relatívne nedávnych verziách. Pri jeho použití sa veľkosť komprimovaných údajov drasticky zníži pre polia, ktoré majú nízku mohutnosť (málo možností).

Momentálne sa používa verzia 19.6 a plánujeme vyskúšať aktualizáciu na najnovšiu verziu. Majú také úžasné funkcie, ako je napríklad adaptívna granularita, indexy preskakovania a kodek DoubleDelta.

Štandardne je počas inštalácie úroveň protokolovania nastavená na sledovanie. Logy sa otáčajú a archivujú, no zároveň sa rozširujú až o gigabajt. Ak to nie je potrebné, môžete nastaviť úroveň varovania, potom sa veľkosť denníka výrazne zníži. Nastavenie protokolovania sa nastavuje v súbore config.xml:

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

Niektoré užitočné príkazy

Поскольку оригинальные пакеты установки собираются по Debian, то для других версий Linux необходимо использовать пакеты собранные компанией Altinity.
 
Вот по этой ссылке есть инструкции с ссылками на их репозиторий: https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse
sudo yum search clickhouse-server
sudo yum install clickhouse-server.noarch
  
1. проверка статуса
sudo systemctl status clickhouse-server
 
2. остановка сервера
sudo systemctl stop clickhouse-server
 
3. запуск сервера
sudo systemctl start clickhouse-server
 
Запуск для выполнения запросов в многострочном режиме (выполнение после знака ";")
clickhouse-client --multiline
clickhouse-client --multiline --host 127.0.0.1 --password pa55w0rd
clickhouse-client --multiline --host 127.0.0.1 --port 9440 --secure --user default --password pa55w0rd
 
Плагин кликлауза для логстеш в случае ошибки в одной строке сохраняет всю пачку в файл /tmp/log_web_failed.json
Можно вручную исправить этот файл и попробовать залить его в БД вручную:
clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /tmp/log_web_failed__fixed.json
 
sudo mv /etc/logstash/tmp/log_web_failed.json /etc/logstash/tmp/log_web_failed__fixed.json
sudo chown user_dev /etc/logstash/tmp/log_web_failed__fixed.json
sudo clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /etc/logstash/tmp/log_web_failed__fixed.json
sudo mv /etc/logstash/tmp/log_web_failed__fixed.json /etc/logstash/tmp/log_web_failed__fixed_.json
 
выход из командной строки
quit;
## Настройка TLS
https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2
 
openssl s_client -connect log.domain.com:9440 < /dev/null

logstash. Zaznamenajte smerovač z frontu FileBeat do RabbitMQ

Tento komponent sa používa na smerovanie protokolov prichádzajúcich z FileBeat do frontu RabbitMQ. Sú tu dva body:

  1. Bohužiaľ, FileBeat nemá výstupný plugin na zapisovanie priamo do RabbitMQ. A takáto funkčnosť, súdiac podľa problému na ich githube, nie je plánovaná na implementáciu. Existuje plugin pre Kafku, ale z nejakého dôvodu ho nemôžeme použiť doma.
  2. V DMZ sú kladené požiadavky na zber logov. Na základe nich je potrebné najskôr pridať protokoly do frontu a potom LogStash načíta záznamy z frontu zvonku.

Preto je pre prípad, že sa servery nachádzajú v DMZ, treba použiť takú trochu komplikovanú schému. Príklad konfigurácie vyzerá takto:

iis_w3c_logs__filebeat_rabbitmq.conf

input {
 
    beats {
        port => 5044
        type => 'iis'
        ssl => true
        ssl_certificate_authorities => ["/etc/pki/tls/certs/app/ca.pem", "/etc/pki/tls/certs/app/ca-issuing.pem"]
        ssl_certificate => "/etc/pki/tls/certs/app/queue.domain.com.cer"
        ssl_key => "/etc/pki/tls/certs/app/queue.domain.com-pkcs8.key"
        ssl_verify_mode => "peer"
    }
 
}
 
output { 
  #stdout {codec => rubydebug}
 
    rabbitmq {
        host => "127.0.0.1"
        port => 5672
        exchange => "monitor.direct"
        exchange_type => "direct"
        key => "%{[fields][fld_app_name]}"
        user => "q-writer"
        password => "password"
        ssl => false
    }
}

RabbitMQ. front správ

Tento komponent sa používa na vyrovnávanie záznamov protokolu v DMZ. Nahrávanie sa vykonáva cez súbor Filebeat → LogStash. Čítanie sa vykonáva mimo DMZ cez LogStash. Pri prevádzke cez RabboitMQ sa spracováva asi 4 XNUMX správ za sekundu.

Smerovanie správ sa konfiguruje podľa názvu systému, t. j. na základe konfiguračných údajov FileBeat. Všetky správy idú do jedného frontu. Ak sa z nejakého dôvodu služba zaraďovania do frontu zastaví, nepovedie to k strate správ: FileBeats dostane chyby pripojenia a dočasne pozastaví odosielanie. A LogStash, ktorý číta z frontu, tiež dostane chyby siete a počká na obnovenie pripojenia. V tomto prípade sa dáta, samozrejme, už nebudú zapisovať do databázy.

Nasledujúce pokyny sa používajú na vytváranie a konfiguráciu frontov:

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

Tento komponent sa používa na vizualizáciu monitorovacích údajov. V tomto prípade musíte nainštalovať zdroj údajov ClickHouse pre doplnok Grafana 4.6+. Museli sme ho trochu upraviť, aby sme zlepšili efektivitu spracovania SQL filtrov na palubnej doske.

Napríklad používame premenné a ak nie sú nastavené v poli filtra, tak by sme chceli, aby negenerovalo podmienku v WHERE formulára ( uriStem = » AND uriStem != » ). V tomto prípade ClickHouse prečíta stĺpec uriStem. Vo všeobecnosti sme skúšali rôzne možnosti a nakoniec sme plugin (makro $valueIfEmpty) opravili tak, aby v prípade prázdnej hodnoty vrátil 1, bez uvedenia samotného stĺpca.

A teraz môžete tento dotaz použiť pre graf

$columns(response, count(*) c) from $table where $adhoc
and $valueIfEmpty($fld_app_name, 1, fld_app_name = '$fld_app_name')
and $valueIfEmpty($fld_app_module, 1, fld_app_module = '$fld_app_module') and $valueIfEmpty($fld_server_name, 1, fld_server_name = '$fld_server_name') and $valueIfEmpty($uriStem, 1, uriStem like '%$uriStem%')
and $valueIfEmpty($clientRealIP, 1, clientRealIP = '$clientRealIP')

čo sa prekladá do tohto SQL (všimnite si, že prázdne polia uriStem boli skonvertované len na 1)

SELECT
t,
groupArray((response, c)) AS groupArr
FROM (
SELECT
(intDiv(toUInt32(logdatetime), 60) * 60) * 1000 AS t, response,
count(*) AS c FROM default.log_web
WHERE (logdate >= toDate(1565061982)) AND (logdatetime >= toDateTime(1565061982)) AND 1 AND (fld_app_name = 'site1.domain.ru') AND (fld_app_module = 'web') AND 1 AND 1 AND 1
GROUP BY
t, response
ORDER BY
t ASC,
response ASC
)
GROUP BY t ORDER BY t ASC

Záver

Vzhľad databázy ClickHouse sa stal medzníkom na trhu. Bolo ťažké si predstaviť, že úplne zadarmo sme boli v okamihu vyzbrojení výkonným a praktickým nástrojom na prácu s veľkými dátami. Samozrejme, s rastúcimi potrebami (napríklad sharding a replikácia na viacero serverov) bude schéma komplikovanejšia. Ale na prvý dojem je práca s touto databázou veľmi príjemná. Je vidieť, že produkt je vyrobený „pre ľudí“.

V porovnaní s ElasticSearch sa odhaduje, že náklady na ukladanie a spracovanie protokolov sa znížia päť až desaťkrát. Inými slovami, ak by sme pri súčasnom objeme dát museli zriadiť zhluk viacerých strojov, tak nám pri použití ClickHouse stačí jeden nízkoenergetický stroj. Áno, samozrejme, ElasticSearch má aj mechanizmy na kompresiu dát na disku a ďalšie funkcie, ktoré môžu výrazne znížiť spotrebu zdrojov, ale v porovnaní s ClickHouse to bude drahšie.

Bez špeciálnych optimalizácií z jeho strany, na predvolené nastavenia, načítanie dát a výber z databázy funguje úžasne rýchlo. Zatiaľ nemáme veľa údajov (asi 200 miliónov záznamov), ale samotný server je slabý. Tento nástroj môžeme v budúcnosti použiť aj na iné účely, ktoré nesúvisia s ukladaním protokolov. Napríklad pre komplexnú analýzu v oblasti bezpečnosti, strojového učenia.

Na záver niečo o výhodách a nevýhodách.

Zápory

  1. Načítavanie záznamov vo veľkých dávkach. Na jednej strane je to funkcia, ale stále musíte použiť ďalšie komponenty na ukladanie záznamov. Táto úloha nie je vždy jednoduchá, ale stále riešiteľná. A rád by som zjednodušil schému.
  2. Niektoré exotické funkcie alebo nové funkcie sa v nových verziách často zlomia. To spôsobuje obavy, čím sa znižuje túžba po inovácii na novú verziu. Napríklad, Kafka table engine je veľmi užitočná funkcia, ktorá vám umožňuje priamo čítať udalosti z Kafky, bez implementácie spotrebiteľov. Ale súdiac podľa počtu Issues na github, stále dávame pozor, aby sme tento engine nepoužili vo výrobe. Ak však nerobíte náhle gestá do strany a používate hlavnú funkcionalitu, funguje to stabilne.

Pros

  1. Nespomalí.
  2. Nízky vstupný prah.
  3. open source.
  4. Zadarmo.
  5. Dobre sa škáluje (sharding/replikácia po vybalení)
  6. Zahrnuté v registri ruského softvéru odporúčaného ministerstvom komunikácií.
  7. Prítomnosť oficiálnej podpory od spoločnosti Yandex.

Zdroj: hab.com

Pridať komentár