BD ClickHouse për njerëzit, ose Teknologjitë e huaja

Aleksej Lizunov, drejtori i qendrës për kompetenca në kanalet e shërbimit të distancës në drejtorinë e teknologjive informative të MKB

BD ClickHouse për njerëzit, ose Teknologjitë e huaja

Si alternativë për grumbullin ELK (ElasticSearch, Logstash, Kibana), ne po zhvillojmë kërkime për përdorimin e DB ClickHouse si një depo për të dhënat e logeve.

NĂ« kĂ«tĂ« artikull do tĂ« doja tĂ« flas pĂ«r pĂ«rvojĂ«n tonĂ« me pĂ«rdorimin e DB ClickHouse dhe pĂ«r rezultatet paraprake nga pilotimi. ËshtĂ« e rĂ«ndĂ«sishme tĂ« theksohet se rezultatet kanĂ« qenĂ« tĂ« shkĂ«lqyera.


BD ClickHouse për njerëzit, ose Teknologjitë e huaja

Më pas do të përshkruajmë më në detaje se si është e organizuar sistemi ynë dhe cilat komponentë përbëjnë atë. Por tani do të doja të flisja pak për këtë DB në përgjithësi dhe pse ia vlen të jepet vëmendje. DB ClickHouse është një DB analitike kolone me performancë të lartë nga Yandex. Përdoret në shërbimet e Yandex, dhe fillimisht është magazina kryesore e të dhënave për Yandex.Metrikën. Sistemi është open-source, falas. Nga këndvështrimi i një zhvilluesi, gjithmonë më ka interesuar si e kanë realizuar ata këtë, sepse ka të dhëna fantastikisht të mëdha. Dhe vetë ndërfaqja e përdoruesit të Metrikës është shumë fleksibile dhe punon shpejt. Në njohjen e parë me këtë DB, ndjesia është: "Më në fund! E bërë 'për njerëzit'! Duke filluar nga procesi i instalimit dhe deri te dërgimi i kërkesave."

Kjo DB ka një prag të ulët hyrjeje. Edhe një zhvillues me kualifikime të mesme mund ta instalojë këtë DB brenda disa minutash dhe të fillojë ta përdorë. çdo gjë funksionon pa probleme. Edhe ata që nuk janë shumë të njohur me Linux, munden ta përfundojnë instalimin dhe të kryejnë operacione të thjeshta mjaft shpejt. Nëse më parë, me fjalët Big Data, Hadoop, Google BigTable, HDFS, një zhvillues i zakonshëm mendonte se fjalët përmbanin ndonjë terabajt, petabajt, dhe se konfigurimi dhe zhvillimi për këto sisteme kërkonte super njerëz, me ardhjen e DB ClickHouse morëm një mjet të thjeshtë dhe të kuptueshëm, me të cilin mund të zgjidhen detyra që ishin të paarritshme më parë. Mjafton vetëm një makinë mesatare dhe pesë minuta për instalim. Pra, morëm një DB si, për shembull, MySql, por vetëm për ruajtjen e miliardave të dhënash! Një super arkivues me gjuhën SQL. Ajo është sikur të kishim dorëzuar njerëzve armë extraterrestrial.

Për sistemin tonë të mbledhjes së logëve

Për mbledhjen e informacionit përdoren skedarë log-esh IIS për aplikacioneve web në format standard (aktualisht po merremi edhe me parsingun e log-eve të aplikacioneve, por qëllimi kryesor në fazën pilot është mbledhja e log-eve IIS).

Nuk mundëm të heqim dorë plotësisht nga staku ELK për arsye të ndryshme, dhe vazhdojmë të përdorim komponentët LogStash dhe Filebeat, të cilët janë provuar mirë dhe funksionojnë mjaft besueshëm dhe parashikueshëm.

Skema e përgjithshme e regjistrimit është e paraqitur në figurën më poshtë:

BD ClickHouse për njerëzit, ose Teknologjitë e huaja

Veçoria e regjistrimit të të dhënave në DB ClickHouse është se regjistrimet futen me ritëm të ulët (një herë në sekondë) në grupe të mëdha. Kjo, duket, është pjesa më 'problematike', me të cilën ndeshesh në eksperiencën e parë me DB ClickHouse: skema paksa komplikohet.
Këtu ndihmoi shumë plugin për LogStash, i cili nguldat të dhënat drejtpërdrejt në ClickHouse. Ky komponent vendoset në të njëjtin server si vetë DB. Ndërsa, përgjithësisht, nuk rekomandohet të bëhet kështu, por nga pikëpamja praktike, për të mos krijuar serverë të veçantë, sa kohë që është vendosur në të njëjtin server. Nuk kemi vërejtur as defekte, as konflikte burimesh me DB-në. Gjithashtu, është e rëndësishme të theksohet se plugin-i ka parashikuar një mekanizëm ritransmetimi në rast gabimesh. Në rast gabimesh, plugin-i shkruan në disk një sasi të dhënash që nuk u arrit të nguliten (formati i skedarit është i përshtatshëm: pasi të jetë rregulluar, është e lehtë të injektohet sasia e rregulluar me ndihmën e clickhouse-client).

Lista e plotë e software-it që përdoret në skemë paraqitet në tabelë:

Lista e përdorur të software-it

Emri

Përshkrimi

Linku për distribuimin

NGINX

Reverse-proxy për kufizimin e aksesit për portet dhe organizimin e autorizimit

Aktualisht nuk përdoret në skemë

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

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

FileBeat

Transferimi i log-ëve të skedarëve.

https://www.elastic.co/downloads/beats/filebeat (distribuimi për Windows 64bit).

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

LogStash

Mblodhësi i log-ëve.

Përdoret për mbledhjen e log-ëve nga FileBeat, si dhe për mbledhjen e log-ëve nga radhët RabbitMQ (për serverët që ndodhen në DMZ).

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

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

Logstash-output-clickhouse

Plugin Loagstash për transferimin e log-ëve në bazën e të dhënave ClickHouse në grumbuj

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

Depo log-ësh 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

Vini re. Që nga gushti 2018, në repositorin e Yandex janë shfaqur ndërrime "normale" RPM për RHEL, prandaj mund të provoni t'i përdorni ato. Në momentin e instalimit kemi përdorur paketat e ndërtuara nga Altinity.

Grafana

Vizualizimi i log-ëve. Konfigurimi i dashboards

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 Bit) – versioni mĂ« i fundit

Burimi i të dhënave ClickHouse për Grafana 4.6+

Plugin për Grafana me burim të dhënash ClickHouse

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

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

LogStash

Routari i log-ëve nga FileBeat në radhën RabbitMQ.

Vini re. Fatkeqësisht, FileBeat nuk ka output direkt në RabbitMQ, prandaj kërkohet një ndërmjetës në formën e Logstash.

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

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

RabbitMQ

Radhë mesazhesh. Ky është një tampon për regjistrat e log-ëve në DMZ

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

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

Erlang Runtime (Kërkohet për RabbitMQ)

Mjedisi i ekzekutimit Erlang. Kërkohet për funksionimin e RabbitMQ

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

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

Konfigurimi i serverit me bazën e të dhënave ClickHouse paraqitet në tabelën e mëposhtme:

Emri

Vlera

Shënim

Konfigurimi

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

Duhet kushtuar vëmendje këshillave për përdorimin e bazës së të dhënave ClickHouse (https://clickhouse.yandex/docs/ru/operations/tips/)

Software sistemik

OS: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Siç duket, kjo është një stacion pune normale.

Struktura e tabelës për ruajtjen e log-ëve duket si më poshtë:

log_web.sql

KRIJO TABELË log_web (
  logdate Data,
  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;

Ne përdorim vlerat e paracaktuara për partiçionimin (për muaj) dhe granolaritetin e indeksit. Të gjitha fushat praktikisht përputhen me regjistrimet e logut IIS për regjistrimin e kërkesave http. Veçanërisht, fushat e veçanta janë për ruajtjen e etiketave utm (ato analizohen gjatë fazës së futjes në tabelë nga fusha e stringut të kërkesës).

Gjithashtu, në tabelë janë shtuar disa fusha sistemike për të ruajtur informacion mbi sistemet, komponentët, serverët. Përshkrimi i këtyre fushave mund të shihet më poshtë në tabelë. Në një tabelë ruajmë logët për disa sisteme.

Emri

Përshkrimi

Shembuj

fld_app_name

Emri i aplikacionit/sistemit
Vlerat e lejuara:

  • site1.domain.com Uebsajti i jashtĂ«m 1
  • site2.domain.com Uebsajti i jashtĂ«m 2
  • internal-site1.domain.local Uebsajti i brendshĂ«m 1

site1.domain.com

fld_app_module

Moduli i sistemit
Vlerat e lejuara:

  • web — Uebsajti
  • svc — ShĂ«rbimi i uebsajtit
  • intgr — ShĂ«rbimi i integrimit
  • bo — Administrata (BackOffice)

web

fld_website_name

Emri i uebsajtit në IIS

Në një server mund të vendosen disa sisteme, ose madje disa ekzemplarë të një moduli sistemi

web-main

fld_server_name

Emri i serverit

web1.domain.com

fld_log_file_name

Rruga te skedari i regjistrit në server

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Kjo lejon ndërtimin efikas të grafikëve në Grafana. Për shembull, shikimin e kërkesave nga frontend-i i një sistemi të caktuar. Kjo është si një numërues në Yandex.Metrica.

Këtu ka disa statistika mbi përdorimin e DB-së për dy muaj.

Numri i regjistrimeve me ndarje sipas sistemeve dhe komponentëve të tyre

Zgjedh
    fld_app_name,
    fld_app_module,
    numri(fld_app_name) SI rows_count
FROM log_web
GRUPO NË
    fld_app_name,
    fld_app_module
    ME TOTAL
RENDITO
    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 │
└──────────────────┮────────────────┮────────────┘
 
Totali:
┌─fld_app_name─┬─fld_app_module─┬─rows_count─┐
│              │                │  210522593 │
└──────────────┮────────────────┮────────────┘
 
11 rreshta në grup. Koha e kaluar: 4.874 sekonda. Procesuar 210.52 milion rreshta, 421.67 MB (43.19 milion rreshta/s., 86.51 MB/s.)

Hapësira e të dhënave në disk

Zgjidhni
    formatReadableSize(sum(data_uncompressed_bytes)) SI e papërcaktuar,
    formatReadableSize(sum(data_compressed_bytes)) SI e kompresuar,
    sum(rows) SI shuma_e_rreshtave
Nga sistem.parts
KU tabela = 'log_web'
 
┌─e papĂ«rcaktuar─┬─e kompresuar─┬─shuma_e_rreshtave─┐
│ 54.50 GiB    │ 4.86 GiB   │  211427094 │
└──────────────┮────────────┮────────────┘
 
1 rresht në grup. Kaloi: 0.035 sek.

Niveli i kompresimit të të dhënave në kolona

Zgjidh
    emrin,
    formatReadableSize(data_uncompressed_bytes) SI e pakompresuar,
    formatReadableSize(data_compressed_bytes) SI e kompresuar,
    data_uncompressed_bytes / data_compressed_bytes SI marrëdhënie_kompresimi
FROM system.columns
KU tabela = 'log_web'
 
┌─emri─────────────────────┬─e pakompresuar─┬─e kompresuar─┬─────marrĂ«dhĂ«nie_kompresimi─┐
│ 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 rresht në set. Koha e kaluar: 0.005 sek.

Përshkrimi i komponimeve të përdorura

FileBeat. Transferimi i log-eve të skedarëve

Ky komponent monitoron ndryshimet në skedarët e log-eve në disk dhe transferon informacionin në LogStash. Instalimi bëhet në të gjitha serverat ku shkruhen skedarët me log-e (zakonisht, IIS). Punon në modalitetin tail (dmth. transferon vetëm regjistrimet e shtuara në skedar). Por veçmas mund të konfigurohet për të transferuar të gjithë skedarin. Kjo është e dobishme kur duhet të ngarkohet të dhëna nga muajt e kaluar. Thjesht vendosni skedarin e log-ut në dosje dhe ai do ta lexojë atë plotësisht.

Kur ndalon shërbimin, të dhënat ndalojnë së transmetuari më tej në ruajtje.

Shembulli i konfigurimit duket si më poshtë:

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.al"
    fld_app_name: "site1.domain.al"
    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.al"
    fld_app_name: "site2.domain.al"
    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.al.cer"
  ssl.key: "C:/filebeat/certs/site1.domain.al.key"
 
#================================ Processors =====================================
 
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~

LogStash. Mblodues i logëve

Ky komponent është projektuar për të marrë regjistrimet e logëve nga FileBeat (ose përmes një radhe RabbitMQ), për t'i përpunuar dhe vendosur në grupe në databazën ClickHouse.

Për të futur në ClickHouse, përdoret plugin-i Logstash-output-clickhouse. Plugin-i Logstash ka një mekanizëm për përsëritjen e kërkesave, por gjatë ndalimit të zakonshëm, është më e mirë që të ndaloni shërbimin vetë. Gjatë ndalimit, do të grumbullohen mesazhe në radhën RabbitMQ, kështu që nëse ndalimi do të jetë për një kohë të gjatë, është më mirë të ndaloni Filebeat-ët në servera. Në skemën ku nuk e përdorim RabbitMQ (në rrjetin lokal, Filebeat dërgon drejtpërdrejt log-et në Logstash), Filebeat-ët punojnë mjaft mirë dhe sigurt, kështu që për ta, mospërmbushja e output-it kalon pa pasoja.

Shembulli i konfigurimit duket si më poshtë:

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. Magazin i logjeve

Të gjitha logjet nga sistemet ruhet në një tabelë (shih në fillim të artikujt). Ajo është destinuar për ruajtjen e informacionit në lidhje me kërkesat: të gjitha parametrat janë të ngjashëm për formate të ndryshme, si për shembull logjet IIS, logjet apache dhe nginx. Për logjet e aplikacioneve, të cilat regjistrojnë, për shembull, gabime, mesazhe informative, paralajmërime, do të parashikohet një tabelë e veçantë, me strukturën përkatëse (aktualisht në fazën e projektimit).

Gjatë projektimit të tabelës, është shumë e rëndësishme të përcaktohet çelësi primar (në bazë të cilit do të renditen të dhënat gjatë ruajtjes). Nga kjo varet shkalla e kompresimit të të dhënave dhe shpejtësia e kërkesave. Në shembullin tonë, çelësi është
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Prahasht do emrit të sistemit, emrit të komponentit të sistemit dhe datës së ngjarjes. Fillimisht, data e ngjarjes ishte në vendin e parë. Pas zhvendosjes së saj në vendin e fundit, kërkesat filluan të funksionojnë rreth dy herë më shpejt. Ndryshimi i çelësit primar do të kërkojë krijimin e ri të tabelës dhe ri-ngarkimin e të dhënave, në mënyrë që ClickHouse të rindërtojë të dhënat në disk. Kjo është një operacion i rëndë, prandaj është e dëshirueshme të planifikoni thellësisht se çfarë duhet të përfshihet në çelësin e renditjes.

Gjithashtu është e nevojshme të theksohet se në versionet e fundit ka dalë tipi i të dhënave LowCardinality. Me përdorimin e tij, ndjeshëm zvogëlohet madhësia e të dhënave të kompresuara për ato fusha që kanë kardinalitet të ulët (po aq variante).

Aktualisht po përdoret versioni 19.6, dhe ne planifikojmë të provojmë të përditësojmë versionin në atë më të fundit. Në to janë prezantuar disa tipare të mrekullueshme si Adaptive Granularity, Skipping indices dhe kodeku DoubleDelta, për shembull.

Me default, kur instalohet, niveli i regjistrimit është konfigurimi i trace. Log-et rotullohen dhe arkivohen, por shtrihen deri në një gigabyte. Nëse nuk ka nevojë, mund të vendoset niveli warning, në këtë rast madhësia e log-ut zvogëlohet ndjeshëm. Konfigurimi i regjistrimit përcaktohet në skedarin config.xml:


warning

Disa komanda të dobishme

Duke paketet origjinale të instalimit janë ndërtuar për Debian, për versionet e tjera të Linux-it nevojiten paketet e ndërtuara nga kompania Altinity.  
 
Këtu keni udhëzime me lidhje në depozitën e tyre: https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse  
sudo yum search clickhouse-server  
sudo yum install clickhouse-server.noarch  
  
1. kontrolloni statusin  
sudo systemctl status clickhouse-server  
 
2. ndaloni serverin  
sudo systemctl stop clickhouse-server  
 
3. nisni serverin  
sudo systemctl start clickhouse-server  
 
Këtu është sa duhet të nisni për të ekzekutuar kërkesat në modin shumë-rresht (ekzekutimi pas shenjës ";")  
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  
 
Plugini ClickHouse për Logstash në rast gabimi në një rresht ruan të gjithë paketën në skedarin /tmp/log_web_failed.json  
Mund ta korrigjoni manualisht këtë skedare dhe ta provoni ta ngarkoni në DB manualisht:  
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  
 
dalja nga komandat  
quit;  
## Konfigurimi i TLS  
https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2  
  
openssl s_client -connect log.domain.com:9440 < /dev/null

LogStash. Ruter i logëve nga FileBeat në radhën RabbitMQ

Ky komponent përdoret për të rritur logët që vijnë nga FileBeat në radhën RabbitMQ. Këtu janë dy pika:

  1. Për fat të keq, FileBeat nuk ka një plugin output për të shkruar drejtpërdrejt në RabbitMQ. Dhe një funksionalitet i tillë, sipas çështjeve në GitHub-in e tyre, nuk planifikohet të realizohet. Ka një plugin për Kafka, por për disa arsye të caktuara nuk mund ta përdorim tek ne.
  2. Ka kërkesa për mbledhjen e logëve në DMZ. Nga këto kërkesa, logët së pari duhet të grumbullohen në radhë dhe pastaj LogStash lexon nga jashtë regjistrat e radhës.

Prandaj, pikërisht për rastin e vendosjes së serverëve në DMZ, duhet të përdorim një skemë paksa më të komplikuar. Një shembull konfigurimi duket si më poshtë:

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. Rreshti i mesazheve

Ky komponent pĂ«rdoret pĂ«r buferimin e regjistrimeve tĂ« logeve nĂ« DMZ. Regjistrimi bĂ«het pĂ«rmes lidhjes Filebeat → LogStash. Leximi kryhet nga jashtĂ« DMZ pĂ«rmes LogStash. GjatĂ« funksionimit pĂ«rmes RabbitMQ trajtohen rreth 4 mijĂ« mesazhe nĂ« sekondĂ«.

Routing i mesazheve është vendosur sipas emrit të sistemit, dmth. në bazë të të dhënave të konfigurimit të FileBeat. Të gjitha mesazhet përfundojnë në një radhë. Nëse shërbimi i radhëve ndalet për ndonjë arsye, kjo nuk do të sjellë humbje të mesazheve: FileBeat do të marrë gabime lidhjeje dhe do të pezullohet përkohësisht dërgimi. Në të njëjtën kohë, LogStash, i cili lexon nga radha, gjithashtu do të marrë gabime rrjetit dhe do të presë që lidhja të rikuperohet. Sigurisht, të dhënat do të ndalojnë së shkruari në databazë.

Udhëzimet e mëposhtme përdoren për krijimin dhe konfigurimin e radhëve:

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

Grafana. Dashboardet

Ky komponent përdoret për vizualizimin e të dhënave të monitorimit. Duhet të instalohet plugin-i ClickHouse datasource for Grafana 4.6+. Na u desh ta rregullojmë pak, për të rritur efikasitetin e përpunimit të SQL-filterave në dashboard.

Për shembull, ne përdorim variablat, dhe nëse ato nuk janë vendosur në fushën e filtrit, do të ishte mirë që të mos krijonte një kusht në WHERE të tipit ( uriStem = » AND uriStem != » ). Në një rast të tillë, ClickHouse do të lexonte kolonën uriStem. Në përgjithësi, ne provuam variante të ndryshme dhe përfundimisht rregulluam plugin-in (makros $valueIfEmpty), në mënyrë që në rastin e një vlere të zbrazët, ai të kthejë 1, pa përmendur kolonën e vet.

Dhe tani mund të përdoret një kërkesë e tillë për grafik

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

që konvertohet në një SQL të tillë (vëreni se fushat e zbrazëta uriStem u konvertuan thjesht në 1)

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

Përfundimi

Shfaqja e DB ClickHouse ishte një ngjarje simbolike në treg. Ishte e vështirë të imagjinohej që në një moment krejtësisht falas, ne u armatosëm me një vegël të fuqishme dhe praktike për punën me të dhëna të mëdha. Sigurisht, me rritjen e nevojave (për shembull, ndarjen dhe replikimin në disa serverë), skema do të komplikojë. Por nga përshtypjet e para, është shumë këndshme të punosh me këtë DB. Këtu është e dukshme se produkti është bërë 'për njerëzit'.

Në krahasim me ElasticSearch, shpenzimet për ruajtjen dhe përpunimin e log-ve, sipas vlerësimeve paraprake, reduktohen nga pesë deri në dhjetë herë. Në fjalë të tjera, nëse për volumet aktuale të të dhënave do të na duhej të konfiguronim një grumbull nga disa makina, me përdorimin e ClickHouse, na mjafton një makinë me kapacitet të ulët. Po, natyrisht, në ElasticSearch gjithashtu ekzistojnë mekanizma për kompresimin e të dhënave në disk dhe karakteristika të tjera që lejojnë një reduktim të dukshëm të konsumit të burimeve, por krahasuar me ClickHouse, kjo do të kërkonte më shumë shpenzime.

Pa ndonjë optimizim të veçantë nga ana jonë, në cilësitë e paracaktuara, ngarkimi i të dhënave dhe marrja nga baza e të dhënave funksionojnë me një shpejtësi të jashtëzakonshme. Të dhënat për momentin janë të pakta (rreth 200 milion regjistrime), por vetë serveri është i dobët. Ky mjet mund ta përdorim në të ardhmen edhe për qëllime të tjera, jo vetëm për ruajtjen e regjistrimeve. Për shembull, për analiza të plota, në fushën e sigurisë, ose mësim të makinerisë.

Në fund, pak për pikat negative dhe pozitive.

Kundrat

  1. Ngarkimi i regjistrimeve në grupe të mëdha. Kjo, nga njëra anë, është një funksionalitet, por megjithatë na duhet të përdorim komponentë të tjerë për buferizimin e regjistrimeve. Kjo detyrë nuk është gjithmonë e thjeshtë, por është e zgjidhshme. Dhe do të dëshironim ta thjeshtonim sistemin.
  2. Disa funksionalitete ekzotike ose tipare të reja shpesh prishen në versionet e reja. Kjo shkakton shqetësime, duke zvogëluar dëshirën për t'u azhurnuar në një version të ri. Për shembull, motorri i tabelave Kafka është një tipar shumë i dobishëm që lejon leximin e drejtpërdrejtë të ngjarjeve nga Kafka, pa implementimin e konsumatorëve. Por gjendja e numrit të çështjeve në GitHub sugjeron se akoma jemi të kujdesshëm për ta përdorur këtë motor në prodhim. Megjithatë, nëse nuk kryejmë lëvizje të papritura dhe përdorim funksionalitetin kryesor, ai funksionon stabilisht.

Përfitimet

  1. Nuk ngadalëson.
  2. Kuotë e ulët hyrjeje.
  3. Open-source.
  4. E lirë.
  5. Përmirësohet mirë (shardim/replikim 'nga kutia')
  6. Pjesë e regjistrit të softuerit rus, e rekomanduar nga Ministria e Komunikacionit.
  7. Prania e mbështetjes zyrtare nga Yandex.

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster