ClickHouse andmed inimeste jaoks, vÔi vÀlismaised tehnoloogiad

Aleksei Lizunov, kompetentsuskeskuse juht kaugteeninduse osakonnas MKB-informaatika direktoraadis

ClickHouse andmed inimeste jaoks, vÔi vÀlismaised tehnoloogiad

ELK (ElasticSearch, Logstash, Kibana) kihi alternatiivina viibime lÀbi teadusuuringute ClickHouse andmebaasi kasutamise kohta logide andmesalvestamiseks.

Selles artiklis soovime jagada meie kogemust ClickHouse andmebaasi kasutamisest ja eelnevaid tulemusi pilootkatsetuste pÔhjal. Oluline on mÀrkida, et tulemused on olnud muljetavaldavad.


ClickHouse andmed inimeste jaoks, vÔi vÀlismaised tehnoloogiad

JĂ€rgnevalt kirjeldame lĂ€hemalt, kuidas meie sĂŒsteem on seadistatud ja millistest komponentidest see koosneb. Kuid enne seda tahaksime rÀÀkida sellest andmebaasist ĂŒldiselt ja miks sellele tĂ€helepanu pöörata. ClickHouse andmebaas on kĂ”rge jĂ”udlusega veergude andmebaas, mis on loodud Yandexi poolt. Seda kasutatakse Yandexi teenustes ja algselt oli see peamine andmesalvestus Yandex.Metrika jaoks. SĂŒsteem on avatud lĂ€htekoodiga ja tasuta. Arendajana on mind alati huvitanu, kuidas nad seda ellu viivad, kuna seal on fantastiliselt suured andmed. Ja Yandex.Metrika kasutajaliides on vĂ€ga paindlik ja töötab kiiresti. Esmakohtumisel selle andmebaasiga jÀÀb mulje: "LĂ”finally! Tehtud 'inimeste jaoks'! Alustades paigaldamisprotsessist ja lĂ”petades pĂ€ringute saatmisega."

Sellel andmebaasil on vĂ€ga madal sisenemiskĂŒnnis. Isegi keskmise kvalifikatsiooniga arendaja suudab selle andmebaasi paigaldada ja alustada kasutamist vaid mĂ”ne minutiga. KĂ”ik töötab tĂ”husalt. Ieven inimesed, kellel on madal Linuxi tundmine, suudavad ĂŒsna kiiresti selle paigaldamisega hakkama saada ja teha lihtsamaid toiminguid. Kui varem seostusid tavalise arendaja mĂ”tted Big Data, Hadoop, Google BigTable, HDFS mainimisega miljonite ja petabaitide ning nende sĂŒsteemide seadistamise ja arendamisega, siis ClickHouse andmebaasi tulekuga saime lihtsa ja arusaadava tööriista, millega saab lahendada enneolematuid ĂŒlesandeid. Piisab vaid ĂŒhest keskmisest masinast ja viiest minutist paigaldamiseks. Seega saime sellise andmebaasi nagu MySql, kuid miljardite rekordite salvestamiseks! Personaali superarhiivator SQL-i keeles. Nagu oleks inimestele antud tulnukate relvad.

Meie logide kogumise sĂŒsteemist

Teabe veebirakenduste IIS logifailide standardformaatide abil teabe kogumine (praegu tegeleme ka rakenduste logide parsimisega, kuid pilootfaasi pÔhieesmÀrk on IIS logide kogumine).

ELK virnaga tÀielikult loobuda ei Ônnestunud mitmetel pÔhjustel ning jÀtkame LogStashi ja Filebeati kasutamist, mis on hÀsti tÔestatud ning toimivad usaldusvÀÀrselt ja ettearvatavalt.

Üldine logimise skeem on esitatud alloleval joonisel:

ClickHouse andmed inimeste jaoks, vÔi vÀlismaised tehnoloogiad

ClickHouse andmebaasi andmete salvestamise eripĂ€ra on andmete harv (ĂŒks kord sekundis) suurte partiidena sisestamine. Ilmselt on see kĂ”ige "problemaatilisem" osa ClickHouse andmebaasi esmakordsel kasutamisel: skeem muutub veidi keerulisemaks.
Seda aitas oluliselt LogStashi plugin, mis sisestab andmed otse ClickHouse'i. See komponent paigaldatakse samale serverile, kus asub ka andmebaas. Üldiselt ei soovitata seda teha, kuid praktiliselt, et mitte loobuda eraldi serveritest, on see aktsepteeritav seni, kuni see on paigaldatud samale serverile. Me ei ole tĂ€heldanud mingeid tĂ”rkeid ega ressursikonflikte andmebaasiga. Samuti tuleb vĂ€lja tuua, et plugina puhul on ette nĂ€htud vigade korral taastamismehhanism. Vigade korral kirjutab plugin kettale andmepaki, mida ei Ă”nnestunud sisestada (faili formaat on mugav: pĂ€rast parandamist saab parandatud paki hĂ”lpsasti sisestada clickhouse-clientiga).

