ClickHouse adatbåzis az emberekért, vagy Idegen technológiåk

Alexey Lizunov, a leader in the Competence Center for Remote Service Channels of the IT Directorate at MKB

ClickHouse adatbåzis az emberekért, vagy Idegen technológiåk

As an alternative to the ELK stack (ElasticSearch, Logstash, Kibana), we are conducting research on using ClickHouse DB as a data storage solution for logs.

In this article, we would like to share our experience with ClickHouse DB and the preliminary results from the pilot operation. It should be noted that the results are impressive.


ClickHouse adatbåzis az emberekért, vagy Idegen technológiåk

Next, we will describe in detail how our system is configured and its components. But first, we would like to discuss this DB in general and why it deserves attention. ClickHouse DB is a high-performance analytical columnar database from Yandex. It is used in Yandex services and originally served as the primary data storage for Yandex.Metrica. It is open-source and free. As a developer, I have always been curious about how they implemented it, given the fantastically large amounts of data. The Yandex.Metrica user interface is very flexible and works quickly. Upon first acquaintance with this DB, the impression is: 'Finally! Done for the people!' Starting from the installation process to sending queries.

This DB has a very low entry threshold. Even a developer of average qualification can install it in a few minutes and start using it. Everything works smoothly. Even people who are not very familiar with Linux can quickly manage the installation and perform basic operations. Previously, when hearing about Big Data, Hadoop, Google BigTable, HDFS, an average developer might have thought it involved some terabytes or petabytes, believing that only superhumans could configure and develop for these systems. However, with the emergence of ClickHouse DB, we now have a simple and accessible tool with which we can solve previously unattainable tasks. All it takes is one fairly average machine and five minutes for installation. In other words, we have a database like MySQL, but designed for storing billions of records! A kind of super archiver with SQL language. It’s as if people have been handed alien weaponry.

About our log collection system

Az informĂĄciĂłgyƱjtĂ©shez az IIS webalkalmazĂĄsok standard formĂĄtumĂș naplĂłfĂĄjljait hasznĂĄljuk (jelenleg a naplĂłk parsingjĂĄn is dolgozunk, de a pilot ĂŒzemeltetĂ©s fĂĄzisĂĄban a fƑ cĂ©lunk az IIS naplĂłk gyƱjtĂ©se).

Teljes mĂ©rtĂ©kben az ELK stacktƑl nem tudtunk megszabadulni kĂŒlönbözƑ okok miatt, Ă©s tovĂĄbbra is hasznĂĄljuk a LogStash Ă©s Filebeat komponenseit, amelyek jĂłl bevĂĄltak Ă©s megbĂ­zhatĂłan dolgoznak.

A naplózås åltalånos sémåja az alåbbi åbrån låtható.

ClickHouse adatbåzis az emberekért, vagy Idegen technológiåk

A ClickHouse adatbĂĄzisba törtĂ©nƑ adatbejegyzĂ©sek sajĂĄtossĂĄga, hogy ritkĂĄn (mĂĄsodpercenkĂ©nt egyszer) nagy adagokban hajtjĂĄk vĂ©gre a bejegyzĂ©seket. Ez lĂĄthatĂłan a legproblĂ©mĂĄsabb rĂ©sz, amellyel a ClickHouse adatbĂĄzissal valĂł elsƑ tapasztalat sorĂĄn talĂĄlkozik az ember: a sĂ©ma kissĂ© bonyolultabbĂĄ vĂĄlik.
Ebben nagy segĂ­tsĂ©get nyĂșjtott a LogStash plugin, amely közvetlenĂŒl adatokat illeszt be a ClickHouse-ba. Ezt az összetevƑt ugyanazon a szerveren kell telepĂ­teni, mint az adatbĂĄzis. Így, mondhatni, ezt nem ajĂĄnlott megtenni, de gyakorlati szempontbĂłl, hogy ne kelljen kĂŒlön szervereket lĂ©trehozni, addig is, amĂ­g ez ugyanazon a szerveren van telepĂ­tve. Nem tapasztaltunk leĂĄllĂĄsokat vagy erƑforrĂĄskonfliktusokat az adatbĂĄzissal. TovĂĄbbĂĄ fontos megjegyezni, hogy a plugin rendelkezik egy hibakezelƑ mechanizmussal, amely megprĂłbĂĄlja Ășjra a hibĂĄs bejegyzĂ©seket. HibĂĄk esetĂ©n a plugin egy adathalmazt Ă­r a lemezre, amelyet nem sikerĂŒlt beilleszteni (a fĂĄjlformĂĄtum kĂ©nyelmes: javĂ­tĂĄs utĂĄn könnyen Ășjra beilleszthetƑ a korrigĂĄlt halmaz a clickhouse-client segĂ­tsĂ©gĂ©vel).

