ClickHouse База на податоци за луѓе, или Alien Technologies

Алексеј Лизунов, раководител на Надлежен центар за далечински сервисни канали на Дирекцијата за информатички технологии на МКБ

ClickHouse База на податоци за луѓе, или Alien Technologies

Како алтернатива на стекот ELK (ElasticSearch, Logstash, Kibana), правиме истражување за користење на базата на податоци ClickHouse како складиште на податоци за дневници.

Во оваа статија би сакале да зборуваме за нашето искуство со користење на базата на податоци ClickHouse и за прелиминарните резултати од пилот операцијата. Веднаш треба да се забележи дека резултатите беа импресивни.


ClickHouse База на податоци за луѓе, или Alien Technologies

Следно, ќе опишеме подетално како е конфигуриран нашиот систем и од кои компоненти се состои. Но, сега би сакал да зборувам малку за оваа база на податоци како целина, и зошто вреди да се обрне внимание. Базата на податоци ClickHouse е аналитичка колонообразна база на податоци со високи перформанси од Yandex. Се користи во услугите на Yandex, првично е главното складирање на податоци за Yandex.Metrica. Систем со отворен код, бесплатен. Од гледна точка на програмери, отсекогаш сум се прашувал како го имплементирале, бидејќи има фантастично големи податоци. И самиот кориснички интерфејс на Metrica е многу флексибилен и брз. При првото запознавање со оваа база на податоци се добива впечаток: „Па, конечно! Создаден за народот! Почнувајќи од процесот на инсталација и завршувајќи со испраќање барања.

Оваа база на податоци има многу низок влезен праг. Дури и просечно квалификуван програмер може да ја инсталира оваа база на податоци за неколку минути и да почне да ја користи. Сè функционира јасно. Дури и луѓето кои се нови во Linux можат брзо да се справат со инсталацијата и да ги направат наједноставните операции. Ако порано, со зборовите Big Data, Hadoop, Google BigTable, HDFS, обичен програмер имал идеи дека станува збор за некои терабајти, петабајти, дека некои натлуѓе се вклучени во поставките и развојот на овие системи, тогаш со доаѓањето на ClickHouse база на податоци, добивме едноставна, разбирлива алатка со која можете да решите досега недостижен опсег на задачи. Потребна е само една прилично просечна машина и пет минути за да се инсталира. Тоа е, добивме таква база на податоци како, на пример, MySql, но само за складирање милијарди записи! Одреден супер-архиватор со јазикот SQL. Тоа е како на луѓето да им го дале оружјето на вонземјаните.

За нашиот систем за сеча

За да се соберат информации, се користат датотеки за евиденција на IIS со веб-апликации со стандарден формат (моментално ги анализираме и дневниците на апликациите, но главната цел во пилот фазата е собирање логови на IIS).

Од различни причини, не можевме целосно да го напуштиме стекот ELK и продолжуваме да ги користиме компонентите LogStash и Filebeat, кои добро се докажаа и работат доста сигурно и предвидливо.

Општата шема за сеча е прикажана на сликата подолу:

ClickHouse База на податоци за луѓе, или Alien Technologies

Карактеристика на запишување податоци во базата на податоци на ClickHouse е реткото (еднаш во секунда) вметнување на записи во големи серии. Ова, очигледно, е „најпроблематичниот“ дел со кој се среќавате кога за првпат ќе искусите работа со базата на податоци ClickHouse: шемата станува малку посложена.
Приклучокот за LogStash, кој директно вметнува податоци во ClickHouse, многу помогна овде. Оваа компонента е распоредена на истиот сервер како и самата база на податоци. Значи, генерално кажано, не се препорачува да се прави тоа, туку од практична гледна точка, за да не се произведуваат посебни сервери додека е распореден на истиот сервер. Не забележавме никакви неуспеси или конфликти со ресурсите со базата на податоци. Покрај тоа, треба да се забележи дека приклучокот има механизам за повторно обид во случај на грешки. И во случај на грешки, приклучокот запишува на диск серија на податоци што не може да се вметнат (форматот на датотеката е погоден: по уредувањето, можете лесно да ја вметнете коригираната серија користејќи clickhouse-client).

Комплетна листа на софтвер што се користи во шемата е претставена во табелата:

Список на користен софтвер

Име

Опис

Врска за дистрибуција

nginx

Обратно-прокси за ограничување на пристапот од пристаништа и организирање овластување