Kasutatava tarkvara tÀielik nimekiri on esitatud tabelis:

Kasutatava tarkvara nimekiri

Nimi

Kirjeldus

Lingid jaotusele

NGINX

Tagasi-proxyna, et piirata juurdepÀÀsu portidele ja korraldada autentimist

Praegu ei kasutata skeemis

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 (Windows 64bit jaotus).

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

LogStash

Logide kogumise tööriist.

Kasutatakse logide kogumiseks FileBeati kaudu ning logide kogumiseks RabbitMQ jÀrjekorrast (serverite jaoks, mis asuvad DMZ-s).

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

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

Logstash-output-clickhouse

Logstashi plugin logide edastamiseks ClickHouse'i andmebaasi partiitena.

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

ClickHouse

Logide hoidla 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Àrkus. Alates 2018. aasta augustist on Yandexi hoidlas ilmnenud "normaalsed" rpm kogumikud RHEL jaoks, seega on neid vÔimalik proovida. Paigaldamise hetkel kasutasime Altinity koostatud pakette.

Grafana

Logide visualiseerimine. Pinnase seadistamine.

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 bit) – viimane versioon.

ClickHouse andmeallikas Grafana 4.6+ jaoks.

Grafana plugin ClickHouse andmeallikaga.

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

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

LogStash

FileBeati logide marsruuter RabbitMQ jÀrjekorda.

MÀrkus. Kahjuks ei toeta FileBeat vÀljundit otse RabbitMQ-sse, seetÔttu on vajalik vahepealne komponent Logstash.

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

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

RabbitMQ

SÔnumite jÀrjekord. See on logide kirjutiste puhverriik DMZ-is.

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 (vajalik RabbitMQ jaoks)

Erlang Runtime. Vajalik RabbitMQ tööks.

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

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

ClickHouse'i andmebaasi serveri konfigureerimine on esitatud jÀrgmistel tabelitel:

Nimi

TĂ€hendus

MĂ€rkus

Konfiguratsioon

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

Oluline on pöörata tÀhelepanu ClickHouse'i andmebaasi kasutamise soovitustele (https://clickhouse.yandex/docs/ru/operations/tips/)

Üldine tarkvara

OS: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Nagu nÀha, on see tavaline tööjaam.

Logide salvestamiseks mÔeldud tabeli struktuur nÀeb vÀlja jÀrgmiselt:

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 partitsioneerimise (kuude kaupa) ja indeksi granulaarsuse vaikeseadeid. KÔik vÀljad vastavad praktiliselt IIS logide salvestamisele http-pÀringute jaoks. Eraldi on mÀrgitud, et on olemas spetsiaalsed vÀljad UTG-mÀrgiste salvestamiseks (need parsitakse tabelisse sisestamise etapis pÀringu stringi vÀljast).

Lisaks on tabelisse lisatud mitu sĂŒsteemivĂ€lja sĂŒsteemide, komponentide, serverite teabe salvestamiseks. Nende vĂ€ljade kirjeldus on toodud allpool tabelis. Ühes tabelis salvestame logid mitmete sĂŒsteemide kohta.

Nimi

Kirjeldus

NĂ€ide

fld_app_name

Rakenduse/sĂŒsteemi nimi
Lubatud vÀÀrtused:

  • site1.domain.com VĂ€line sait 1
  • site2.domain.com VĂ€line sait 2
  • internal-site1.domain.local Sisemine sait 1

site1.domain.com

fld_app_module

SĂŒsteemi moodul
Lubatud vÀÀrtused:

  • web — Veebisait
  • svc — Veebiteenus saidile
  • intgr — Integreerimise veebiteenus
  • bo — Adminpaneel (BackOffice)

web

fld_website_name

Veebisaidi nimi IIS-is

Ühel serveril vĂ”ib olla mitmeid sĂŒsteeme vĂ”i isegi mitu eksemplari ĂŒhes sĂŒsteemi moodulist.

web-main

fld_server_name

Serveri nimi

web1.domain.com

fld_log_file_name

Logifaili tee serveris

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