A hasznĂĄlt szoftverek teljes listĂĄjĂĄt az alĂĄbbi tĂĄblĂĄzat tartalmazza.

A hasznĂĄlt szoftverek listĂĄja

Név

LeĂ­rĂĄs

Link a disztribĂșciĂłhoz

NGINX

Reverse proxy a portkorlåtozås és az azonosítås szervezéséhez

Jelenleg nem alkalmazzåk a sémåban

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

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

FileBeat

FĂĄjlok naplĂłinak ĂĄtadĂĄsa.

https://www.elastic.co/downloads/beats/filebeat (Windows 64bit disztribĂșciĂł).

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

LogStash

NaplĂłgyƱjtƑ.

Hasznåljåk a FileBeat naplók gyƱjtésére, valamint a RabbitMQ sorból szårmazó naplók gyƱjtésére (a DMZ-ben talålható szerverek szåmåra).

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

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

Logstash-output-clickhouse

A Logstash plugin a naplók nagyadagokban való åtvitelére a ClickHouse adatbåzisba.

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

clickhousedb_fdw

NaplĂłarchĂ­vum 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

MegjegyzĂ©s: 2018 augusztusĂĄtĂłl a Yandex repozitĂłriumĂĄban megjelentek a „normĂĄlis” rpm csomagok a RHEL-hez, Ă­gy Ă©rdemes kiprĂłbĂĄlni Ƒket. TelepĂ­tĂ©skor az Altinity ĂĄltal kĂ©szĂ­tett csomagokat hasznĂĄltuk.

GrafanĂĄba

A naplĂłk vizualizĂĄlĂĄsa. Dashbordok beĂĄllĂ­tĂĄsa

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 bit) – legĂșjabb verziĂł

ClickHouse adatforrĂĄs a Grafana 4.6+ verziĂłhoz

Grafana plugin a ClickHouse adatforrĂĄssal

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

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

LogStash

A filebeat log router to RabbitMQ.

Note. Unfortunately, Filebeat does not have direct output to RabbitMQ, so an intermediate link in the form of Logstash is required.

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

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

RabbitMQ

Message queue. This is a buffer for log entries in the 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 (Required for RabbitMQ)

Erlang Runtime. Required for RabbitMQ operation.

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

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

The server configuration with ClickHouse DB is presented in the following table:

Név

Value

Megjegyzés

KonfigurĂĄciĂł

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

It is important to pay attention to the recommendations for using ClickHouse DB (https://clickhouse.yandex/docs/ru/operations/tips/)

System Software

OS: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

As you can see, this is a regular workstation.

The structure of the table for storing logs is as follows:

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;

We use default values for partitioning (by months) and index granularity. All fields largely correspond to IIS log records for HTTP request logging. Notably, separate fields are designated for storing UTM tags (they are parsed during the insertion stage from the query string field).

Also, several system fields have been added to the table to store information about systems, components, and servers. Details of these fields are provided below in the table. In one table, we store logs for several systems.

Név

LeĂ­rĂĄs

tĂĄmadĂĄsra

fld_app_name

Application/System Name
Allowed values:

  • site1.domain.com External site 1
  • site2.domain.com External site 2
  • internal-site1.domain.local Internal site 1

site1.domain.com

fld_app_module

System Module
Allowed values:

  • web — Website
  • svc — Website web service
  • intgr — Integration web service
  • bo — Admin panel (BackOffice)

szolgåltatås szeretne hozzåférni egy

fld_website_name

Website Name in IIS

Multiple systems, or even several instances of a single system module, can be deployed on one server.

web-main

fld_server_name

Server Name

web1.domain.com

fld_log_file_name

Path to the log file on the server

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Ez lehetƑvĂ© teszi a grafikonok hatĂ©kony felĂ©pĂ­tĂ©sĂ©t a GrafanĂĄban. PĂ©ldĂĄul a konkrĂ©t rendszer front-endjĂ©bƑl szĂĄrmazĂł lekĂ©rdezĂ©sek megtekintĂ©sĂ©t. Ez hasonlĂ­t a Yandex.Metrica weboldal-olvasĂłjĂĄhoz.

Itt van nĂ©hĂĄny statisztika az adatbĂĄzis hasznĂĄlatĂĄrĂłl az elmĂșlt kĂ©t hĂłnapban.

Rekordok szåma rendszerek és azok komponensei szerint

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.hu  │ web            │     131441 │
│ site2.domain.hu  │ web            │    1751081 │
│ site3.domain.hu  │ web            │  106887543 │
│ site3.domain.hu  │ svc            │   44908603 │
│ site3.domain.hu  │ intgr          │    9813911 │
│ site4.domain.hu  │ web            │     772095 │
│ site5.domain.hu  │ web            │   17037221 │
│ site5.domain.hu  │ intgr          │     838559 │
│ site5.domain.hu  │ bo             │       7404 │
│ site6.domain.hu  │ web            │     595877 │
│ site7.domain.hu  │ 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.)

Az adatok mérete a lemezen

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.

Az adatok tömörítési arånya az oszlopokban

VÁLASZ
    név,
    formåzottOlvashatóMéret(data_uncompressed_bytes) AS kiNemTömörített,
    formåzottOlvashatóMéret(data_compressed_bytes) AS tömörített,
    data_uncompressed_bytes / data_compressed_bytes AS tömörítési_aråny
FROM system.columns
WHERE table = 'log_web'
 
┌─nĂ©v────────────────────┬─kiNemTömörĂ­tett─┬─tömörĂ­tett─┬─────tömörĂ­tĂ©si_arĂĄny─┐
│ 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 sor talålható az eredményben. Elapsed: 0.005 sec.

A felhasznĂĄlt összetevƑk leĂ­rĂĄsa

FileBeat. FĂĄjlnaplĂłk tovĂĄbbĂ­tĂĄsa

Ez az összetevƑ figyelemmel kĂ­sĂ©ri a lemeznaplĂłk fĂĄjljaiban bekövetkezƑ vĂĄltozĂĄsokat, Ă©s az informĂĄciĂłkat ĂĄtkonvertĂĄlja a LogStash-be. Minden olyan szerveren telepĂ­tve van, ahol naplĂłfĂĄjlok kĂ©szĂŒlnek (ĂĄltalĂĄban IIS). Tail mĂłdban mƱködik (azaz csak az Ășjonnan hozzĂĄadott bejegyzĂ©seket tovĂĄbbĂ­tja a fĂĄjlba). De kĂŒlön is beĂĄllĂ­thatĂł teljes fĂĄjlok tovĂĄbbĂ­tĂĄsĂĄra. Ez kĂ©nyelmes, ha az elƑzƑ hĂłnapok adatait kell betölteni. EgyszerƱen helyezze a naplĂłfĂĄjlt egy mappĂĄba, Ă©s az automatikusan teljes egĂ©szĂ©ben elolvassa.

A szolgĂĄltatĂĄs leĂĄllĂ­tĂĄsakor az adatok tovĂĄbbitĂĄsa leĂĄll a tĂĄrolĂłba.

A konfigurĂĄciĂł pĂ©ldĂĄul a következƑkĂ©ppen nĂ©z ki:

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

LogStash. NaplĂłgyƱjtƑ

Ez az összetevƑ a FileBeat-tƑl (vagy a RabbitMQ soron keresztĂŒl) Ă©rkezƑ naplĂłbejegyzĂ©sek fogadĂĄsĂĄra, elemzĂ©sĂ©re Ă©s tömeges adatbĂĄzisba törtĂ©nƑ beszĂșrĂĄsra szolgĂĄl ClickHouse-ba.

A ClickHouse-ba valĂł beszĂșrĂĄshoz a Logstash-output-clickhouse bƑvĂ­tmĂ©nyt hasznĂĄljuk. A Logstash bƑvĂ­tmĂ©ny rendelkezik kĂ©rĂ©sretry mechanizmussal, de normĂĄl leĂĄllĂ­tĂĄs esetĂ©n jobb, ha magĂĄt a szolgĂĄltatĂĄst is leĂĄllĂ­tjuk. LeĂĄllĂ­tĂĄskor ĂŒzenetek halmozĂłdnak fel a RabbitMQ sorban, ezĂ©rt ha a leĂĄllĂĄs hosszĂș ideig tart, akkor jobban teszi, ha leĂĄllĂ­tja a Filebeat-eket a szervereken. Abban a sĂ©mĂĄban, ahol nem hasznĂĄlunk RabbitMQ-t (a helyi hĂĄlĂłzaton a Filebeat közvetlenĂŒl kĂŒldi a naplĂłkat a Logstash-ba), a Filebeat-ek megfelelöen Ă©s biztonsĂĄgosan mƱködnek, ezĂ©rt szĂĄmukra a kimenet elĂ©rhetetlensĂ©ge következmĂ©nyek nĂ©lkĂŒl mĂșlik el.

A konfigurĂĄciĂł pĂ©ldĂĄul a következƑkĂ©ppen nĂ©z ki:

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. NaplĂłzĂĄsi tĂĄrolĂł

Minden rendszer naplĂłja egy tĂĄblĂĄba kerĂŒl mentĂ©sre (lĂĄsd a cikk elejĂ©n). Ez a tĂĄblĂĄzat a kĂ©rĂ©sinformĂĄciĂłk tĂĄrolĂĄsĂĄra szolgĂĄl: minden paramĂ©ter hasonlĂł a kĂŒlönbözƑ formĂĄtumokhoz, pĂ©ldĂĄul IIS, Apache Ă©s Nginx naplĂłk esetĂ©ben. Az alkalmazĂĄsok naplĂłihoz, amelyek pĂ©ldĂĄul hibĂĄkat, informĂĄciĂłs ĂŒzeneteket, figyelmeztetĂ©seket rögzĂ­tenek, kĂŒlön tĂĄblĂĄzat lesz lĂ©trehozva a megfelelƑ struktĂșrĂĄval (jelenleg tervezĂ©s alatt ĂĄll).

A tĂĄblĂĄzat tervezĂ©se sorĂĄn nagyon fontos meghatĂĄrozni az elsƑdleges kulcsot (amely alapjĂĄn az adatok rendezĂ©sre kerĂŒlnek a tĂĄrolĂĄskor). Ez hatĂĄssal van az adatok tömörĂ­tĂ©sĂ©nek mĂ©rtĂ©kĂ©re Ă©s a lekĂ©rdezĂ©sek sebessĂ©gĂ©re. PĂ©ldĂĄnkban a kulcs a következƑ:
ORDER BY (fld_app_name, fld_app_module, logdatetime)
TehĂĄt a rendszer neve, a rendszer komponensĂ©nek neve Ă©s az esemĂ©ny idƑpontja szerint. Kezdetben az esemĂ©ny idƑpontja volt az elsƑ helyen. MiutĂĄn ezt az utolsĂł helyre költöztettĂŒk, a lekĂ©rdezĂ©sek körĂŒlbelĂŒl kĂ©tszer gyorsabban futottak. Az elsƑdleges kulcs mĂłdosĂ­tĂĄsa Ășjra kell lĂ©trehozni a tĂĄblĂĄt Ă©s Ășjra kell tölteni az adatokat, hogy a ClickHouse Ășjrarendezze az adatokat a lemezen. Ez egy nehĂ©z mƱvelet, ezĂ©rt Ă©rdemes elƑre gondolkodni arrĂłl, hogy mi tartozik a rendezĂ©si kulcsba.

Meg kell jegyezni, hogy a legĂșjabb verziĂłkban megjelent a LowCardinality adat tĂ­pusa. Ennek hasznĂĄlatĂĄval drĂĄmaian csökkenthetƑ a tömörĂ­tett adatok mĂ©rete az alacsony kardinalitĂĄsĂș (kevĂ©s opciĂłval rendelkezƑ) mezƑk esetĂ©ben.

Jelenleg a 19.6-os verziĂłt hasznĂĄljuk, Ă©s tervezzĂŒk, hogy frissĂ­tjĂŒk a legĂșjabb verziĂłra. Ezekben csodĂĄlatos funkciĂłk jelentek meg, mint pĂ©ldĂĄul az AdaptĂ­v GranularitĂĄs, a KihagyĂĄsos indexek Ă©s a DoubleDelta kĂłdolĂĄs.

AlapĂ©rtelmezĂ©s szerint a telepĂ­tĂ©s sorĂĄn a konfigurĂĄciĂłban a trace szint van beĂĄllĂ­tva. A naplĂłk forgatĂłdnak Ă©s archivĂĄlĂłdnak, de közben akĂĄr gigabĂĄjtokra is bƑvĂŒlhetnek. Ha nincs szĂŒksĂ©g rĂĄ, beĂĄllĂ­thatĂł a warning szint, amivel a naplĂł mĂ©rete jelentƑsen csökken. A naplĂłzĂĄs beĂĄllĂ­tĂĄsa a config.xml fĂĄjlban törtĂ©nik:

<!-- Lehetséges szintek: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger.h#L105 -->
<level>warning</level>

Néhåny hasznos parancs

Mivel az eredeti telepĂ­tƑcsomagok Debian alapjĂĄn kĂ©szĂŒlnek, mĂĄs Linux verziĂłkhoz az Altinity ĂĄltal kĂ©szĂŒlt csomagokat kell hasznĂĄlni. 

Itt talĂĄlhatĂł egy ĂștmutatĂł a repĂłjukra mutatĂł linkekkel: https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse
sudo yum search clickhouse-server
sudo yum install clickhouse-server.noarch
  
1. az ĂĄllapot ellenƑrzĂ©se
sudo systemctl status clickhouse-server
 
2. a szerver leĂĄllĂ­tĂĄsa
sudo systemctl stop clickhouse-server
 
3. a szerver indĂ­tĂĄsa
sudo systemctl start clickhouse-server
 
Futtatås a lekérdezések végrehajtåsåra többsoros módban (a ";" utåni végrehajtå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
 
A Logstash ClickHouse pluginje hiba esetén az összes csomagot egy fåjlba menti: /tmp/log_web_failed.json
Ezt a fåjlt manuålisan kijavíthatjuk, és megpróbålhatjuk felölteni a DB-be: 
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
 
kilépés a parancssorból
quit;
## TLS beĂĄllĂ­tĂĄs
https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2
 
openssl s_client -connect log.domain.com:9440 < /dev/null

LogStash. A FileBeat log routere RabbitMQ sorba

Ez az összetevƑ a FileBeat-tƑl Ă©rkezƑ logok RabbitMQ sorba törtĂ©nƑ irĂĄnyĂ­tĂĄsĂĄra szolgĂĄl. KĂ©t dolog van itt:

  1. Sajnos a FileBeat nem rendelkezik output plugin-nel az adatok közvetlen kiíråsåhoz RabbitMQ-ba. A Githubon talålható hibajegyek alapjån ez a funkció nem tervezett. Van plugin Kafka-hoz, de bizonyos okok miatt ezt nem hasznålhatjuk.
  2. KövetelmĂ©nyek vannak a logok DMZ-ben törtĂ©nƑ gyƱjtĂ©sĂ©re. Ezek alapjĂĄn a logok elƑször egy sorba kerĂŒlnek, majd a LogStash kĂ­vĂŒlrƑl olvassa a sorbejegyzĂ©seket.

Ezért a DMZ-ben elhelyezett szerverek esetében egy kicsit bonyolultabb rendszert kell alkalmazni. A konfiguråció példåul így néz ki:

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. Üzenetsor

Ez a komponens a DMZ-ben lĂ©vƑ naplĂłbejegyzĂ©sek pufferelĂ©sĂ©re szolgĂĄl. A bejegyzĂ©s a Filebeat → LogStash kapcsolaton keresztĂŒl törtĂ©nik. Az olvasĂĄs kĂ­vĂŒlrƑl, a DMZ-bƑl a LogStash ĂĄltal törtĂ©nik. A RabbitMQ-n keresztĂŒli hasznĂĄlat sorĂĄn körĂŒlbelĂŒl 4000 ĂŒzenetet dolgoz fel mĂĄsodpercenkĂ©nt.

Az ĂŒzenetek irĂĄnyĂ­tĂĄsa a rendszer neve alapjĂĄn van beĂĄllĂ­tva, azaz a FileBeat konfigurĂĄciĂłs adatainak alapjĂĄn. Minden ĂŒzenet egy sorba kerĂŒl. Ha bĂĄrmilyen okbĂłl leĂĄll a sorozatszolgĂĄltatĂĄs, az nem eredmĂ©nyez ĂŒzenetvesztĂ©st: a FileBeat hibĂĄt fog kapni a kapcsolatban, Ă©s ideiglenesen leĂĄllĂ­tja a kĂŒldĂ©st. A LogStash, ami a sorbĂłl olvas, szintĂ©n hĂĄlĂłzati hibĂĄkat fog kapni Ă©s vĂĄrni fog, amĂ­g a kapcsolat helyreĂĄll. Az adatok termĂ©szetesen nem fognak beĂ­rĂłdni az adatbĂĄzisba ebben az idƑszakban.

A következƑ utasĂ­tĂĄsok a sorok lĂ©trehozĂĄsĂĄra Ă©s beĂĄllĂ­tĂĄsĂĄra szolgĂĄlnak:

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. IrĂĄnyĂ­tĂłpultok

Ez a komponens a megfigyelĂ©si adatok vizualizĂĄlĂĄsĂĄra szolgĂĄl. Ehhez telepĂ­teni kell a ClickHouse datasource for Grafana 4.6+ plugint. Kicsit mĂłdosĂ­tanunk kellett rajta, hogy javĂ­tsuk az SQL-szƱrƑk feldolgozĂĄsĂĄnak hatĂ©konysĂĄgĂĄt az irĂĄnyĂ­tĂłpulton.

PĂ©ldĂĄul, a vĂĄltozĂłkat hasznĂĄljuk, Ă©s ha nincsenek megadva a szƱrƑmezƑben, akkor szeretnĂ©nk, ha nem generĂĄlna olyan feltĂ©telt a WHERE zĂĄradĂ©kban, mint ( uriStem = » AND uriStem != » ). Ebben az esetben a ClickHouse olvasni fogja az uriStem oszlopot. ÖsszessĂ©gĂ©ben kĂŒlönbözƑ lehetƑsĂ©geket prĂłbĂĄltunk ki, Ă©s vĂ©gĂŒl mĂłdosĂ­tottuk a plugint (makrĂł $valueIfEmpty), hogy ĂŒres Ă©rtĂ©k esetĂ©n 1-et adjon vissza, anĂ©lkĂŒl, hogy megemlĂ­tenĂ© magĂĄt az oszlopot.

Most pedig hasznålhatunk egy ilyen lekérdezést a grafikonhoz

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

amely Ă­gy SQL-re alakul (figyeljen, hogy az ĂŒres uriStem mezƑk egyszerƱen 1-re alakultak)

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

ZĂĄrĂĄs

A ClickHouse adatbĂĄzis megjelenĂ©se mĂ©rföldkƑnek szĂĄmĂ­t a piacon. Nehezen kĂ©pzelhetƑ el, hogy teljesen ingyen, egyik pillanatrĂłl a mĂĄsikra egy erƑteljes Ă©s gyakorlati eszközhöz jutottunk a nagy adatokkal valĂł munkĂĄhoz. TermĂ©szetesen a növekvƑ igĂ©nyekkel (pĂ©ldĂĄul több szerverre valĂł sharding Ă©s replikĂĄciĂł) a sĂ©ma bonyolultabbĂĄ vĂĄlik. Az elsƑ benyomĂĄsok alapjĂĄn azonban rendkĂ­vĂŒl kellemes dolgozni ezzel az adatbĂĄzissal. NyilvĂĄnvalĂł, hogy ez a termĂ©k az emberek szĂĄmĂĄra kĂ©szĂŒlt.

Az ElasticSearch-hoz kĂ©pest a logok tĂĄrolĂĄsĂĄnak Ă©s feldolgozĂĄsĂĄnak költsĂ©gei elƑzetes becslĂ©sek szerint öt-tĂ­zszeresĂ©re csökkennek. MĂĄs szavakkal, ha a jelenlegi adatmennyisĂ©ghez klaszterre lenne szĂŒksĂ©gĂŒnk több gĂ©pbƑl, akkor a ClickHouse hasznĂĄlatĂĄval elegendƑ lenne egy gyenge teljesĂ­tmĂ©nyƱ gĂ©p. Igen, az ElasticSearch-ben is vannak adatok tömörĂ­tĂ©sĂ©re vonatkozĂł mechanizmusok, Ă©s mĂĄs funkciĂłk, amelyek jelentƑsen csökkenthetik az erƑforrĂĄs-fogyasztĂĄst, de a ClickHouse-hoz kĂ©pest ez több költsĂ©get igĂ©nyel.

MindenfĂ©le kĂŒlönleges optimalizĂĄlĂĄs nĂ©lkĂŒl, alapbeĂĄllĂ­tĂĄssal, az adatok betöltĂ©se Ă©s a lekĂ©rdezĂ©sek az adatbĂĄzisbĂłl elkĂ©pesztƑ sebessĂ©ggel mƱködnek. Jelenleg nem sok adatunk van (körĂŒlbelĂŒl 200 milliĂł rekord), de a szerver gyenge. Ezt az eszközt a jövƑben mĂĄs cĂ©lokra is felhasznĂĄlhatjuk, amelyek nem kapcsolĂłdnak a logok tĂĄrolĂĄsĂĄhoz. PĂ©ldĂĄul ĂĄtfogĂł analitikĂĄra, biztonsĂĄgi terĂŒleten, gĂ©pi tanulĂĄsban.

Kicsit a hĂĄtrĂĄnyokrĂłl Ă©s elƑnyökrƑl.

HĂĄtrĂĄnyok

  1. Rekordok nagyobb csomagokban való betöltése. Ez egyrészt egy funkció, de mindenképpen tovåbbi komponenseket kell hasznålni a rekordok pufferezéséhez. Ez a feladat nem mindig egyszerƱ, de mégis megoldható. Szeretném egyszerƱsíteni a sémåt.
  2. NĂ©hĂĄny egzotikus funkciĂł vagy Ășj jellemzƑ gyakran megsĂ©rĂŒl az Ășj verziĂłkban. Ez aggodalmat kelt, csökkentve az Ășj verziĂłra valĂł frissĂ­tĂ©s irĂĄnti vĂĄgyat. PĂ©ldĂĄul a Kafka tĂĄblamotor – egy nagyon hasznos funkciĂł, amely lehetƑvĂ© teszi az esemĂ©nyek közvetlen olvasĂĄsĂĄt a KafkĂĄbĂłl, anĂ©lkĂŒl, hogy fogyasztĂłkat kellene megvalĂłsĂ­tani. De a GitHub-ra feltett problĂ©mĂĄk szĂĄma alapjĂĄn egyelƑre Ăłvatosak vagyunk e motor hasznĂĄlatĂĄval a termelĂ©sben. Azonban, ha nem teszĂŒnk hirtelen lĂ©pĂ©seket, Ă©s hasznĂĄljuk az alapvetƑ funkciĂłt, akkor stabilan mƱködik.

ElƑnyök

  1. Nem lassul.
  2. Alacsony belĂ©pĂ©si kĂŒszöb.
  3. NyĂ­lt forrĂĄskĂłdĂș.
  4. Ingyenes.
  5. Jól skålåzható (töredezés/replicålås "tartalmazva")
  6. A MinComSzvĂĄz ĂĄltal ajĂĄnlott orosz szoftverek nyilvĂĄntartĂĄsĂĄba tartozik.
  7. Hivatalos tĂĄmogatĂĄs elĂ©rhetƑsĂ©ge a Yandex-tƑl.

ForrĂĄs: habr.com

MegbĂ­zhatĂł hosting vĂĄsĂĄrlĂĄsa weboldalak szĂĄmĂĄra, DDoS vĂ©delemmel, VPS VDS szerverek. đŸ”„ MegbĂ­zhatĂł webtĂĄrhely vĂĄsĂĄrlĂĄsa DDoS vĂ©delemmel, VPS VDS szerverek | ProHoster