ClickHouse Database for Humans, ose Alien Technologies

Aleksey Lizunov, Shef i Qendrës së Kompetencës për kanalet e shërbimit në distancë të Drejtorisë së Teknologjive të Informacionit të MKB-së

ClickHouse Database for Humans, ose Alien Technologies

Si një alternativë ndaj pirgut ELK (ElasticSearch, Logstash, Kibana), ne po bëjmë kërkime për përdorimin e bazës së të dhënave ClickHouse si një dyqan të dhënash për regjistrat.

Në këtë artikull, ne do të donim të flasim për përvojën tonë të përdorimit të bazës së të dhënave ClickHouse dhe rezultatet paraprake të operacionit pilot. Duhet të theksohet menjëherë se rezultatet ishin mbresëlënëse.


ClickHouse Database for Humans, ose Alien Technologies

Më tej, ne do të përshkruajmë më në detaje se si është konfiguruar sistemi ynë dhe nga cilat komponentë përbëhet. Por tani do të doja të flisja pak për këtë bazë të dhënash në tërësi dhe pse ia vlen t'i kushtohet vëmendje. Baza e të dhënave ClickHouse është një bazë të dhënash kolone analitike me performancë të lartë nga Yandex. Përdoret në shërbimet Yandex, fillimisht është ruajtja kryesore e të dhënave për Yandex.Metrica. Sistemi me burim të hapur, falas. Nga këndvështrimi i një zhvilluesi, gjithmonë kam pyetur veten se si e kanë zbatuar atë, sepse ka të dhëna fantastike të mëdha. Dhe vetë ndërfaqja e përdoruesit të Metrica është shumë fleksibël dhe e shpejtë. Në njohjen e parë me këtë bazë të dhënash, përshtypja është: “Epo, më në fund! Krijuar për njerëzit! Duke filluar nga procesi i instalimit dhe duke përfunduar me dërgimin e kërkesave.

Kjo bazë të dhënash ka një prag shumë të ulët hyrjeje. Edhe një zhvillues me aftësi mesatare mund ta instalojë këtë bazë të dhënash brenda pak minutash dhe të fillojë ta përdorë atë. Gjithçka funksionon qartë. Edhe njerëzit që janë të rinj në Linux mund ta kalojnë shpejt instalimin dhe të bëjnë operacionet më të thjeshta. Nëse më parë, me fjalët Big Data, Hadoop, Google BigTable, HDFS, një zhvillues i zakonshëm kishte idenë se bëhej fjalë për disa terabajt, petabajt, se disa mbinjerëz janë të angazhuar në cilësimet dhe zhvillimin e këtyre sistemeve, atëherë me ardhjen e ClickHouse. bazën e të dhënave, kemi marrë një mjet të thjeshtë, të kuptueshëm me të cilin mund të zgjidhni një sërë detyrash të paarritshme më parë. Duhet vetëm një makinë mjaft mesatare dhe pesë minuta për t'u instaluar. Kjo do të thotë, ne morëm një bazë të dhënash të tillë si, për shembull, MySql, por vetëm për ruajtjen e miliarda të dhënave! Një super-arkivues i caktuar me gjuhën SQL. Është sikur njerëzve u janë dorëzuar armët e të huajve.

Rreth sistemit tonë të prerjeve

Për të mbledhur informacion, përdoren skedarët e regjistrave të IIS të aplikacioneve në ueb të formatit standard (ne po analizojmë gjithashtu regjistrat e aplikacioneve, por qëllimi kryesor në fazën pilot është mbledhja e regjistrave të IIS).

Për arsye të ndryshme, ne nuk mund ta braktisnim plotësisht pirgun ELK dhe vazhdojmë të përdorim përbërësit LogStash dhe Filebeat, të cilët janë dëshmuar mirë dhe funksionojnë mjaft të besueshëm dhe të parashikueshëm.

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

ClickHouse Database for Humans, ose Alien Technologies

Një veçori e shkrimit të të dhënave në bazën e të dhënave ClickHouse është futja e rrallë (një herë në sekondë) e të dhënave në grupe të mëdha. Kjo, me sa duket, është pjesa më "problematike" që hasni kur provoni për herë të parë punën me bazën e të dhënave ClickHouse: skema bëhet pak më e ndërlikuar.
Shtojca për LogStash, e cila fut drejtpërdrejt të dhënat në ClickHouse, ndihmoi shumë këtu. Ky komponent vendoset në të njëjtin server si vetë baza e të dhënave. Pra, në përgjithësi, nuk rekomandohet ta bësh atë, por nga pikëpamja praktike, në mënyrë që të mos prodhohen serverë të veçantë ndërsa ai është i vendosur në të njëjtin server. Ne nuk kemi vërejtur ndonjë dështim ose konflikt burimesh me bazën e të dhënave. Për më tepër, duhet të theksohet se shtojca ka një mekanizëm të riprovës në rast gabimesh. Dhe në rast gabimesh, shtojca shkruan në disk një grup të dhënash që nuk mund të futeshin (formati i skedarit është i përshtatshëm: pas redaktimit, mund të futni lehtësisht grupin e korrigjuar duke përdorur clickhouse-client).

Një listë e plotë e softuerit të përdorur në skemë është paraqitur në tabelë:

Lista e softuerit të përdorur

Emër

Përshkrim

Lidhja e shpërndarjes

nginx

Reverse-proxy për të kufizuar aksesin nga portet dhe për të organizuar autorizimin

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 regjistrave të skedarëve.

https://www.elastic.co/downloads/beats/filebeat (Kit shpërndarës për Windows 64bit).

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

logstash

Koleksionist i trungjeve.

Përdoret për të mbledhur regjistrat nga FileBeat, si dhe për të mbledhur regjistrat nga radha e RabbitMQ (për serverët që janë në DMZ.)

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

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

Logstash-output-clickhouse

Shtojca Loagstash për transferimin e regjistrave në bazën e të dhënave ClickHouse në grupe

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

/usr/share/logstash/bin/logstash-plugin instalo logstash-output-clickhouse

/usr/share/logstash/bin/logstash-plugin instalo logstash-filter-prune

/usr/share/logstash/bin/logstash-plugin instalo logstash-filter-multiline

Shtëpi Kliko

Ruajtja e regjistrave 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

Shënim. Duke filluar nga gushti 2018, ndërtimet "normale" të rpm për RHEL u shfaqën në depon e Yandex, kështu që mund të provoni t'i përdorni ato. Në kohën e instalimit, ne ishim duke përdorur paketa të ndërtuara nga Altinity.

grafana

Vizualizimi i regjistrit. Konfigurimi i paneleve

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 Bit) - versioni i fundit

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

Plugin për Grafana me burimin e të dhënave ClickHouse

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

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

logstash

Regjistro ruterin nga FileBeat në radhën e RabbitMQ.

Shënim. Fatkeqësisht, FileBeat nuk ka dalje direkt në RabbitMQ, kështu që kërkohet një lidhje e ndërmjetme në formën e Logstash

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

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

LepuriMQ

radha e mesazheve. Ky është buferi i regjistrit 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)

Koha e duhur e ekzekutimit. Kërkohet që RabbitMQ të funksionojë

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 është paraqitur në tabelën e mëposhtme:

Emër

Vlerë

Shënim

konfiguracion

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

Është e nevojshme t'i kushtohet vëmendje këshillave për funksionimin e bazës së të dhënave ClickHouse (https://clickhouse.yandex/docs/ru/operations/tips/)

Softuer i përgjithshëm i sistemit

OS: Serveri Linux Red Hat Enterprise (Maipo)

JRE (Java 8)

 

Siç mund ta shihni, ky është një stacion i zakonshëm pune.

Struktura e tabelës për ruajtjen e regjistrave është si më poshtë:

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;

Ne përdorim ndarjen e paracaktuar (sipas muajit) dhe shkallëzimin e indeksit. Të gjitha fushat praktikisht korrespondojnë me hyrjet e regjistrit të IIS për regjistrimin e kërkesave http. Më vete, vërejmë se ka fusha të veçanta për ruajtjen e etiketave utm (ato analizohen në fazën e futjes në tabelë nga fusha e vargut të pyetjes).

Gjithashtu, në tabelë janë shtuar disa fusha të sistemit për të ruajtur informacione rreth sistemeve, komponentëve, serverëve. Shihni tabelën më poshtë për një përshkrim të këtyre fushave. Në një tabelë, ne ruajmë regjistrat për disa sisteme.

Emër

Përshkrim

Shembull

emri_fld_app

Emri i aplikacionit/sistemi
Vlerat e vlefshme:

  • site1.domain.com Faqja e jashtme 1
  • site2.domain.com Faqja e jashtme 2
  • interior-site1.domain.local Faqja e brendshme 1

site1.domain.com

fld_app_module

Moduli i sistemit
Vlerat e vlefshme:

  • web - Faqja e internetit
  • svc - Shërbimi i faqes në internet
  • intgr - Shërbimi Ueb i Integrimit
  • bo - Admin (BackOffice)

web

emri_fld_website

Emri i faqes në IIS

Disa sisteme mund të vendosen në një server, apo edhe disa raste të një moduli sistemi

web kryesore

emri_fld_server

Emri i serverit

web1.domain.com

fld_log_file_name

Rruga drejt skedarit të regjistrit në server

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Kjo ju lejon të ndërtoni me efikasitet grafikët në Grafana. Për shembull, shikoni kërkesat nga frontend i një sistemi të caktuar. Kjo është e ngjashme me numëruesin e faqes në Yandex.Metrica.

Këtu janë disa statistika për përdorimin e bazës së të dhënave për dy muaj.

Numri i regjistrimeve të ndara sipas sistemeve dhe përbërësve të tyre

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

Sasia e të dhënave në disk

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.

Shkalla e ngjeshjes së të dhënave në kolona

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.

Përshkrimi i komponentëve të përdorur

FileBeat. Transferimi i regjistrave të skedarëve

Ky komponent gjurmon ndryshimet në skedarët e regjistrit në disk dhe ia kalon informacionin LogStash. Instaluar në të gjithë serverët ku janë shkruar skedarët e regjistrave (zakonisht IIS). Punon në modalitetin tail (d.m.th. transferon vetëm regjistrimet e shtuara në skedar). Por veçmas mund të konfigurohet për të transferuar skedarë të tërë. Kjo është e dobishme kur ju duhet të shkarkoni të dhëna nga muajt e kaluar. Thjesht vendosni skedarin e regjistrit në një dosje dhe ai do ta lexojë atë në tërësi.

Kur shërbimi ndalet, të dhënat nuk transferohen më në memorie.

Një shembull i konfigurimit duket si ky:

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. Mbledhësi i regjistrave

Ky komponent është krijuar për të marrë shënime në regjistrat nga FileBeat (ose përmes radhës RabbitMQ), analizimin dhe futjen e grupeve në bazën e të dhënave ClickHouse.

Për futje në ClickHouse, përdoret shtojca Logstash-output-clickhouse. Shtojca Logstash ka një mekanizëm të riprovës së kërkesës, por me një mbyllje të rregullt, është më mirë të ndaloni vetë shërbimin. Kur ndalohet, mesazhet do të grumbullohen në radhën e RabbitMQ, kështu që nëse ndalimi është për një kohë të gjatë, atëherë është më mirë të ndaloni Filebeats në serverë. Në një skemë ku RabbitMQ nuk përdoret (në rrjetin lokal, Filebeat dërgon direkt regjistrat në Logstash), Filebeats funksionojnë mjaft të pranueshëm dhe të sigurt, kështu që për ta mosdisponueshmëria e daljes kalon pa pasoja.

Një shembull i konfigurimit duket si ky:

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

tubacionet.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"

klikim shtëpie. Ruajtja e regjistrave

Regjistrat për të gjitha sistemet ruhen në një tabelë (shihni në fillim të artikullit). Ai synon të ruajë informacione rreth kërkesave: të gjithë parametrat janë të ngjashëm për formate të ndryshme, si regjistrat e IIS, regjistrat e apache dhe nginx. Për regjistrat e aplikacioneve, në të cilat, për shembull, regjistrohen gabime, mesazhe informacioni, paralajmërime, do të sigurohet një tabelë e veçantë me strukturën e duhur (aktualisht në fazën e projektimit).

