ClickHouse Database for Humans, eða Alien Technologies

Aleksey Lizunov, yfirmaður hæfnimiðstöðvar fyrir fjarþjónusturásir upplýsingatæknistofnunar MKB

ClickHouse Database for Humans, eða Alien Technologies

Sem valkostur við ELK stafla (ElasticSearch, Logstash, Kibana), erum við að gera rannsóknir á því að nota ClickHouse gagnagrunninn sem gagnageymslu fyrir annála.

Í þessari grein viljum við segja frá reynslu okkar af notkun ClickHouse gagnagrunnsins og bráðabirgðaniðurstöður tilraunaaðgerðarinnar. Það skal strax tekið fram að árangurinn var glæsilegur.


ClickHouse Database for Humans, eða Alien Technologies

Næst munum við lýsa nánar hvernig kerfið okkar er stillt og hvaða íhlutum það samanstendur af. En nú langar mig að tala aðeins um þennan gagnagrunn í heild sinni og hvers vegna það er þess virði að gefa gaum. ClickHouse gagnagrunnurinn er afkastamikill greiningargagnagrunnur frá Yandex. Það er notað í Yandex þjónustu, upphaflega er það aðalgagnageymsla Yandex.Metrica. Opið uppspretta kerfi, ókeypis. Frá sjónarhóli þróunaraðila hef ég alltaf velt því fyrir mér hvernig þeir útfærðu það, því það eru ótrúlega stór gögn. Og notendaviðmót Metrica sjálft er mjög sveigjanlegt og hratt. Við fyrstu kynni af þessum gagnagrunni er tilfinningin: „Jæja, loksins! Gert fyrir fólkið! Byrjar á uppsetningarferlinu og endar með því að senda beiðnir.

Þessi gagnagrunnur er með mjög lágan aðgangsþröskuld. Jafnvel meðalhæfur verktaki getur sett upp þennan gagnagrunn á nokkrum mínútum og byrjað að nota hann. Allt virkar greinilega. Jafnvel fólk sem er nýtt í Linux getur fljótt séð um uppsetninguna og gert einföldustu aðgerðir. Ef fyrr, með orðunum Big Data, Hadoop, Google BigTable, HDFS, hafði venjulegur þróunaraðili hugmyndir um að það væri um sum terabæt, petabæt, að sumir ofurmenn tækju þátt í stillingum og þróun fyrir þessi kerfi, þá með tilkomu ClickHouse gagnagrunninum, fengum við einfalt, skiljanlegt tól sem þú getur leyst áður óframkvæmanleg verkefni. Það tekur aðeins eina nokkuð meðalvél og fimm mínútur að setja upp. Það er að segja, við fengum slíkan gagnagrunn eins og til dæmis MySql, en aðeins til að geyma milljarða skráa! Ákveðinn ofurskjalasafnari með SQL tungumálinu. Það er eins og fólki hafi verið afhent vopn geimvera.

Um skógarhöggskerfið okkar

Til að safna upplýsingum eru notaðar IIS annálaskrár með venjulegu sniði vefforrita (við erum líka að flokka forritaskrár, en meginmarkmiðið á tilraunastigi er að safna IIS logs).

Af ýmsum ástæðum gátum við ekki alveg yfirgefið ELK stafla, og við höldum áfram að nota LogStash og Filebeat íhlutina, sem hafa reynst vel og virka nokkuð áreiðanlega og fyrirsjáanlega.

Almennt skráningarkerfi er sýnt á myndinni hér að neðan:

ClickHouse Database for Humans, eða Alien Technologies

Einkenni þess að skrifa gögn í ClickHouse gagnagrunninn er sjaldgæf (einu sinni á sekúndu) innsetningu gagna í stórum lotum. Þetta er greinilega „vandræðalegasti“ hlutinn sem þú lendir í þegar þú upplifir fyrst að vinna með ClickHouse gagnagrunninum: kerfið verður aðeins flóknara.
Viðbótin fyrir LogStash, sem setur gögn beint inn í ClickHouse, hjálpaði mikið hér. Þessi hluti er settur á sama netþjón og gagnagrunnurinn sjálfur. Svo, almennt séð, er ekki mælt með því að gera það, heldur frá hagnýtu sjónarhorni, til að framleiða ekki aðskilda netþjóna á meðan hann er settur á sama netþjóninn. Við tókum ekki eftir neinum bilunum eða átökum við gagnagrunninn. Að auki skal tekið fram að viðbótin er með endurreynslukerfi ef villur koma upp. Og ef villur koma upp, skrifar viðbótin á diskinn slatta af gögnum sem ekki var hægt að setja inn (skráarsniðið er þægilegt: eftir breytingar geturðu auðveldlega sett inn leiðréttu lotuna með því að nota clickhouse-client).

Heildarlisti yfir hugbúnað sem notaður er í kerfinu er sýndur í töflunni:

Listi yfir hugbúnað sem notaður er

Nafn

Lýsing

Dreifingartengsl

nginx

Reverse-proxy til að takmarka aðgang eftir höfnum og skipuleggja heimild

Sem stendur ekki notað í kerfinu

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

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

FileBeat

Flutningur skráaskráa.

https://www.elastic.co/downloads/beats/filebeat (dreifingarsett fyrir Windows 64bit).

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

logstash

Log safnari.

Notað til að safna annálum frá FileBeat, sem og til að safna annálum úr RabbitMQ biðröðinni (fyrir netþjóna sem eru í DMZ.)

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

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

Logstash-output-clickhouse

Loagstash viðbót til að flytja annála yfir í ClickHouse gagnagrunninn í lotum

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

/usr/share/logstash/bin/logstash-plugin setja upp logstash-output-clickhouse

/usr/share/logstash/bin/logstash-plugin setja upp logstash-filter-prune

/usr/share/logstash/bin/logstash-plugin setja upp logstash-filter-multiline

smellahús

Log geymsla 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

Athugið. Frá og með ágúst 2018 birtust „venjuleg“ rpm smíði fyrir RHEL í Yandex geymslunni, svo þú getur prófað að nota þær. Þegar uppsetningin var sett notuðum við pakka sem smíðaðir voru af Altinity.

grafana

Log sjón. Að setja upp mælaborð

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos(64 Bit) - nýjasta útgáfan

ClickHouse gagnaheimild fyrir Grafana 4.6+

Viðbót fyrir Grafana með ClickHouse gagnagjafa

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

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

logstash

Skráðu leið frá FileBeat í RabbitMQ biðröð.

Athugið. Því miður hefur FileBeat ekki úttak beint til RabbitMQ, þannig að millitengil í formi Logstash er nauðsynlegur

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

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

Kanína MQ

skilaboðaröð. Þetta er log buffer í 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 (krafist fyrir RabbitMQ)

Erlang keyrslutími. Nauðsynlegt til að RabbitMQ virki

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

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

Uppsetning miðlara með ClickHouse gagnagrunninum er sýnd í eftirfarandi töflu:

Nafn

Gildi

Athugið

Stillingar

HDD: 40GB
RAM: 8GB
Örgjörvi: Core 2 2Ghz

Nauðsynlegt er að fylgjast með ráðleggingum um notkun ClickHouse gagnagrunnsins (https://clickhouse.yandex/docs/ru/operations/tips/)

Almennur kerfishugbúnaður

Stýrikerfi: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Eins og þú sérð er þetta venjuleg vinnustöð.

Uppbygging töflunnar til að geyma logs er sem hér segir:

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;

Við notum sjálfgefna skiptingu (eftir mánuði) og nákvæmni vísitölu. Allir reiti samsvara nánast IIS færslum til að skrá http beiðnir. Sérstaklega athugum við að það eru aðskildir reitir til að geyma utm-merki (þau eru flokkuð á stigi þess að setja inn í töfluna úr fyrirspurnarstrengsreitnum).

Einnig hefur nokkrum kerfisreitum verið bætt við töfluna til að geyma upplýsingar um kerfi, íhluti, netþjóna. Sjá töfluna hér að neðan til að fá lýsingu á þessum sviðum. Í einni töflu geymum við annála fyrir nokkur kerfi.

Nafn

Lýsing

Dæmi

fld_app_name

Nafn forrits/kerfis
Gild gildi:

  • site1.domain.com Ytri síða 1
  • site2.domain.com Ytri síða 2
  • internal-site1.domain.local Innri síða 1

site1.domain.com

fld_app_module

Kerfiseining
Gild gildi:

  • vefur - Vefsíða
  • svc - Vefsíðuþjónusta
  • intgr - Samþættingarvefþjónusta
  • bo - Admin (BackOffice)

Vefurinn

fld_website_name

Vefnafn í IIS

Hægt er að setja upp nokkur kerfi á einn netþjón, eða jafnvel nokkur tilvik af einni kerfiseiningu

aðal vefur

fld_þjónnafn

Nafn netþjóns

web1.domain.com

fld_log_file_name

Slóð að annálaskránni á þjóninum

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Þetta gerir þér kleift að smíða línurit á skilvirkan hátt í Grafana. Skoðaðu til dæmis beiðnir frá framenda tiltekins kerfis. Þetta er svipað og síðuteljarinn í Yandex.Metrica.

Hér eru nokkur tölfræði um notkun gagnagrunnsins í tvo mánuði.

Fjöldi skráa sundurliðað eftir kerfum og íhlutum þeirra

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

Gagnamagnið á disknum

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.

Gagnaþjöppun í dálkum

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.

Lýsing á notuðum íhlutum

FileBeat. Flutningur skráaskráa

Þessi hluti fylgist með breytingum á annálaskrám á diski og sendir upplýsingarnar til LogStash. Uppsett á öllum netþjónum þar sem log skrár eru skrifaðar (venjulega IIS). Virkar í halaham (þ.e.a.s. flytur aðeins færslurnar sem bætt er við í skrána). En sérstaklega er hægt að stilla það til að flytja heilar skrár. Þetta er gagnlegt þegar þú þarft að hlaða niður gögnum frá fyrri mánuðum. Settu bara skrána í möppu og hún mun lesa hana í heild sinni.

Þegar þjónustan er stöðvuð eru gögnin ekki lengur flutt lengra í geymsluna.

Dæmi um uppsetningu lítur svona út:

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

Þessi hluti er hannaður til að taka á móti skráningarfærslum frá FileBeat (eða í gegnum RabbitMQ biðröðina), flokka og setja runur inn í ClickHouse gagnagrunninn.

Til að setja inn í ClickHouse er Logstash-output-clickhouse viðbótin notuð. Logstash viðbótin er með beiðni um að reyna aftur, en með reglulegri lokun er betra að hætta þjónustunni sjálfri. Þegar það er hætt safnast skilaboð í RabbitMQ biðröðina, þannig að ef stoppið er í langan tíma, þá er betra að stoppa Filebeats á netþjónunum. Í kerfi þar sem RabbitMQ er ekki notað (á staðarnetinu sendir Filebeat annála beint til Logstash), virka Filebeats alveg ásættanlegt og á öruggan hátt, þannig að fyrir þá gengur ekki framleiðsla framhjá án afleiðinga.

Dæmi um uppsetningu lítur svona út:

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"

smellahús. Log geymsla

Logs fyrir öll kerfi eru geymd í einni töflu (sjá í upphafi greinarinnar). Það er ætlað að geyma upplýsingar um beiðnir: allar breytur eru svipaðar fyrir mismunandi snið, svo sem IIS logs, apache og nginx logs. Fyrir forritaskrár, þar sem til dæmis villur, upplýsingaskilaboð, viðvaranir eru skráðar, verður sérstök tafla með viðeigandi uppbyggingu (nú á hönnunarstigi).

Við hönnun á töflu er mjög mikilvægt að ákveða aðallykilinn (sem gögnin verða flokkuð eftir við geymslu). Hversu gagnaþjöppun og fyrirspurnarhraði er háð þessu. Í okkar dæmi er lykilatriðið
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Það er, með nafni kerfisins, nafni kerfishluta og dagsetningu viðburðarins. Upphaflega kom dagsetning viðburðarins fyrst. Eftir að hafa flutt það á síðasta staðinn fóru fyrirspurnir að vinna um það bil tvöfalt hraðar. Til að breyta aðallyklinum þarf að endurskapa töfluna og endurhlaða gögnin þannig að ClickHouse endurflokki gögnin á disknum. Þetta er þung aðgerð og því er gott að velta því fyrir sér hvað eigi að vera með í flokkunarlyklinum.

Það skal líka tekið fram að LowCardinality gagnategundin hefur birst í tiltölulega nýlegum útgáfum. Þegar það er notað er stærð þjappaðra gagna minnkað verulega fyrir þá reiti sem hafa lágt kardínalitet (fáir valkostir).

Útgáfa 19.6 er í notkun og við ætlum að prófa að uppfæra í nýjustu útgáfuna. Þeir hafa svo frábæra eiginleika eins og Adaptive Granularity, Skipping vísitölur og DoubleDelta merkjamálið, til dæmis.

Sjálfgefið er, meðan á uppsetningu stendur, er skráningarstigið stillt á að rekja. Annálunum er snúið og sett í geymslu en á sama tíma stækka þeir upp í gígabæt. Ef það er engin þörf, þá geturðu stillt viðvörunarstigið, þá minnkar stærð skrárinnar verulega. Skráningarstillingin er stillt í config.xml skránni:

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

Nokkrar gagnlegar skipanir

Поскольку оригинальные пакеты установки собираются по 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. Skráðu leið frá FileBeat í RabbitMQ biðröð

Þessi hluti er notaður til að beina annálum sem koma frá FileBeat í RabbitMQ biðröðina. Hér eru tveir punktar:

  1. Því miður er FileBeat ekki með úttaksviðbót til að skrifa beint á RabbitMQ. Og slík virkni, miðað við málið á github þeirra, er ekki fyrirhuguð fyrir innleiðingu. Það er viðbót fyrir Kafka, en af ​​einhverjum ástæðum getum við ekki notað það heima.
  2. Það eru kröfur um að safna annálum í DMZ. Byggt á þeim þarf fyrst að bæta annálunum við biðröðina og síðan les LogStash færslurnar úr biðröðinni að utan.

Þess vegna er það tilfellið þar sem netþjónar eru staðsettir í DMZ sem maður þarf að nota svona svolítið flókið kerfi. Dæmi um uppsetningu lítur svona út:

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. skilaboðaröð

Þessi hluti er notaður til að biðja um skráningarfærslur í DMZ. Upptaka er gerð í gegnum fullt af Filebeat → LogStash. Lestur fer fram utan DMZ í gegnum LogStash. Þegar unnið er í gegnum RabboitMQ eru um 4 þúsund skilaboð unnin á sekúndu.

Skilaboðaleið er stillt með kerfisheiti, þ.e. byggt á FileBeat stillingargögnum. Öll skilaboð fara í eina biðröð. Ef biðröðþjónustan er stöðvuð af einhverjum ástæðum mun það ekki leiða til taps á skilaboðum: FileBeats mun fá tengingarvillur og stöðva sendingu tímabundið. Og LogStash sem les úr biðröðinni mun einnig fá netvillur og bíða eftir að tengingin verði endurheimt. Í þessu tilviki verða gögnin að sjálfsögðu ekki lengur skrifuð í gagnagrunninn.

Eftirfarandi leiðbeiningar eru notaðar til að búa til og stilla biðraðir:

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. Mælaborð

Þessi hluti er notaður til að sjá vöktunargögn. Í þessu tilviki þarftu að setja upp ClickHouse gagnaveituna fyrir Grafana 4.6+ viðbótina. Við þurftum að laga það aðeins til að bæta skilvirkni vinnslu SQL sía á mælaborðinu.

Til dæmis notum við breytur, og ef þær eru ekki stilltar í síureitinn, þá viljum við að það myndi ekki skilyrði í WHERE eyðublaðsins ( uriStem = » OG uriStem != » ). Í þessu tilviki mun ClickHouse lesa uriStem dálkinn. Almennt reyndum við mismunandi valkosti og leiðréttum að lokum viðbótina ($valueIfEmpty fjölvi) þannig að ef um er að ræða tómt gildi skilar það 1, án þess að minnast á dálkinn sjálfan.

Og nú geturðu notað þessa fyrirspurn fyrir línuritið

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

sem þýðir SQL svona (athugið að tómu uriStem reitirnir hafa verið breyttir í aðeins 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

Ályktun

Útlit ClickHouse gagnagrunnsins hefur orðið tímamótaviðburður á markaðnum. Það var erfitt að ímynda sér að við, algjörlega ókeypis, á augabragði værum vopnaðir öflugu og hagnýtu tæki til að vinna með stór gögn. Auðvitað, með auknum þörfum (til dæmis, sundrun og afritun á marga netþjóna), mun kerfið verða flóknara. En við fyrstu kynni er mjög notalegt að vinna með þennan gagnagrunn. Það má sjá að varan er gerð "fyrir fólk."

Í samanburði við ElasticSearch er áætlað að kostnaður við geymslu og vinnslu annála lækki um fimm til tífalt. Með öðrum orðum, ef fyrir núverandi gagnamagn þyrftum við að setja upp þyrping af nokkrum vélum, þá nægir okkur ein orkulítil vél þegar þú notar ClickHouse. Já, auðvitað, ElasticSearch hefur einnig gagnaþjöppunarkerfi á diski og aðra eiginleika sem geta dregið verulega úr auðlindanotkun, en miðað við ClickHouse verður þetta dýrara.

Án sérstakra hagræðinga af okkar hálfu, á sjálfgefnum stillingum, virkar hleðsla gagna og val úr gagnagrunninum á ótrúlegum hraða. Við höfum ekki mikið af gögnum ennþá (um 200 milljón færslur), en þjónninn sjálfur er veikur. Við getum notað þetta tól í framtíðinni í öðrum tilgangi sem ekki tengist geymslu annála. Til dæmis, fyrir end-to-end greiningar, á sviði öryggis, vélanáms.

Í lokin, smá um kosti og galla.

Gallar

  1. Hleður skrám í stórum lotum. Annars vegar er þetta eiginleiki, en þú verður samt að nota viðbótaríhluti til að hlaða niður færslum. Þetta verkefni er ekki alltaf auðvelt, en samt leysanlegt. Og mig langar til að einfalda kerfið.
  2. Sum framandi virkni eða nýir eiginleikar brjóta oft í nýjum útgáfum. Þetta veldur áhyggjum og dregur úr lönguninni til að uppfæra í nýja útgáfu. Til dæmis er Kafka borðvélin mjög gagnlegur eiginleiki sem gerir þér kleift að lesa atburði frá Kafka beint, án þess að útfæra neytendur. En miðað við fjölda vandamála á github, erum við samt varkár að nota þessa vél ekki í framleiðslu. Hins vegar, ef þú gerir ekki skyndilegar bendingar til hliðar og notar aðalvirkni, þá virkar það stöðugt.

Kostir

  1. Ekki hægir á sér.
  2. Lágt inntökumörk.
  3. Opinn uppspretta.
  4. Ókeypis.
  5. Skalast vel (klipping/afritun út úr kassanum)
  6. Innifalið í skrá yfir rússneskan hugbúnað sem samgönguráðuneytið mælir með.
  7. Tilvist opinbers stuðnings frá Yandex.

Heimild: www.habr.com

Bæta við athugasemd