ClickHouse Database for Humans tai Alien Technologies

Aleksei Lizunov, MKB:n tietotekniikan osaston etäpalvelukanavien osaamiskeskuksen johtaja

ClickHouse Database for Humans tai Alien Technologies

Vaihtoehtona ELK-pinolle (ElasticSearch, Logstash, Kibana) tutkimme ClickHouse-tietokannan käyttöä lokien tietovarastona.

Tässä artikkelissa haluamme kertoa kokemuksistamme ClickHouse-tietokannan käytöstä ja pilottitoiminnan alustavista tuloksista. On heti huomattava, että tulokset olivat vaikuttavia.


ClickHouse Database for Humans tai Alien Technologies

Seuraavaksi kuvailemme yksityiskohtaisemmin, kuinka järjestelmämme on konfiguroitu ja mistä komponenteista se koostuu. Mutta nyt haluaisin puhua hieman tästä tietokannasta kokonaisuutena ja miksi siihen kannattaa kiinnittää huomiota. ClickHouse-tietokanta on Yandexin tehokas analyyttinen saraketietokanta. Sitä käytetään Yandex-palveluissa, alun perin se on Yandex.Metrican tärkein tietojen tallennuspaikka. Avoimen lähdekoodin järjestelmä, ilmainen. Kehittäjän näkökulmasta olen aina ihmetellyt, kuinka he sen toteuttavat, koska dataa on fantastisen paljon. Ja Metrican käyttöliittymä itsessään on erittäin joustava ja nopea. Ensimmäisellä tutustumisella tähän tietokantaan, vaikutelma on: "No, vihdoin! Tehty ihmisiä varten! Alkaen asennusprosessista ja päättyen pyyntöjen lähettämiseen.

Tällä tietokannalla on erittäin alhainen pääsykynnys. Jopa keskimäärin taitava kehittäjä voi asentaa tämän tietokannan muutamassa minuutissa ja aloittaa sen käytön. Kaikki toimii selkeästi. Jopa ihmiset, jotka ovat uusia Linuxin käyttäjiä, voivat hoitaa asennuksen nopeasti ja tehdä yksinkertaisimmatkin toiminnot. Jos aiemmin sanoilla Big Data, Hadoop, Google BigTable, HDFS, tavallisella kehittäjällä oli ajatuksia, että kyse oli joistakin teratavuista, petatavuista, että jotkut yli-ihmiset ovat tekemisissä näiden järjestelmien asetuksissa ja kehittämisessä, niin ClickHousen tultua tietokanta, saimme yksinkertaisen, ymmärrettävän työkalun, jolla voit ratkaista aiemmin saavuttamattomia tehtäviä. Asennus kestää vain yhden melko keskimääräisen koneen ja viisi minuuttia. Eli meillä on sellainen tietokanta kuin esimerkiksi MySql, mutta vain miljardien tietueiden tallentamiseen! Tietty superarkistaattori SQL-kielellä. Se on kuin ihmisille annettaisiin muukalaisten aseet.

Tietoja lokijärjestelmästämme

Tietojen keräämiseen käytetään standardimuotoisten web-sovellusten IIS-lokitiedostoja (parsiamme myös sovelluslokeja, mutta pilottivaiheen päätavoitteena on kerätä IIS-lokeja).

Eri syistä emme päässeet kokonaan luopumaan ELK-pinosta, vaan käytämme edelleen LogStash- ja Filebeat-komponentteja, jotka ovat osoittautuneet hyvin ja toimivat varsin luotettavasti ja ennustettavasti.

Yleinen kirjauskaavio on esitetty alla olevassa kuvassa:

ClickHouse Database for Humans tai Alien Technologies

Datan kirjoittamisen ominaisuus ClickHouse-tietokantaan on harvinainen (kerran sekunnissa) tietueiden lisääminen suuriin eriin. Tämä on ilmeisesti "ongelmallisin" osa, jonka kohtaat, kun koet ensimmäisen kerran työskennellessäsi ClickHouse-tietokannan kanssa: järjestelmästä tulee hieman monimutkaisempi.
LogStashin lisäosa, joka lisää tiedot suoraan ClickHouseen, auttoi tässä paljon. Tämä komponentti on otettu käyttöön samassa palvelimessa kuin itse tietokanta. Yleisesti ottaen sitä ei siis suositella, vaan käytännön näkökulmasta, jotta ei muodostu erillisiä palvelimia, kun se otetaan käyttöön samalla palvelimella. Emme havainneet vikoja tai resurssiristiriitoja tietokannan kanssa. Lisäksi on huomattava, että laajennuksessa on uudelleenyritysmekanismi virheiden varalta. Ja jos ilmenee virheitä, laajennus kirjoittaa levylle joukon tietoja, joita ei voitu lisätä (tiedostomuoto on kätevä: muokkaamisen jälkeen voit helposti lisätä korjatun erän clickhouse-client-sovelluksella).

Täydellinen luettelo järjestelmässä käytetyistä ohjelmistoista on esitetty taulukossa:

Luettelo käytetyistä ohjelmistoista

Nimi

Kuvaus

Linkki jakeluun

nginx

Käänteinen välityspalvelin rajoittaa porttien käyttöä ja järjestää valtuutuksen

Ei tällä hetkellä käytössä järjestelmässä

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

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

FileBeat

Tiedostolokien siirto.

https://www.elastic.co/downloads/beats/filebeat (jakelusarja Windows 64-bittiselle käyttöjärjestelmälle).

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

logstash

Hirsien keräilijä.

Käytetään lokien keräämiseen FileBeatista sekä lokien keräämiseen RabbitMQ-jonosta (palvelimille, jotka ovat DMZ:ssä.)

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

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

Logstash-output-clickhouse

Loagstash-laajennus lokien siirtämiseen ClickHouse-tietokantaan erissä

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

Napsauta taloa

Tukkivarasto 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

Huomautus. Elokuusta 2018 alkaen RHEL:n "normaalit" rpm-koontiversiot ilmestyivät Yandex-tietovarastoon, joten voit yrittää käyttää niitä. Asennushetkellä käytimme Altinityn valmistamia paketteja.

grafana

Lokin visualisointi. Kojetaulujen määrittäminen

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 Bit) - uusin versio

ClickHouse-tietolähde Grafana 4.6+:lle

Grafana-laajennus ClickHouse-tietolähteellä

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

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

logstash

Kirjaa reititin FileBeatista RabbitMQ-jonoon.

Huomautus. Valitettavasti FileBeat ei tulosta suoraan RabbitMQ:lle, joten välilinkki Logstashin muodossa tarvitaan

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

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

RabbitMQ

viestijono. Tämä on lokipuskuri DMZ:ssä

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 (pakollinen RabbitMQ:lle)

Erlang-ajoaika. Vaaditaan, jotta RabbitMQ toimii

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

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

Palvelimen kokoonpano ClickHouse-tietokannan kanssa on esitetty seuraavassa taulukossa:

Nimi

Arvo

Huomata

kokoonpano

Kiintolevy: 40GB
RAM: 8GB
Prosessori: Core 2 2GHz

On syytä kiinnittää huomiota ClickHouse-tietokannan käyttövinkkeihin (https://clickhouse.yandex/docs/ru/operations/tips/)

Yleinen järjestelmäohjelmisto

Käyttöjärjestelmä: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Kuten näet, tämä on tavallinen työasema.

Lokkien varastointitaulukon rakenne on seuraava:

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;

Käytämme oletusosiointia (kuukausittain) ja indeksin tarkkuutta. Kaikki kentät vastaavat käytännössä IIS-lokimerkintöjä http-pyyntöjen kirjaamiseen. Huomaamme erikseen, että utm-tunnisteiden tallentamiseen on erilliset kentät (ne jäsennetään siinä vaiheessa, kun ne lisätään taulukkoon kyselymerkkijonokentästä).

Lisäksi taulukkoon on lisätty useita järjestelmäkenttiä tietojen tallentamiseksi järjestelmistä, komponenteista ja palvelimista. Katso alla olevasta taulukosta näiden kenttien kuvaus. Yhteen taulukkoon tallennamme useiden järjestelmien lokit.

Nimi

Kuvaus

Esimerkki

fld_app_name

Sovelluksen/järjestelmän nimi
Kelvolliset arvot:

  • site1.domain.com Ulkoinen sivusto 1
  • site2.domain.com Ulkoinen sivusto 2
  • internal-site1.domain.local Sisäinen sivusto 1

site1.domain.com

fld_app_module

Järjestelmämoduuli
Kelvolliset arvot:

  • web - Verkkosivusto
  • svc - Web-sivustopalvelu
  • intgr - Integration Web Service
  • bo - Järjestelmänvalvoja (BackOffice)

verkko

fld_sivuston_nimi

Sivuston nimi IIS:ssä

Yhdelle palvelimelle voidaan ottaa käyttöön useita järjestelmiä tai jopa useita yhden järjestelmämoduulin esiintymiä

web pää

fld_palvelimen_nimi

Palvelimen nimi

web1.domain.com

fld_loki_tiedoston_nimi

Polku palvelimella olevaan lokitiedostoon

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Tämän avulla voit rakentaa kaavioita tehokkaasti Grafanassa. Voit esimerkiksi tarkastella pyyntöjä tietyn järjestelmän käyttöliittymästä. Tämä on samanlainen kuin Yandex.Metrican sivustolaskuri.

Tässä muutamia tilastoja tietokannan käytöstä kahden kuukauden ajalta.

Tietueiden lukumäärä järjestelmien ja niiden komponenttien mukaan

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

Levyllä olevan tiedon määrä

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.

Tietojen pakkausaste sarakkeissa

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.

Kuvaus käytetyistä komponenteista

FileBeat. Tiedostolokien siirtäminen

Tämä komponentti seuraa muutoksia levyllä oleviin lokitiedostoihin ja välittää tiedot LogStashiin. Asennettu kaikille palvelimille, joille lokitiedostoja kirjoitetaan (yleensä IIS). Toimii häntätilassa (eli siirtää vain lisätyt tietueet tiedostoon). Mutta erikseen se voidaan määrittää siirtämään kokonaisia ​​tiedostoja. Tästä on hyötyä, kun sinun on ladattava tietoja edellisiltä kuukausilta. Laita lokitiedosto kansioon ja se lukee sen kokonaisuudessaan.

Kun palvelu lopetetaan, tietoja ei enää siirretä edelleen tallennustilaan.

Esimerkkikokoonpano näyttää tältä:

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. Hirsikerääjä

Tämä komponentti on suunniteltu vastaanottamaan lokimerkintöjä FileBeatista (tai RabbitMQ-jonon kautta), jäsentämään ja lisäämään eriä ClickHouse-tietokantaan.

ClickHouseen lisäämiseen käytetään Logstash-output-clickhouse-laajennusta. Logstash-laajennuksessa on pyyntöjen uudelleenyritysmekanismi, mutta tavallisella sammutuksella on parempi lopettaa itse palvelu. Pysäytettynä viestit kerääntyvät RabbitMQ-jonoon, joten jos pysähdys kestää pitkään, on parempi pysäyttää Filebeats palvelimilla. Kaavassa, jossa RabbitMQ:ta ei käytetä (paikallisessa verkossa Filebeat lähettää lokit suoraan Logstashille), Filebeats toimii varsin hyväksyttävästi ja turvallisesti, joten heille lähdön puuttuminen kulkee ilman seurauksia.

Esimerkkikokoonpano näyttää tältä:

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

Kaikkien järjestelmien lokit tallennetaan yhteen taulukkoon (katso artikkelin alussa). Se on tarkoitettu tallentamaan tietoja pyynnöistä: kaikki parametrit ovat samanlaisia ​​eri muodoissa, kuten IIS-lokeissa, apache- ja nginx-lokeissa. Sovelluslokeille, joihin tallennetaan esimerkiksi virheitä, tietoviestejä, varoituksia, järjestetään erillinen taulukko sopivalla rakenteella (tällä hetkellä suunnitteluvaiheessa).

Taulukkoa suunniteltaessa on erittäin tärkeää päättää ensisijainen avain (jonka mukaan tiedot lajitellaan tallennuksen aikana). Tietojen pakkausaste ja kyselyn nopeus riippuvat tästä. Esimerkissämme avain on
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Eli järjestelmän nimen, järjestelmäkomponentin nimen ja tapahtuman päivämäärän mukaan. Aluksi tapahtuman päivämäärä oli ensin. Kun se oli siirretty viimeiseen paikkaan, kyselyt alkoivat toimia noin kaksi kertaa nopeammin. Ensisijaisen avaimen muuttaminen edellyttää taulukon luomista uudelleen ja tietojen lataamista uudelleen, jotta ClickHouse lajittelee tiedot uudelleen levyllä. Tämä on raskas operaatio, joten on hyvä ajatus miettiä paljon, mitä lajitteluavaimeen pitäisi sisällyttää.

On myös huomattava, että LowCardinality-tietotyyppi on esiintynyt suhteellisen uusissa versioissa. Sitä käytettäessä pakattujen tietojen koko pienenee huomattavasti niille kentille, joilla on alhainen kardinaliteetti (vähän vaihtoehtoja).

Versio 19.6 on tällä hetkellä käytössä ja aiomme yrittää päivittää uusimpaan versioon. Niissä on sellaisia ​​upeita ominaisuuksia kuin esimerkiksi Adaptive Granularity, Skipping-indeksit ja DoubleDelta-koodekki.

Asennuksen aikana lokikirjaustasoksi asetetaan oletusarvoisesti jäljitys. Lokeja pyöritetään ja arkistoidaan, mutta samalla ne laajenevat jopa gigatavuun. Jos tarvetta ei ole, voit asettaa varoitustason, jolloin puun koko pienenee huomattavasti. Kirjausasetus on määritetty config.xml-tiedostossa:

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

Muutamia hyödyllisiä komentoja

Поскольку оригинальные пакеты установки собираются по 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. Kirjaa reititin FileBeatista RabbitMQ-jonoon

Tätä komponenttia käytetään FileBeatista tulevien lokien reitittämiseen RabbitMQ-jonoon. Tässä on kaksi kohtaa:

  1. Valitettavasti FileBeatilla ei ole ulostulolaajennusta, joka kirjoittaa suoraan RabbitMQ:hen. Ja tällaista toimivuutta heidän githubin ongelmasta päätellen ei ole suunniteltu toteutettavaksi. Kafkalle on lisäosa, mutta emme jostain syystä voi käyttää sitä kotona.
  2. DMZ:ssä on lokien keräämistä koskevia vaatimuksia. Niiden perusteella lokit on ensin lisättävä jonoon ja sitten LogStash lukee merkinnät jonosta ulkopuolelta.

Siksi siinä tapauksessa, että palvelimet sijaitsevat DMZ:ssä, on käytettävä tällaista hieman monimutkaista järjestelmää. Esimerkkikokoonpano näyttää tältä:

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

Tätä komponenttia käytetään puskuroimaan lokimerkinnät DMZ:ssä. Nauhoitus tehdään Filebeat → LogStashin avulla. Lukeminen tapahtuu DMZ:n ulkopuolelta LogStashin kautta. RabboitMQ:n kautta toimittaessa käsitellään noin 4 tuhatta viestiä sekunnissa.

Viestien reititys määritetään järjestelmän nimen mukaan eli FileBeat-määritystietojen perusteella. Kaikki viestit menevät yhteen jonoon. Jos jonotuspalvelu jostain syystä pysäytetään, tämä ei johda viestien katoamiseen: FileBeats vastaanottaa yhteysvirheet ja keskeyttää lähettämisen väliaikaisesti. Ja jonosta lukeva LogStash saa myös verkkovirheitä ja odottaa yhteyden palautumista. Tässä tapauksessa tietoja ei tietenkään enää kirjoiteta tietokantaan.

Seuraavia ohjeita käytetään jonojen luomiseen ja määrittämiseen:

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

Tätä komponenttia käytetään monitorointitietojen visualisointiin. Tässä tapauksessa sinun on asennettava ClickHouse-tietolähde Grafana 4.6+ -laajennukselle. Meidän piti säätää sitä hieman parantaaksemme SQL-suodattimien käsittelyn tehokkuutta kojelaudalla.

Käytämme esimerkiksi muuttujia, ja jos niitä ei ole asetettu suodatinkenttään, niin haluamme, ettei se luo ehtoa lomakkeen WHERE-kenttään ( uriStem = » AND uriStem != » ). Tässä tapauksessa ClickHouse lukee uriStem-sarakkeen. Yleensä kokeilimme eri vaihtoehtoja ja lopulta korjasimme laajennuksen ($valueIfEmpty-makro) niin, että tyhjän arvon tapauksessa se palauttaa arvon 1 mainitsematta itse saraketta.

Ja nyt voit käyttää tätä kyselyä kaaviossa

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

joka tarkoittaa tätä SQL:ää (huomaa, että tyhjät uriStem-kentät on muunnettu vain 1:ksi)

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

Johtopäätös

ClickHouse-tietokannan ilmestymisestä on tullut markkinoiden maamerkkitapahtuma. Oli vaikea kuvitella, että olimme hetkessä aseistettu täysin maksutta tehokkaalla ja käytännöllisellä työkalulla big datan käsittelyyn. Tietenkin, kun tarpeet kasvavat (esimerkiksi jakaminen ja replikointi useille palvelimille), järjestelmästä tulee monimutkaisempi. Mutta ensivaikutelman perusteella työskentely tämän tietokannan kanssa on erittäin miellyttävää. Voidaan nähdä, että tuote on tehty "ihmisiä varten".

ElasticSearchiin verrattuna lokien säilytys- ja käsittelykustannusten arvioidaan laskevan viidestä kymmeneen kertaan. Toisin sanoen, jos nykyiselle datamäärälle joutuisi perustamaan usean koneen klusteri, niin ClickHousea käytettäessä yksi pienitehoinen kone riittää meille. Kyllä, tietysti ElasticSearchilla on myös levyllä olevia tietojen pakkausmekanismeja ja muita ominaisuuksia, jotka voivat vähentää resurssien kulutusta merkittävästi, mutta ClickHouseen verrattuna tämä tulee kalliimmaksi.

Ilman erityisiä optimointejamme, oletusasetuksilla tietojen lataaminen ja valinta tietokannasta toimii hämmästyttävän nopeasti. Meillä ei ole vielä paljon dataa (noin 200 miljoonaa tietuetta), mutta itse palvelin on heikko. Voimme käyttää tätä työkalua jatkossa muihin tarkoituksiin, jotka eivät liity lokien tallentamiseen. Esimerkiksi päästä päähän -analytiikkaan turvallisuuden, koneoppimisen alalla.

Lopuksi vähän plussat ja miinukset.

Miinukset

  1. Ladataan tietueita suurissa erissä. Toisaalta tämä on ominaisuus, mutta sinun on silti käytettävä lisäkomponentteja tietueiden puskurointiin. Tämä tehtävä ei ole aina helppo, mutta silti ratkaistavissa. Ja haluaisin yksinkertaistaa järjestelmää.
  2. Jotkut eksoottiset toiminnot tai uudet ominaisuudet rikkoutuvat usein uusissa versioissa. Tämä aiheuttaa huolta ja vähentää halukkuutta päivittää uuteen versioon. Esimerkiksi Kafka-taulukkomoottori on erittäin hyödyllinen ominaisuus, jonka avulla voit lukea tapahtumia suoraan Kafkasta ilman kuluttajien käyttöönottoa. Mutta githubin ongelmien määrän perusteella olemme edelleen varovaisia, ettemme käytä tätä moottoria tuotannossa. Jos et kuitenkaan tee äkillisiä eleitä sivulle ja käytä päätoimintoa, se toimii vakaasti.

Pros

  1. Ei hidasta.
  2. Alhainen tulokynnys.
  3. Avoin lähdekoodi.
  4. Se on ilmainen.
  5. Skaalautuu hyvin (sharjoittelu/replikointi valmiina)
  6. Sisältyy viestintäministeriön suosittelemaan venäläisten ohjelmistojen rekisteriin.
  7. Yandexin virallisen tuen läsnäolo.

Lähde: will.com

Lisää kommentti