Kur hartoni një tabelë, është shumë e rëndësishme të vendosni për çelësin primar (me të cilin do të renditen të dhënat gjatë ruajtjes). Shkalla e ngjeshjes së të dhënave dhe shpejtësia e pyetjes varen nga kjo. Në shembullin tonë, çelësi është
POROSIT ME (fld_app_name, fld_app_module, logdatetime)
Kjo është, me emrin e sistemit, emrin e komponentit të sistemit dhe datën e ngjarjes. Fillimisht, data e ngjarjes ishte e para. Pasi e zhvendosën në vendin e fundit, pyetjet filluan të funksionojnë rreth dy herë më shpejt. Ndryshimi i çelësit primar do të kërkojë rikrijimin e tabelës dhe ringarkimin e të dhënave në mënyrë që ClickHouse të rirendisë të dhënat në disk. Ky është një operacion i rëndë, prandaj është mirë të mendoni shumë se çfarë duhet të përfshihet në çelësin e renditjes.

Duhet gjithashtu të theksohet se lloji i të dhënave LowCardinality është shfaqur relativisht në versionet e fundit. Kur e përdorni, madhësia e të dhënave të kompresuara zvogëlohet në mënyrë drastike për ato fusha që kanë kardinalitet të ulët (pak opsione).

Versioni 19.6 është aktualisht në përdorim dhe ne planifikojmë të provojmë përditësimin në versionin më të fundit. Ata kanë karakteristika të tilla të mrekullueshme si Granulariteti Adaptive, Indekset Skipping dhe kodiku DoubleDelta, për shembull.

Si parazgjedhje, gjatë instalimit, niveli i regjistrimit është vendosur në gjurmim. Regjistrat rrotullohen dhe arkivohen, por në të njëjtën kohë ato zgjerohen deri në një gigabajt. Nëse nuk ka nevojë, atëherë mund të vendosni nivelin e paralajmërimit, atëherë madhësia e regjistrit zvogëlohet në mënyrë drastike. Cilësimi i regjistrimit është vendosur në skedarin config.xml:

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

Disa komanda të dobishme

Поскольку оригинальные пакеты установки собираются по 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. Regjistro ruterin nga FileBeat në radhën e RabbitMQ

Ky komponent përdoret për të drejtuar regjistrat që vijnë nga FileBeat në radhën e RabbitMQ. Këtu ka dy pika:

  1. Fatkeqësisht, FileBeat nuk ka një shtojcë dalëse për të shkruar drejtpërdrejt në RabbitMQ. Dhe një funksionalitet i tillë, duke gjykuar nga çështja në github e tyre, nuk është planifikuar për zbatim. Ekziston një shtojcë për Kafka, por për disa arsye nuk mund ta përdorim atë në shtëpi.
  2. Ekzistojnë kërkesa për mbledhjen e trungjeve në DMZ. Bazuar në to, regjistrat fillimisht duhet të shtohen në radhë dhe më pas LogStash lexon hyrjet nga radha nga jashtë.

Prandaj, është për rastin kur serverët janë të vendosur në DMZ që duhet të përdoret një skemë kaq pak e ndërlikuar. Një shembull i konfigurimit duket si ky:

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. radha e mesazheve

Ky komponent përdoret për të zbutur hyrjet e regjistrit në DMZ. Regjistrimi bëhet përmes një grupi Filebeat → LogStash. Leximi bëhet nga jashtë DMZ nëpërmjet LogStash. Kur operoni përmes RabboitMQ, përpunohen rreth 4 mijë mesazhe në sekondë.

Drejtimi i mesazheve konfigurohet sipas emrit të sistemit, pra bazuar në të dhënat e konfigurimit të FileBeat. Të gjitha mesazhet shkojnë në një radhë. Nëse për ndonjë arsye shërbimi i radhës ndalet, atëherë kjo nuk do të çojë në humbjen e mesazheve: FileBeats do të marrë gabime në lidhje dhe do të pezullojë përkohësisht dërgimin. Dhe LogStash që lexon nga radha do të marrë gjithashtu gabime në rrjet dhe do të presë që lidhja të rikthehet. Në këtë rast, të dhënat, natyrisht, nuk do të shkruhen më në bazën e të dhënave.

Udhëzimet e mëposhtme përdoren për të krijuar dhe konfiguruar radhët:

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

Ky komponent përdoret për të vizualizuar të dhënat e monitorimit. Në këtë rast, duhet të instaloni burimin e të dhënave ClickHouse për shtojcën Grafana 4.6+. Na u desh ta ndryshonim pak për të përmirësuar efikasitetin e përpunimit të filtrave SQL në pult.

Për shembull, ne përdorim variabla dhe nëse ato nuk janë vendosur në fushën e filtrit, atëherë do të dëshironim që të mos gjeneronte një kusht në WHERE të formës ( uriStem = » AND uriStem != » ). Në këtë rast, ClickHouse do të lexojë kolonën uriStem. Në përgjithësi, ne provuam opsione të ndryshme dhe përfundimisht korrigjuam shtojcën (makro $valueIfEmpty) në mënyrë që në rastin e një vlere boshe të kthejë 1, pa përmendur vetë kolonën.

Dhe tani mund ta përdorni këtë pyetje për grafikun

$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ë përkthehet në këtë SQL (vini re se fushat e zbrazëta uriStem janë konvertuar në vetëm 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ërfundim

Shfaqja e bazës së të dhënave ClickHouse është bërë një ngjarje historike në treg. Ishte e vështirë të imagjinohej që, plotësisht pa pagesë, në një çast ishim të armatosur me një mjet të fuqishëm dhe praktik për të punuar me të dhëna të mëdha. Sigurisht, me rritjen e nevojave (për shembull, ndarjen dhe replikimin në shumë serverë), skema do të bëhet më e ndërlikuar. Por në përshtypjet e para, puna me këtë bazë të dhënash është shumë e këndshme. Mund të shihet se produkti është bërë "për njerëzit".

Krahasuar me ElasticSearch, kostoja e ruajtjes dhe përpunimit të regjistrave vlerësohet të reduktohet nga pesë deri në dhjetë herë. Me fjalë të tjera, nëse për sasinë aktuale të të dhënave do të duhej të vendosnim një grup me disa makina, atëherë kur përdorni ClickHouse, na mjafton një makinë me fuqi të ulët. Po, sigurisht, ElasticSearch ka gjithashtu mekanizma të kompresimit të të dhënave në disk dhe veçori të tjera që mund të reduktojnë ndjeshëm konsumin e burimeve, por në krahasim me ClickHouse, kjo do të jetë më e shtrenjtë.

Pa ndonjë optimizim të veçantë nga ana jonë, në cilësimet e paracaktuara, ngarkimi i të dhënave dhe zgjedhja nga baza e të dhënave funksionon me një shpejtësi të mahnitshme. Nuk kemi ende shumë të dhëna (rreth 200 milionë regjistrime), por vetë serveri është i dobët. Ne mund ta përdorim këtë mjet në të ardhmen për qëllime të tjera që nuk lidhen me ruajtjen e regjistrave. Për shembull, për analitikë nga fundi në fund, në fushën e sigurisë, mësimin e makinerive.

Në fund, pak për të mirat dhe të këqijat.

Cons

  1. Ngarkimi i të dhënave në tufa të mëdha. Nga njëra anë, kjo është një veçori, por gjithsesi duhet të përdorni komponentë shtesë për buferimin e të dhënave. Kjo detyrë nuk është gjithmonë e lehtë, por gjithsesi e zgjidhshme. Dhe unë do të doja të thjeshtoja skemën.
  2. Disa funksione ekzotike ose veçori të reja shpesh prishen në versione të reja. Kjo shkakton shqetësim, duke reduktuar dëshirën për të përmirësuar në një version të ri. Për shembull, motori i tabelës Kafka është një veçori shumë e dobishme që ju lejon të lexoni drejtpërdrejt ngjarjet nga Kafka, pa zbatuar konsumatorët. Por duke gjykuar nga numri i Çështjeve në github, ne jemi ende të kujdesshëm që të mos e përdorim këtë motor në prodhim. Sidoqoftë, nëse nuk bëni gjeste të papritura anash dhe përdorni funksionalitetin kryesor, atëherë funksionon në mënyrë të qëndrueshme.

Rekuizitë

  1. Nuk ngadalësohet.
  2. Pragu i ulët i hyrjes.
  3. Me burim të hapur.
  4. Falas.
  5. Shkallëtohet mirë (ndarja/përsëritja jashtë kutisë)
  6. Përfshirë në regjistrin e softuerit rus të rekomanduar nga Ministria e Komunikimeve.
  7. Prania e mbështetjes zyrtare nga Yandex.

Burimi: www.habr.com

Shto një koment