Во моментов не се користи во шемата

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

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

FileBeat

Пренос на логови на датотеки.

https://www.elastic.co/downloads/beats/filebeat (комплет за дистрибуција за Windows 64bit).

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

logstash

Собирач на трупци.

Се користи за собирање дневници од FileBeat, како и за собирање логови од редот на RabbitMQ (за сервери кои се во DMZ.)

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

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

Logstash-output-clickhouse

Loagstash приклучок за пренос на дневници во базата на податоци на ClickHouse во серии

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

/usr/share/logstash/bin/logstash-plugin инсталирај logstash-output-clickhouse

/usr/share/logstash/bin/logstash-plugin инсталирај logstash-filter-prune

/usr/share/logstash/bin/logstash-plugin инсталирај logstash-filter-multiline

Кликни куќа

Складирање на дневници 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

Забелешка. Почнувајќи од август 2018 година, во складиштето на Yandex се појавија „нормални“ вртежи во минута за RHEL, па можете да се обидете да ги користите. Во времето на инсталацијата, користевме пакети изградени од Altinity.

Графана

Визуелизација на дневник. Поставување контролни табли

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 Bit) - најнова верзија

Извор на податоци на ClickHouse за Grafana 4.6+

Приклучок за Grafana со извор на податоци на ClickHouse

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

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

logstash

Пријавете го рутерот од FileBeat до редицата RabbitMQ.

Забелешка. За жал, FileBeat не излегува директно на RabbitMQ, па затоа е потребна средна врска во форма на Logstash

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

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

Зајакот MQ

редица за пораки. Ова е тампон за дневници во 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 (потребно за RabbitMQ)

Ерланг време на траење. Потребно за RabbitMQ да работи

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

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

Конфигурацијата на серверот со базата на податоци ClickHouse е претставена во следната табела:

Име

Вредност

Имајте на ум

Конфигурација

HDD: 40 GB
RAM: 8GB
Процесор: Core 2 2Ghz

Неопходно е да се обрне внимание на советите за управување со базата на податоци ClickHouse (https://clickhouse.yandex/docs/ru/operations/tips/)

Општ системски софтвер

ОС: Red Hat Enterprise Linux Server (Maipo)

JRE (Јава 8)

 

Како што можете да видите, ова е обична работна станица.

Структурата на табелата за складирање на дневници е како што следува:

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;

Ние користиме стандардна партиција (по месец) и грануларност на индексот. Сите полиња практично одговараат на записите во дневникот на IIS за евидентирање на http барања. Одделно, забележуваме дека има посебни полиња за складирање на utm-ознаки (тие се анализираат во фазата на вметнување во табелата од полето за низа за пребарување).

Исто така, на табелата се додадени неколку системски полиња за складирање на информации за системи, компоненти, сервери. Погледнете ја табелата подолу за опис на овие полиња. Во една табела складираме дневници за неколку системи.

Име

Опис

Пример

fld_app_name

Име на апликација/систем
Валидни вредности:

  • site1.domain.com Надворешна локација 1
  • site2.domain.com Надворешна локација 2
  • внатрешен-сајт1.домен.локален Внатрешна локација 1

site1.domain.com

fld_app_module

Системски модул
Валидни вредности:

  • веб - веб-страница
  • svc - услуга на веб-страница
  • intgr - Веб сервис за интеграција
  • bo - Администратор (BackOffice)

веб-

fld_website_name

Име на страницата во IIS

Неколку системи може да се распоредат на еден сервер, па дури и неколку примери на еден системски модул

веб главна

fld_server_name

Име на серверот

web1.domain.com

fld_log_file_name

Патека до датотеката за евиденција на серверот

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Ова ви овозможува ефикасно да изградите графикони во Графана. На пример, прегледајте ги барањата од предниот дел на одреден систем. Ова е слично на бројачот на страницата во Yandex.Metrica.

Еве неколку статистички податоци за користењето на базата за два месеци.

Број на записи поделени по системи и нивни компоненти

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

Количината на податоци на дискот

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.

Степен на компресија на податоци во колони

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.

Опис на користени компоненти

FileBeat. Пренесување логови на датотеки

Оваа компонента ги следи промените во датотеките за евиденција на дискот и ги пренесува информациите до LogStash. Инсталиран на сите сервери каде што се напишани датотеките за евиденција (обично IIS). Работи во режим на опашка (т.е. ги пренесува само додадените записи во датотеката). Но, одделно може да се конфигурира за пренос на цели датотеки. Ова е корисно кога треба да преземете податоци од претходните месеци. Само ставете ја датотеката за евиденција во папка и таа ќе ја прочита во целост.

Кога услугата е прекината, податоците повеќе не се пренесуваат понатаму во складиштето.

Примерна конфигурација изгледа вака:

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. Собирач на дневници

Оваа компонента е дизајнирана да прима записи во дневникот од FileBeat (или преку редот на RabbitMQ), парсирање и вметнување на серии во базата на податоци на ClickHouse.

За вметнување во ClickHouse, се користи приклучокот Logstash-output-clickhouse. Приклучокот Logstash има механизам за повторување на барањето, но со редовно исклучување, подобро е да се прекине самата услуга. Кога ќе се запре, пораките ќе се акумулираат во редот на RabbitMQ, па ако застанувањето е подолго време, тогаш подобро е да се запре Filebeats на серверите. Во шема каде што RabbitMQ не се користи (на локалната мрежа, Filebeat директно испраќа логови до Logstash), Filebeats работат сосема прифатливо и безбедно, така што за нив недостапноста на излезот поминува без последици.

Примерна конфигурација изгледа вака:

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

цевководи.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"

кликхаус. Складирање на дневници

Дневниците за сите системи се чуваат во една табела (види на почетокот на статијата). Наменет е да складира информации за барањата: сите параметри се слични за различни формати, како што се дневници на IIS, дневници на Apache и nginx. За дневници на апликации, во кои, на пример, се евидентираат грешки, информативни пораки, предупредувања, ќе биде обезбедена посебна табела со соодветна структура (во моментов во фаза на дизајнирање).

Кога дизајнирате табела, многу е важно да се одлучите за примарниот клуч (со кој ќе се подредат податоците за време на складирањето). Степенот на компресија на податоците и брзината на барањето зависат од ова. Во нашиот пример, клучот е
НАРАЧАЈ ПО (fld_app_name, fld_app_module, logdatetime)
Тоа е, со името на системот, името на системската компонента и датумот на настанот. Првично, датумот на настанот беше прв. По преместувањето на последното место, прашањата почнаа да работат околу двојно побрзо. Промената на примарниот клуч ќе бара повторно креирање на табелата и повторно вчитување на податоците, така што ClickHouse повторно ќе ги подреди податоците на дискот. Ова е тешка операција, па затоа е добра идеја да размислите многу за тоа што треба да биде вклучено во клучот за сортирање.

Исто така, треба да се забележи дека типот на податоци LowCardinality се појави во релативно неодамнешните верзии. Кога го користите, големината на компресираните податоци е драстично намалена за оние полиња кои имаат мала кардиналност (малку опции).

Моментално се користи верзијата 19.6 и планираме да се обидеме да ја ажурираме до најновата верзија. Тие имаат прекрасни карактеристики како што се Прилагодлива грануларност, индекси за прескокнување и кодек DoubleDelta, на пример.

Стандардно, за време на инсталацијата, нивото на евиденција е поставено на следење. Дневниците се ротираат и архивираат, но во исто време се прошируваат до гигабајт. Ако нема потреба, тогаш можете да го поставите нивото на предупредување, тогаш големината на дневникот е драстично намалена. Поставката за логирање е поставена во датотеката config.xml:

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

Некои корисни команди

Поскольку оригинальные пакеты установки собираются по 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. Пријавете го рутерот од FileBeat до редица RabbitMQ

Оваа компонента се користи за насочување на дневниците кои доаѓаат од FileBeat до редот на RabbitMQ. Тука има две точки:

  1. За жал, FileBeat нема излезен приклучок за директно пишување на RabbitMQ. И таквата функционалност, судејќи според прашањето на нивниот github, не е планирана за имплементација. Постои додаток за Кафка, но поради некоја причина не можеме да го користиме дома.
  2. Постојат барања за собирање трупци во DMZ. Врз основа на нив, дневниците мора прво да се додадат во редот, а потоа LogStash ги чита записите од редот однадвор.

Затоа, за случајот кога серверите се наоѓаат во DMZ треба да се користи таква малку комплицирана шема. Примерна конфигурација изгледа вака:

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. редица за пораки

Оваа компонента се користи за баферирање на записите во дневникот во DMZ. Снимањето се врши преку еден куп Filebeat → LogStash. Читањето се врши надвор од DMZ преку LogStash. Кога се работи преку RabboitMQ, се обработуваат околу 4 илјади пораки во секунда.

Рутирањето на пораките е конфигурирано според името на системот, т.е. врз основа на конфигурациските податоци на FileBeat. Сите пораки одат во една редица. Ако поради некоја причина услугата за чекање е прекината, тогаш тоа нема да доведе до губење на пораките: FileBeats ќе прима грешки во врската и привремено ќе го прекине испраќањето. И LogStash што чита од редот исто така ќе добие мрежни грешки и ќе чека да се врати врската. Во овој случај, податоците, се разбира, повеќе нема да се запишуваат во базата на податоци.

Следниве инструкции се користат за креирање и конфигурирање на редици:

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"

Графана. Контролни табли

Оваа компонента се користи за визуелизација на податоците од мониторингот. Во овој случај, треба да го инсталирате податочниот извор на ClickHouse за приклучокот Grafana 4.6+. Моравме малку да го дотеруваме за да ја подобриме ефикасноста на обработката на SQL филтрите на контролната табла.

На пример, ние користиме променливи, и ако тие не се поставени во полето за филтрирање, тогаш би сакале да не генерира услов во WHERE на формата ( uriStem = » И uriStem != » ). Во овој случај, ClickHouse ќе ја прочита колоната uriStem. Во принцип, пробавме различни опции и на крајот го коригиравме додатокот (макрото $valueIfEmpty), така што во случај на празна вредност враќа 1, без да ја спомене самата колона.

И сега можете да го користите ова барање за графикот

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

што се преведува на овој SQL (забележете дека празните полиња uriStem се претворени во само 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

Заклучок

Појавата на базата на податоци ClickHouse стана значаен настан на пазарот. Тешко беше да се замисли дека, потполно бесплатно, во еден миг бевме вооружени со моќна и практична алатка за работа со големи податоци. Се разбира, со зголемување на потребите (на пример, споделување и репликација на повеќе сервери), шемата ќе стане посложена. Но, на првиот впечаток, работата со оваа база на податоци е многу пријатна. Се гледа дека производот е направен „за луѓе“.

Во споредба со ElasticSearch, се проценува дека трошоците за складирање и обработка на дневниците ќе бидат намалени за пет до десет пати. Со други зборови, ако за сегашната количина на податоци би требало да поставиме кластер од неколку машини, тогаш кога користиме ClickHouse, доволна ни е една машина со мала моќност. Да, се разбира, ElasticSearch има и механизми за компресија на податоци на дискот и други функции кои можат значително да ја намалат потрошувачката на ресурси, но во споредба со ClickHouse, ова ќе биде поскапо.

Без никакви посебни оптимизации од наша страна, на стандардните поставки, вчитувањето на податоците и избирањето од базата на податоци работи со неверојатна брзина. Сè уште немаме многу податоци (околу 200 милиони записи), но самиот сервер е слаб. Можеме да ја користиме оваа алатка во иднина за други цели кои не се поврзани со складирање на дневници. На пример, за аналитика од крај до крај, во областа на безбедноста, машинско учење.

На крајот, малку за добрите и лошите страни.

Конс

  1. Вчитување записи во големи серии. Од една страна, ова е карактеристика, но сепак треба да користите дополнителни компоненти за баферирање на записите. Оваа задача не е секогаш лесна, но сепак решлива. И јас би сакал да ја поедноставам шемата.
  2. Некои егзотични функционалности или нови функции често се распаѓаат во новите верзии. Ова предизвикува загриженост, намалувајќи ја желбата за надградба на нова верзија. На пример, моторот за табели Кафка е многу корисна карактеристика што ви овозможува директно да читате настани од Кафка, без да ги имплементирате потрошувачите. Но, судејќи според бројот на проблеми на github, сепак внимаваме да не го користиме овој мотор во производството. Меѓутоа, ако не правите ненадејни гестови на страна и не ја користите главната функционалност, тогаш таа работи стабилно.

Добрите

  1. Не успорува.
  2. Низок влезен праг.
  3. Отворен извор.
  4. Бесплатно.
  5. Добро се скали (разделување/репликација надвор од кутијата)
  6. Вклучено во регистарот на руски софтвер препорачан од Министерството за комуникации.
  7. Присуство на официјална поддршка од Yandex.

Извор: www.habr.com

Додадете коментар