See vĂ”imaldab Grafanas tĂ”husalt graafikute loomiseks. NĂ€iteks saab vaadata konkreetse sĂŒsteemi esiplaani pĂ€ringuid. See sarnaneb saidi loenduri funktsioonile Yandex.Metrikas.

Siin on teatud statistika andmebaasi kasutamise kohta kahe kuu jooksul.

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

Andmete maht kettal

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 kokkusurumise mÀÀr veergudes

VALI
    nimi,
    formatReadableSize(data_uncompressed_bytes) KUI kompressitud,
    formatReadableSize(data_compressed_bytes) KUI kompressitud,
    data_uncompressed_bytes / data_compressed_bytes KUI kompressioonisuhe
FROM system.columns
WHERE table = 'log_web'
 
┌─nimi───────────────────┬─kompressimata─┬─kompressitud─┬─────kompressioonisuhe─┐
│ 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 rida komplektis. Aeg: 0.005 sek.

Kasutatud komponentide kirjeldus

FileBeat. Faili logide edastamine

See komponent jĂ€lgib logifailide muudatusi kettal ja edastab teavet LogStash'ile. Installeeritakse kĂ”ikidele serveritele, kus logifailid kirjutatakse (tavaliselt IIS). Töötab tail-reĆŸiimis (st edastab ainult lisatud kirjed faili). Kuid eraldi saab seadistada ka failide tĂ€ielikku edastamist. See on mugav, kui on vaja laadida andmeid varasemate kuude kohta. Lihtsalt pane logifail kausta ja see loeb selle ise kogu kaupa.

Kui teenus peatatakse, siis andmed lakkavad edastamast andmebaasi.

Konfiguratsiooni nÀidis nÀeb vÀlja jÀrgmine:

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"
 
#================================ Protsessorid =====================================
 
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~

LogStash. Logide kogumise tööriist

See komponent on mÔeldud logikande saamiseks FileBeatilt (kas lÀbi RabbitMQ jÀrjekorra vÔi mitte), nende parsimiseks ja partii kaupa andmebaasi ClickHouse sisestamiseks.

ClickHouse'i sisestamiseks kasutatakse Logstash-output-clickhouse pluginat. Logstash'il on taastekse mehhanism pÀringute jaoks, kuid korraliku peatamise korral on parem peatada teenus ise. Teenuse peatamisel hakkavad sÔnumid kogunema RabbitMQ jÀrjekorda, seega kui peatamine kestab pikalt, on parem peatada Filebeat'id serverites. Schemas, kus RabbitMQ-d ei kasutata (Filebeat saadab logid otse Logstash'ile), töötavad Filebeat'id tÀiesti rahuldavalt ja ohutult, seega nende jaoks toimub vÀljundite puudumine ilma tagajÀrgedeta.

Konfiguratsiooni nÀidis nÀeb vÀlja jÀrgmine:

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

pipelines.yml

# This file is where you define your pipelines. You can define multiple.
# For more information on multiple pipelines, see the documentation:
#   https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html
 
- pipeline.id: log_web__filebeat_clickhouse
  path.config: "/etc/logstash/log_web__filebeat_clickhouse.conf"

ClickHouse. Logide hoidmine

Logid kĂ”igi sĂŒsteemide kohta salvestatakse ĂŒhte tabelisse (vt artikli alguses). See on mĂ”eldud pĂ€ringute kohta teabe talletamiseks: kĂ”ik parameetrid sarnanevad erinevate formaatidega, nĂ€iteks IIS-i logid, Apache ja Nginx logid. Rakenduste logide jaoks, kus registreeritakse nĂ€iteks vead, teated, hoiatused, on ette nĂ€htud eraldi tabel koos vastava struktuuriga (praegu projekteerimise etapis).

Tabeli projekteerimisel on vÀga oluline mÀÀrata esmased vÔtmed (mille alusel andmeid salvestamisel sorteeritakse). See mÔjutab andmete tihendamise mÀÀra ja pÀringute kiirus. Meie nÀites on vÔtme vÀÀrtuseks
ORDER BY (fld_app_name, fld_app_module, logdatetime)
St. sĂŒsteemi nime, sĂŒsteemi komponendi nime ja sĂŒndmuse kuupĂ€eva jĂ€rgi. Alguses oli sĂŒndmuse kuupĂ€ev esimesena. PĂ€rast selle viimist viimasele kohale töötasid pĂ€ringud umbes kaks korda kiiremini. Eesmise vĂ”tme muutmine nĂ”uab tabeli uuesti loomist ja andmete uuesti laadimist, et ClickHouse andmed kettale ĂŒmber sorteeriks. See on keeruline operatsioon, seetĂ”ttu on soovitatav hoolikalt ette mĂ”elda, mis peab kuuluma sorteerimise vĂ”tmesse.

