ClickHouse Database for Humans edo Alien Technologies

Aleksey Lizunov, MKBko Informazio Teknologien Zuzendaritzako Urruneko Zerbitzu Kanaletarako Konpetentzia Zentroko burua.

ClickHouse Database for Humans edo Alien Technologies

ELK pila (ElasticSearch, Logstash, Kibana) alternatiba gisa, ClickHouse datu-basea erregistroetarako datu biltegi gisa erabiltzeko ikerketa egiten ari gara.

Artikulu honetan, ClickHouse datu-basea erabiltzeko dugun esperientziaz eta operazio pilotuaren aurretiazko emaitzei buruz hitz egin nahi dugu. Berehala esan behar da emaitzak ikusgarriak izan zirela.


ClickHouse Database for Humans edo Alien Technologies

Jarraian, gure sistema nola konfiguratuta dagoen eta zer osagaiz osatuta dagoen deskribatuko dugu zehatzago. Baina orain datu-base honi buruz apur bat hitz egin nahiko nuke bere osotasunean, eta zergatik merezi duen arreta jartzea. ClickHouse datu-basea Yandex-en errendimendu handiko zutabe-datu-base analitikoa da. Yandex zerbitzuetan erabiltzen da, hasieran Yandex.Metrica-ren datu biltegiratze nagusia da. Kode irekiko sistema, doakoa. Garatzaile baten ikuspuntutik, beti galdetu izan diot nola inplementatu zuten, datu izugarri handiak daudelako. Eta Metrica-ren erabiltzaile-interfazea bera oso malgua eta azkarra da. Datu-base hau lehen ezagutzean, inpresioa hauxe da: “Beno, azkenean! Herriarentzat egina! Instalazio prozesutik hasi eta eskaerak bidaltzen amaitu.

Datu-base honek sarrera-atalase oso baxua du. Batez besteko trebea den garatzaile batek ere datu-base hau instalatu dezake minutu gutxitan eta erabiltzen hasi. Dena argi eta garbi funtzionatzen du. Linux-en berriak diren pertsonek ere azkar kudeatu dezakete instalazioa eta eragiketa errazenak egin. Lehenago, Big Data, Hadoop, Google BigTable, HDFS hitzekin, garatzaile arrunt batek terabyte batzuei buruz, petabytei buruz, supergizaki batzuek sistema hauen ezarpenetan eta garapenean parte hartzen duten ideiak bazituen, orduan ClickHouse-ren etorrerarekin. datu-basea, tresna sinple eta ulergarri bat lortu dugu, zeinekin aurrez lortu ezin diren zeregin sorta bat ebazteko. Batez besteko makina bat eta bost minutu besterik ez dira behar instalatzeko. Hau da, adibidez, MySql bezalako datu-base bat lortu dugu, baina soilik milioika erregistro gordetzeko! SQL lengoaia duen super-artxibotzaile jakin bat. Jendeari atzerritarren armak eman zizkioten bezala da.

Gure erregistro-sistemari buruz

Informazioa biltzeko, formatu estandarreko web aplikazioen IIS erregistro-fitxategiak erabiltzen dira (gaur egun aplikazioen erregistroak aztertzen ari gara, baina fase pilotuan helburu nagusia IIS erregistroak biltzea da).

Hainbat arrazoirengatik, ezin izan dugu ELK pila erabat alde batera utzi, eta LogStash eta Filebeat osagaiak erabiltzen jarraitzen dugu, ondo frogatu duten eta nahiko fidagarri eta aurreikusteko funtzionatzen dutenak.

Erregistro-eskema orokorra beheko irudian ageri da:

ClickHouse Database for Humans edo Alien Technologies

ClickHouse datu-basean datuak idazteko ezaugarri bat sarritan (segundoko behin) erregistroak lote handietan sartzea da. Hau da, itxuraz, ClickHouse datu-basearekin lan egiten duzunean aurkitzen duzun zatirik "problematikoena": eskema pixka bat konplikatu egiten da.
ClickHouse-n datuak zuzenean txertatzen dituen LogStash-en pluginak asko lagundu zuen hemen. Osagai hau datu-basearen beraren zerbitzari berean zabaltzen da. Beraz, oro har, ez da gomendagarria egitea, ikuspuntu praktikotik baizik, zerbitzari berean hedatuta dagoen bitartean zerbitzari bereiziak ez sortzeko. Ez dugu datu-basearekin hutsegiterik edo baliabide-gatazkarik ikusi. Horrez gain, kontuan izan behar da pluginak akatsen kasuan berriro saiatzeko mekanismoa duela. Eta akatsen kasuan, pluginak txertatu ezin diren datu sorta bat idazten du diskoan (fitxategiaren formatua komeni da: editatu ondoren, erraz txertatu dezakezu zuzendutako sorta clickhouse-client erabiliz).

Eskeman erabilitako software-zerrenda osoa taulan aurkezten da:

Erabilitako software-zerrenda

Izena

Description

Banaketa esteka

nginx

Alderantzizko proxy portuen sarbidea mugatzeko eta baimena antolatzeko

Gaur egun ez da eskeman erabiltzen

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

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

FileBeat

Fitxategien erregistroen transferentzia.

https://www.elastic.co/downloads/beats/filebeat (banaketa kit Windows 64bit-erako).

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

logstash

Erregistro-biltzailea.

FileBeat-en erregistroak biltzeko erabiltzen da, baita RabbitMQ ilararen erregistroak biltzeko ere (DMZn dauden zerbitzarietarako).

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

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

Logstash-output-clickhouse

Loagstash plugina erregistroak ClickHouse datu-basera loteka transferitzeko

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

Erregistro biltegiratzea 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

Ohar. 2018ko abuztutik aurrera, RHEL-erako rpm eraikitze "normalak" Yandex biltegian agertu ziren, haiek erabiltzen saia zaitezke. Instalazio garaian, Altinity-k eraikitako paketeak erabiltzen ari ginen.

Grafana

Erregistroen bistaratzea. Aginte-panelak konfiguratzea

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 bit) - azken bertsioa

ClickHouse datu-iturria Grafana 4.6+erako

Grafanarako plugina ClickHouse datu-iturburuarekin

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

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

logstash

Erregistratu bideratzailea FileBeat-etik RabbitMQ ilarara.

Ohar. Zoritxarrez, FileBeat-ek ez du zuzenean ateratzen RabbitMQ-ra, beraz, Logstash moduko tarteko esteka bat behar da

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

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

RabbitMQ

mezu-ilara. Hau DMZko erregistro-buffera da

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 (Derrigorrezkoa RabbitMQ-rako)

Erlang exekuzioa. Beharrezkoa da RabbitMQ-k funtziona dezan

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

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

ClickHouse datu-basearekin zerbitzariaren konfigurazioa taula honetan aurkezten da:

Izena

Balio

Kontuan izan

konfigurazioa

Diskoa: 40 GB
RAM: 8GB
Prozesadorea: Core 2 2Ghz

ClickHouse datu-basea funtzionatzeko aholkuei erreparatu behar zaie (https://clickhouse.yandex/docs/ru/operations/tips/)

Sistema orokorraren softwarea

OS: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Ikus dezakezunez, lan-estazio arrunt bat da.

Erregistroak gordetzeko taularen egitura honakoa da:

log_web.sql

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

Partizio lehenetsia (hilabeteka) eta indizearen granulartasuna erabiltzen ditugu. Eremu guztiak ia IIS erregistroko sarrerei dagozkie http eskaerak erregistratzeko. Bereiz, ohartzen gara utm-tags gordetzeko eremu bereiziak daudela (kontsulta-katearen eremutik taulan txertatzeko fasean analizatzen dira).

Era berean, sistemaren hainbat eremu gehitu dira taulara sistemei, osagaiei, zerbitzariei buruzko informazioa gordetzeko. Ikus beheko taula eremu hauen deskribapena lortzeko. Taula batean, hainbat sistemaren erregistroak gordetzen ditugu.

Izena

Description

Adibidea

fld_app_izena

Aplikazio/sistemaren izena
Baliozko balioak:

  • site1.domain.com Kanpoko gunea 1
  • site2.domain.com Kanpoko gunea 2
  • barne-gunea1.domeinua.local Barne-gunea 1

gune1.domeinua.com

fld_app_module

Sistemaren modulua
Baliozko balioak:

  • web - Webgunea
  • svc - Webgunearen zerbitzua
  • intgr - Integrazio Web Zerbitzua
  • bo - Administratzailea (BackOffice)

web

fld_webgune_izena

Gunearen izena IISen

Hainbat sistema inplementa daitezke zerbitzari batean, edo baita sistema modulu bateko hainbat instantzia ere

web nagusia

fld_zerbitzari_izena

Zerbitzariaren izena

web1.domeinua.com

fld_log_file_name

Zerbitzariko erregistro-fitxategirako bidea

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Horri esker, grafikoak eraginkortasunez eraiki ditzakezu Grafanan. Adibidez, ikusi sistema jakin baten frontend-eko eskaerak. Yandex.Metrica-ko gune-kontagailuaren antzekoa da.

Hona hemen bi hilabetez datu-basearen erabilerari buruzko estatistika batzuk.

Sistemen eta haien osagaien arabera banatutako erregistro kopurua

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

Diskoan dagoen datu kopurua

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

Datuen konpresio-maila zutabeetan

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

Erabilitako osagaien deskribapena

FileBeat. Fitxategien erregistroak transferitzea

Osagai honek erregistro-fitxategien aldaketen jarraipena egiten du diskoan eta informazioa LogStash-era pasatzen du. Erregistro fitxategiak idazten diren zerbitzari guztietan instalatuta (normalean IIS). Buztan moduan funtzionatzen du (hau da, gehitutako erregistroak fitxategira soilik transferitzen ditu). Baina bereizita fitxategi osoak transferitzeko konfigura daiteke. Hau erabilgarria da aurreko hilabeteetako datuak deskargatu behar dituzunean. Jarri erregistro-fitxategia karpeta batean eta osorik irakurriko du.

Zerbitzua gelditzen denean, datuak ez dira gehiago biltegiratzera transferitzen.

Konfigurazio adibide bat honelakoa da:

filebeat.yml

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

logstash. Erregistro-biltzailea

Osagai hau FileBeat-etik (edo RabbitMQ ilararen bidez) erregistro-sarrerak jasotzeko diseinatuta dago, ClickHouse datu-basean loteak analizatuz eta txertatuz.

ClickHousen txertatzeko, Logstash-output-clickhouse plugina erabiltzen da. Logstash pluginak eskaera berriro saiatzeko mekanismoa du, baina ohiko itzaliarekin, hobe da zerbitzua bera geldiaraztea. Gelditzen denean, mezuak RabbitMQ ilaran pilatuko dira, beraz, geldialdia denbora luzez bada, hobe da Filebeats-ek zerbitzarietan gelditzea. RabbitMQ erabiltzen ez den eskema batean (sare lokalean, Filebeat-ek zuzenean Logstash-era bidaltzen ditu erregistroak), Filebeats-ek nahiko onargarri eta seguru funtzionatzen du, beraz, beraientzat irteeraren erabilgarritasunik eza ondoriorik gabe pasatzen da.

Konfigurazio adibide bat honelakoa da:

log_web__filebeat_clickhouse.conf

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

hodiak.yml

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

clickhouse. Erregistro biltegiratzea

Sistema guztien erregistroak taula batean gordetzen dira (ikus artikuluaren hasieran). Eskaerei buruzko informazioa gordetzeko xedea da: parametro guztiak antzekoak dira formatu desberdinetarako, hala nola IIS erregistroak, apache eta nginx erregistroak. Aplikazioen erregistroetarako, zeinetan, adibidez, akatsak, informazio-mezuak, abisuak erregistratzen diren, egitura egokia duen taula bereizi bat emango da (gaur egun diseinu-fasean).

Taula bat diseinatzerakoan, oso garrantzitsua da gako nagusia erabakitzea (horren bidez ordenatuko dira datuak biltegiratzean). Datuen konpresio-maila eta kontsulta-abiadura horren araberakoak dira. Gure adibidean, gakoa da
ORDENATU (fld_app_name, fld_app_module, logdatetime)
Hau da, sistemaren izenaren, sistemaren osagaiaren izenaren eta gertaeraren dataren arabera. Hasieran, ekitaldiaren data izan zen lehenengo. Azken tokira eraman ondoren, kontsultak bi aldiz azkarrago hasi ziren lanean. Gako nagusia aldatzeko, taula birsortu eta datuak berriro kargatu beharko dira, ClickHouse-k datuak diskoan berriro ordenatu ditzan. Eragiketa astuna da, beraz, ideia ona da ordenatzeko gakoan zer sartu behar den asko pentsatzea.

Kontuan izan behar da, gainera, LowCardinality datu-mota nahiko agertu dela azken bertsioetan. Erabiltzean, konprimitutako datuen tamaina izugarri murrizten da kardinaltasun txikia duten eremuetarako (aukera gutxi).

19.6 bertsioa erabiltzen ari da eta azken bertsiora eguneratzen saiatzeko asmoa dugu. Ezaugarri zoragarriak dituzte, esaterako, Adaptive Granularity, Skipping indexes eta DoubleDelta codec-a, adibidez.

Lehenespenez, instalazioan zehar, erregistro-maila trazatzeko ezartzen da. Erregistroak biratu eta artxibatu egiten dira, baina aldi berean gigabyte batera hedatzen dira. Beharrik ez badago, abisu-maila ezar dezakezu, orduan erregistroaren tamaina ikaragarri murriztuko da. Erregistroaren ezarpena config.xml fitxategian ezartzen da:

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

Komando erabilgarria batzuk

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

logstash. Erregistratu bideratzailea FileBeat-etik RabbitMQ ilarara

Osagai hau FileBeat-etik datozen erregistroak RabbitMQ ilara bideratzeko erabiltzen da. Hemen bi puntu daude:

  1. Zoritxarrez, FileBeat-ek ez du irteerako pluginik RabbitMQ-ra zuzenean idazteko. Eta funtzionaltasun hori, beren github-eko arazoaren arabera, ez dago inplementatzeko aurreikusita. Kafkarako plugin bat dago, baina arrazoiren batengatik ezin dugu etxean erabili.
  2. DMZn erregistroak biltzeko baldintzak daude. Horietan oinarrituta, erregistroak ilarara gehitu behar dira lehenik eta, ondoren, LogStash-ek ilarako sarrerak kanpotik irakurtzen ditu.

Hori dela eta, zerbitzariak DMZn kokatuta dauden kasuetarako da halako eskema apur bat konplikatua erabili behar dela. Konfigurazio adibide bat honelakoa da:

iis_w3c_logs__filebeat_rabbitmq.conf

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

RabbitMQ. mezu-ilara

Osagai hau DMZko erregistro-sarrerak gordetzeko erabiltzen da. Grabaketa Filebeat → LogStash multzo baten bidez egiten da. Irakurketa DMZ kanpotik egiten da LogStash bidez. RabboitMQ bidez jarduten denean, segundoko 4 mila mezu inguru prozesatzen dira.

Mezuen bideratzea sistemaren izenaren arabera konfiguratzen da, hau da, FileBeat-en konfigurazio-datuetan oinarrituta. Mezu guztiak ilara batera joaten dira. Arrazoiren batengatik ilaran zerbitzua gelditzen bada, horrek ez du mezuak galtzea ekarriko: FileBeats-ek konexio akatsak jasoko ditu eta bidalketa aldi baterako etengo du. Eta ilaratik irakurtzen duen LogStash-ek sareko akatsak ere jasoko ditu eta konexioa leheneratu arte itxarongo du. Kasu honetan, datuak, noski, ez dira gehiago datu-basean idatziko.

Ilarak sortzeko eta konfiguratzeko jarraibide hauek erabiltzen dira:

sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin declare exchange --vhost=/ name=monitor.direct type=direct sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin declare queue --vhost=/ name=web_log durable=true
sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin --vhost="/" declare binding source="monitor.direct" destination_type="queue" destination="web_log" routing_key="site1.domain.ru"
sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin --vhost="/" declare binding source="monitor.direct" destination_type="queue" destination="web_log" routing_key="site2.domain.ru"

Grafana. Aginte-panelak

Osagai hau monitorizazio datuak ikusteko erabiltzen da. Kasu honetan, Grafana 4.6+ pluginerako ClickHouse datu-iturria instalatu behar duzu. Apur bat moldatu behar izan dugu aginte-paneleko SQL iragazkiak prozesatzeko eraginkortasuna hobetzeko.

Esaterako, aldagaiak erabiltzen ditugu, eta iragazkien eremuan ezartzen ez badira, nahi genuke baldintzarik ez sortzea formularioko NON-AN ( uriStem = » ETA uriStem != » ). Kasu honetan, ClickHousek uriStem zutabea irakurriko du. Oro har, aukera desberdinak probatu ditugu eta azkenean plugina ($valueIfEmpty makroa) zuzendu dugu, hutsik dagoen balio baten kasuan 1 itzultzeko, zutabea bera aipatu gabe.

Eta orain kontsulta hau erabil dezakezu grafikorako

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

SQL honetara itzultzen dena (kontuan izan uriStem eremu hutsak 1era soilik bihurtu direla)

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

Ondorioa

ClickHouse datu-basearen agerpena merkatuan mugarri bihurtu da. Zaila zen imajinatzea, guztiz dohainik, istant batean big data-ekin lan egiteko tresna indartsu eta praktiko batekin armatuta geundela. Jakina, beharrak gero eta handiagoak direnez (adibidez, zatiketa eta zerbitzari anitzetan erreplikatzea), eskema zailagoa izango da. Baina lehen inpresioetan, datu-base honekin lan egitea oso atsegina da. Produktua "pertsonentzako" egina dagoela ikus daiteke.

ElasticSearch-ekin alderatuta, erregistroak gordetzeko eta prozesatzeko kostua bost edo hamar aldiz murriztuko dela kalkulatzen da. Beste era batera esanda, uneko datu kopururako hainbat makina multzo bat konfiguratu beharko bagenu, ClickHouse erabiltzean, potentzia baxuko makina bat nahikoa da guretzat. Bai, noski, ElasticSearch-ek ere baditu diskoan datuak konprimitzeko mekanismoak eta baliabideen kontsumoa nabarmen murrizteko beste ezaugarri batzuk, baina ClickHouse-rekin alderatuta, hori garestiagoa izango da.

Gure aldetik optimizazio berezirik gabe, ezarpen lehenetsietan, datuak kargatu eta datu-basetik aukeratzeak abiadura harrigarrian funtzionatzen du. Oraindik ez dugu datu askorik (200 milioi erregistro inguru), baina zerbitzaria bera ahula da. Etorkizunean tresna hau erregistroak gordetzearekin zerikusia ez duten beste helburu batzuetarako erabil dezakegu. Adibidez, muturreko analisirako, segurtasunaren arloan, ikaskuntza automatikoa.

Bukaeran, alde onak eta txarrak buruz pixka bat.

Cons

  1. Erregistroak lote handietan kargatzen. Alde batetik, ezaugarri bat da, baina oraindik osagai osagarriak erabili behar dituzu erregistroak buffererako. Zeregin hau ez da beti erraza, baina oraindik konpon daiteke. Eta eskema sinplifikatu nahiko nuke.
  2. Funtzionalitate exotiko batzuk edo eginbide berri batzuk askotan hautsi egiten dira bertsio berrietan. Horrek kezka eragiten du, bertsio berri batera eguneratzeko gogoa murrizten du. Adibidez, Kafka taula-motorra oso funtzio erabilgarria da, Kafka-ren gertaerak zuzenean irakurtzeko aukera ematen duena, kontsumitzaileak ezarri gabe. Baina github-eko Arazo kopuruaren arabera, oraindik kontuz ibiltzen gara motor hau ekoizpenean ez erabiltzeko. Hala ere, alborako bat-bateko keinurik egiten ez baduzu eta funtzionalitate nagusia erabiltzen ez baduzu, egonkor funtzionatzen du.

Pros

  1. Ez du moteltzen.
  2. Sarrera atalase baxua.
  3. Kode irekia.
  4. Doan.
  5. Ondo eskalatzen da (zatiketa/erreplikatzea kutxatik kanpo)
  6. Komunikazio Ministerioak gomendatutako Errusiako softwarearen erregistroan sartuta dago.
  7. Yandex-en laguntza ofizialaren presentzia.

Iturria: www.habr.com

Gehitu iruzkin berria