Samuti on oluline mĂ€rkida, et viimastel versioonidel on ilmunud andmetĂŒĂŒp LowCardinality. Selle kasutamisel vĂ€heneb oluliselt tihendatud andmete suurus madala kardinaalsusega vĂ€ljade jaoks (vĂ€he variante).

Praegu kasutatakse versiooni 19.6 ja plaanime proovida versiooni uuendada uusimale. Neil on sellised suurepÀrased funktsioonid nagu Adaptive Granularity, Skipping indices ja DoubleDelta koodek.

Paigaldamisel on konfiguratsioonis vaikimisi seadistatud logimistase trace. Logid roteeritakse ja arhiveeritakse, kuid samal ajal paisuvad need gigabaidini. Kui see pole vajalik, saab seada logimistaseme warning, mis vÀhendab logi suurust jÀrsult. Logimise seadistamine on mÀÀratud failis config.xml:

<!-- VÔimalikud tasemed: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger.h#L105 -->
<level>warning</level>

MÔned kasulikud kÀsud

Kuna originaalpakkumised koostatakse Debianis, tuleb teiste Linuxi versioonide puhul kasutada Altinity poolt koostatud pakette.

Siit lingilt leiate juhised koos linkidega nende hoidlasse: https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse
sudo yum search clickhouse-server
sudo yum install clickhouse-server.noarch

1. staatuse kontrollimine
sudo systemctl status clickhouse-server

2. serveri peatamine
sudo systemctl stop clickhouse-server

3. serveri kÀivitamine
sudo systemctl start clickhouse-server

KĂ€ivitamine mitmereĆŸii reĆŸiimis (kĂ€ivitatakse pĂ€rast mĂ€rki ";")
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

LogStashi ClickHouse plugin salvestab ĂŒhe rea vea korral kogu partii faili /tmp/log_web_failed.json.
Seda faili saab kĂ€sitsi parandada ja proovida selle andmebaasi kĂ€sitsi ĂŒles laadida:
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

command line'ist vÀljumine
quit;
## TLS seadistamine
https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2

openssl s_client -connect log.domain.com:9440 < /dev/null

LogStash. Ajalogide marsruut DafaBeatist RabbitMQ jÀrjekorda.

Seda komponenti kasutatakse logide suunamiseks, mis tulevad DafaBeatist RabbitMQ jÀrjekorda. Siin on kaks aspekti:

  1. Kahjuks puudub DafaBeatil vÀljundi plugin, mis vÔimaldaks kirjutada otse RabbitMQ-sse. Ja sellist funktsionaalsust, nagu nÀhtub nende GitHubi probleemidest, ei plaanita rakendada. On olemas plugin Kafka jaoks, kuid erinevate pÔhjuste tÔttu ei saa me seda kasutada.
  2. On nÔudmised logide kogumiseks DMZ-is. Nende alusel peavad logid esmalt minema jÀrjekorda ja seejÀrel loeb LogStash jÀrjekorrast sissekanded.

Seega, just DMZ-is asuvate serverite puhul tuleb kasutada sellist veidi keerukamat skeemi. Konfiguratsiooni nÀidis nÀeb vÀlja jÀrgmine:

iis_w3c_logs__filebeat_rabbitmq.conf

sisend {
 
    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"
    }
 
}
 
vÀljalase { 
  #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 logi kirjeid vahemĂ€luks DMZ-s. Kirje toimub kaudu Filebeat → LogStash. Lugemine toimub DMZ-st vĂ€ljaspool LogStashi kaudu. RabbitMQ kaudu kasutamisel töödeldakse umbes 4000 sĂ”numit sekundis.

SĂ”numite suunamine on seadistatud sĂŒsteemi nime jĂ€rgi, st FileBeat'i konfiguratsiooniandmete pĂ”hjal. KĂ”ik sĂ”numid satuvad ĂŒhte jĂ€rjekorda. Kui mingil pĂ”hjusel peatatakse jĂ€rjekorra teenus, siis see ei too kaasa sĂ”numite kadumist: FileBeat’id saavad ĂŒhenduse veateate ja peatavad ajutiselt saatmise. Samuti saab LogStash, mis loeb jĂ€rjekorrast, vĂ”rguveateate ja ootab, kuni ĂŒhendus taastub. Andmed peatuvad loomulikult andmebaasi kirjutamisest.

JÀrgmisi juhiseid kasutatakse jÀrjekordade loomiseks ja seadistamiseks:

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

Seda komponenti kasutatakse monitorimise andmete visualiseerimiseks. Selleks on vajalik paigaldada ClickHouse andmeallika plugin Grafana 4.6+. Olime pidanud seda veidi kohandama, et suurendada SQL filtrite töötlemise efektiivsust juhtpaneelil.

NĂ€iteks, me kasutame muutujaid ja kui need pole filtervĂ€ljas mÀÀratud, siis tahaksime, et see ei genereeriks WHERE tingimust kujul ( uriStem = » AND uriStem != » ). Sellisel juhul loeb ClickHouse veergu uriStem. Üldiselt proovisime erinevaid variante ja lĂ”puks kohandasime plugina (makro $valueIfEmpty), et tĂŒhi vÀÀrtus tagastaks 1, ilma et veerg oleks mainitud.

Ja nĂŒĂŒd saab kasutada sellist pĂ€ringut graafiku jaoks

$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 lisandub selliseks SQL-iks (pange tĂ€hele, et tĂŒhjad vĂ€ljad uriStem muudetakse lihtsalt 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

KokkuvÔte

ClickHouse'i andmebaasi ilmumine on turul olnud mĂ€rgiliseks sĂŒndmuseks. Raskusi oli kujutada, et tĂ€iesti tasuta saame hetkega tĂ”husa ja praktilise tööriista suurte andmete töötlemiseks. Kindlasti, vajaduste suurenedes (nt sharding ja replikeerimine mitmele serverile) muutub skeem keerulisemaks. Kuid esialgse mulje kohaselt on selle andmebaasiga töötamine vĂ€ga naudinng. On nĂ€ha, et toode on loodud 'inimeste' jaoks.

VĂ”rreldes ElasticSearchiga, vĂ€heneb logide sĂ€ilitamise ja töötlemise kulu, esialgsete hindamiste kohaselt, viis kuni kĂŒmme korda. TeisisĂ”nu, kui praeguste andmemahtude jaoks pidime seadistama mitu masinat, siis ClickHouse'i kasutamise korral piisab meile ĂŒhest madala jĂ”udlusega masinast. Jah, kindlasti, ElasticSearchil on ka mehhanismid andmete kokkusurumiseks kettale ja muid funktsioone, mis vĂ”imaldavad mĂ€rkimisvÀÀrselt vĂ€hendada ressursside tarbimist, kuid ClickHouse'i puhul kulub rohkem ressursse.

Ilma igasuguste eriliste optimeerimisteta ning vaikeseadetel töötavad andmete laadimine ja andmebaasist valimine vapustava kiirusena. Andmeid on meil veel vĂ€he (umbes 200 miljonit kirjet), kuid server on nĂ”rk. Seda tööriista saame tulevikus kasutada ka teiste eesmĂ€rkide jaoks, mis ei ole seotud logide hoidmisega. NĂ€iteks, lĂ”ppkliendi analĂŒĂŒtikaks, turvalisuse valdkonnas, masinĂ”ppes.

LÔpetuseks mÔned miinused ja plussid.

Miinused

  1. Kirjete laadimine suurte partiidena. See on ĂŒhelt poolt funktsioon, kuid siiski tuleb kasutada lisaelemente kirjete puhvris hoidmiseks. See ĂŒlesanne ei ole alati lihtne, kuid ikkagi lahendatav. Ja sooviks sisemise skeemi lihtsustada.
  2. MĂ”ned eksootilised funktsioonid vĂ”i uued omadused katkevad sageli uutes versioonides. See tekitab muret, vĂ€hendades soovi uuendada uuele versioonile. NĂ€iteks Kafka tabelimootor – vĂ€ga kasulik omadus, mis vĂ”imaldab otse lugeda sĂŒndmusi Kafkast ilma tarbijate rakendamiseta. Kuid arvestades GitHubi probleemide arvu, oleme seni ettevaatlikud selle mootori kasutamisega tootmises. Siiski, kui mitte teha jĂ€rske samme ning kasutada pĂ”hifunktsioone, töötab see stabiilselt.

Plussid

  1. Ei aeglusta.
  2. Madala sisenemisbarjÀÀriga.
  3. Avatud lÀhtekoodiga.
  4. Taas tasuta.
  5. HÀsti skaleerub (shardimine / replikatsioon "karbist vÀlja")
  6. Sisaldub Venemaa tarkvara registris, mida Soovitab MinKommunikatsioon.
  7. Yandexi ametlik toe olemasolu.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster