ЦлицкХоусе база података за људе, или Алиен технологије

Алексеј Лизунов, руководилац центра компетенција за канале даљинског сервиса Дирекције за информационе технологије ИЦБ-а

ЦлицкХоусе база података за људе, или Алиен технологије

Као алтернативу ЕЛК стеку (ЕластицСеарцх, Логстасх, Кибана), спроводимо истраживање о коришћењу ЦлицкХоусе базе података као складишта података за логове.

У овом чланку желимо да говоримо о нашем искуству коришћења ЦлицкХоусе базе података и прелиминарним резултатима пилот операције. Одмах је вредно напоменути да су резултати били импресивни.


ЦлицкХоусе база података за људе, или Алиен технологије

Затим ћемо детаљније описати како је наш систем конфигурисан и од којих компоненти се састоји. Али сада бих желео да причам мало о овој бази података у целини и зашто је вредно обратити пажњу. ЦлицкХоусе база података је аналитичка стубна база података високих перформанси компаније Иандек. Користи се у Иандек услугама, у почетку је ово главно складиште података за Иандек.Метрица. Систем отвореног кода, бесплатан. Са тачке гледишта програмера, увек сам се питао како су то имплементирали, јер постоје фантастично велики подаци. И сам кориснички интерфејс Метрица је веома флексибилан и ради брзо. Када се први пут упознате са овом базом података, стичете утисак: „Па, коначно! Направљено „за народ“! Од процеса инсталације до слања захтева.”

Ова база података има веома ниску улазну баријеру. Чак и просечан програмер може да инсталира ову базу података за неколико минута и почне да је користи. Све ради глатко. Чак и људи који су нови у Линук-у могу брзо да се носе са инсталацијом и обављају једноставне операције. Ако је раније, када је чуо речи Биг Дата, Хадооп, Гоогле БигТабле, ХДФС, просечан програмер имао идеју да је реч о неким терабајтима, петабајтима, да су неки надљуди укључени у постављање и развој ових система, онда са појавом од ЦлицкХоусе базе података добили смо једноставну, разумљиву алатку помоћу које можете решити до сада недостижан низ проблема. Све што је потребно је једна прилично просечна машина и пет минута за инсталацију. Односно, добили смо базу података као, на пример, МиСкл, али само за чување милијарди записа! Нека врста суперархиватора са СКЛ језиком. Као да је људима дато ванземаљско оружје.

О нашем систему прикупљања дневника

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

Нисмо били у могућности да потпуно напустимо ЕЛК стек из различитих разлога, и настављамо да користимо компоненте ЛогСтасх и Филебеат, које су се добро показале и раде прилично поуздано и предвидљиво.

Општа шема евидентирања је приказана на слици испод:

ЦлицкХоусе база података за људе, или Алиен технологије

Карактеристика снимања података у ЦлицкХоусе бази података је ретко (једном у секунди) уметање записа у великим серијама. Ово је, очигледно, најпроблематичнији део са којим се сусрећете када први пут радите са ЦлицкХоусе базом података: шема постаје мало компликованија.
Ту је много помогао додатак за ЛогСтасх, који директно убацује податке у ЦлицкХоусе. Ова компонента је распоређена на истом серверу као и сама база података. Дакле, уопштено говорећи, није препоручљиво да се то ради, већ са практичне тачке гледишта, како се не би правили одвојени сервери док је распоређен на истом серверу. Нисмо приметили никакве грешке или сукобе ресурса са базом података. Поред тога, треба напоменути да додатак има механизам за поновно покретање у случају грешака. А у случају грешака, додатак записује на диск групу података који се не могу убацити (формат датотеке је згодан: након уређивања, можете лако да убаците исправљену серију користећи цлицкхоусе-цлиент).

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

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

Име

Опис

Линк до дистрибуције

НГИНКС

Реверсе-проки за ограничавање приступа портом и организовање ауторизације

Тренутно се не користи у шеми

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

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

ФилеБеат

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

https://www.elastic.co/downloads/beats/filebeat (дистрибуција за Виндовс 64бит).

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

ЛогСтасх

Сакупљач трупаца.

Користи се за прикупљање евиденције из ФилеБеат-а, као и за прикупљање евиденције из реда РаббитМК (за сервере који се налазе у ДМЗ-у.)

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

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

Логстасх- оутпут- цлицкхоусе

Лоагстасх додатак за пренос евиденције у ЦлицкХоусе базу података у серијама

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

/уср/схаре/логстасх/бин/логстасх-плугин инсталл логстасх-оутпут-цлицкхоусе

/уср/схаре/логстасх/бин/логстасх-плугин инсталирај логстасх-филтер-пруне

/уср/схаре/логстасх/бин/логстасх-плугин инсталирај логстасх-филтер-мултилине

ЦлицкХоусе

Складиште дневника 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, „нормалне“ верзије рпм за РХЕЛ су се појавиле у Иандек спремишту, тако да можете покушати да их користите. У време инсталације користили смо пакете које је саставио Алтинити.

Графана

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

https://grafana.com/

https://grafana.com/grafana/download

Редхат & Центос (64 Бит) – најновија верзија

ЦлицкХоусе извор података за Графана 4.6+

Додатак за Графана са ЦлицкХоусе извором података

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

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

ЛогСтасх

Рутер за евиденцију од ФилеБеат до РаббитМК реда.

Белешка. Нажалост, ФилеБеат нема излаз директно у РаббитМК, тако да је потребна посредна веза у облику Логстасх-а

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

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

РаббитМК

Ред порука. Ово је бафер уноса дневника у ДМЗ

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

Ерланг Рунтиме (потребно за РаббитМК)

Ерланг рунтиме. Потребно је да РаббитМК ради

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

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

Конфигурација сервера са ЦлицкХоусе базом података је представљена у следећој табели:

Име

Вредност

Приметити

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

ХДД: 40 ГБ
РАМ КСНУМКСГБ
Процесор: Цоре 2 2 Гхз

Треба обратити пажњу на савете за коришћење ЦлицкХоусе базе података (https://clickhouse.yandex/docs/ru/operations/tips/)

Системски софтвер

ОС: Ред Хат Ентерприсе Линук сервер (Маипо)

ЈРЕ (Јава 8)

 

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

Структура табеле за чување дневника је следећа:

лог_веб.скл

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;

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

Такође, неколико системских поља је додато у табелу за чување информација о системима, компонентама и серверима. За опис ових поља, погледајте табелу испод. У једној табели чувамо дневнике за неколико система.

Име

Опис

Пример

флд_апп_наме

Назив апликације/система
Важеће вредности:

  • сите1.домаин.цом Екстерни сајт 1
  • сите2.домаин.цом Екстерни сајт 2
  • интернал-сите1.домаин.лоцал Интерни сајт 1

сите1.домаин.цом

флд_апп_модуле

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

  • веб - Вебсите
  • свц — Веб услуга веб локације
  • интгр — Услуга веб интеграције
  • бо — Администратор (БацкОффице)

web

флд_вебсите_наме

Име локације у ИИС-у

На једном серверу може бити постављено неколико система, или чак неколико инстанци једног системског модула

веб-маин

флд_сервер_наме

Име сервера

веб1.домаин.цом

флд_лог_филе_наме

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

Фром:инетпублогсЛогФилес
В3СВЦ1у_ек190711.лог

Ово вам омогућава да ефикасно градите графиконе у Графани. На пример, прегледајте захтеве са предњег дела одређеног система. Ово је слично бројачу сајтова у Иандек.Метрици.

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

Број записа по систему и компоненти

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.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: ~

ЛогСтасх. Сакупљач трупаца

Ова компонента је дизајнирана да прима записе дневника из ФилеБеат-а (или преко реда РаббитМК), анализира и убацује их у серијама у ЦлицкХоусе базу података.

За уметање у ЦлицкХоусе користите додатак Логстасх-оутпут-цлицкхоусе. Додатак Логстасх има механизам за поновно праћење захтева, али током редовног гашења боље је зауставити саму услугу. Када се зауставе, поруке ће се акумулирати у РаббитМК реду, тако да ако је заустављање на дуже време, онда је боље зауставити Филебеатс на серверима. У шеми где се РаббитМК не користи (на локалној мрежи Филебеат директно шаље логове у Логстасх), Филебеатс раде сасвим прихватљиво и безбедно, тако да за њих недоступност излаза нема последица.

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

лог_веб__филебеат_цлицкхоусе.цонф

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

пипелинес.имл

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

ЦлицкХоусе. Складиште дневника

Дневници за све системе се чувају у једној табели (погледајте на почетку чланка). Дизајниран је да чува информације о захтевима: сви параметри су слични за различите формате, на пример ИИС евиденције, апацхе и нгинк евиденције. За евиденције апликација у којима се, на пример, бележе грешке, информативне поруке, упозорења, биће обезбеђена посебна табела са одговарајућом структуром (тренутно у фази пројектовања).

Приликом пројектовања табеле веома је важно одлучити се за примарни кључ (по коме ће се подаци сортирати током складиштења). Од тога зависи степен компресије података и брзина упита. У нашем примеру, кључ је
ОРДЕР БИ (флд_апп_наме, флд_апп_модуле, логдатетиме)
Односно, по имену система, називу компоненте система и датуму догађаја. У почетку је датум догађаја био први. Након померања на последње место, упити су почели да раде отприлике дупло брже. Промена примарног кључа ће захтевати поновно креирање табеле и поновно отпремање података тако да ће ЦлицкХоусе поново сортирати податке на диску. Ово је тешка операција, па је препоручљиво унапред добро размислити шта би требало да буде укључено у кључ за сортирање.

Такође треба напоменути да се тип података ЛовЦардиналити појавио у релативно новијим верзијама. Када се користи, величина компримованих података се нагло смањује за она поља која имају ниску кардиналност (неколико опција).

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

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

<!-- 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

ЛогСтасх. Рутер дневника од ФилеБеат до РаббитМК реда

Ова компонента се користи за рутирање дневника који долазе из ФилеБеат-а у ред РаббитМК. Овде постоје две тачке:

  1. Нажалост, ФилеБеат нема излазни додатак за писање директно у РаббитМК. А таква функционалност, судећи по објави на њиховом гитхубу, није планирана за имплементацију. Постоји додатак за Кафку, али из одређених разлога не можемо да га користимо сами.
  2. Постоје захтеви за прикупљање трупаца у ДМЗ. На основу њих, евиденције се прво морају ставити у ред, а затим ЛогСтасх екстерно чита записе из реда.

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

иис_в3ц_логс__филебеат_раббитмк.цонф

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

РаббитМК. Ред порука

Ова компонента се користи за баферовање уноса дневника у ДМЗ. Снимање се врши преко Филебеат → ЛогСтасх линка. Читање се врши изван ДМЗ-а преко ЛогСтасх-а. Када се ради преко РаббитМК-а, обрађује се око 4 хиљаде порука у секунди.

Рутирање порука је конфигурисано именом система, тј. на основу података о конфигурацији ФилеБеат-а. Све поруке иду у један ред. Ако је из неког разлога услуга чекања заустављена, то неће довести до губитка поруке: ФилеБеатс ће примити грешке у вези и привремено ће престати са слањем. А ЛогСтасх, који чита из реда, такође ће примати мрежне грешке и чекати да се веза врати. У овом случају, наравно, подаци више неће бити уписани у базу података.

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

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"

Графана. Дасхбоардс

Ова компонента се користи за визуелизацију података праћења. У овом случају, потребно је да инсталирате ЦлицкХоусе извор података за додатак Графана 4.6+. Морали смо да га мало подесимо да бисмо побољшали ефикасност обраде СКЛ филтера на контролној табли.

На пример, користимо променљиве, а ако нису наведене у пољу филтера, онда бисмо желели да не генерише услов у ВХЕРЕ обрасца ( уриСтем = "АНД уриСтем != "). У овом случају, ЦлицкХоусе ће прочитати колону уриСтем. Дакле, испробали смо различите опције и коначно поправили додатак (макро $валуеИфЕмпти) да враћа 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')

који се овако конвертује у СКЛ (имајте на уму да су празна поља уриСтем конвертована у само 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

Закључак

Појава ЦлицкХоусе базе података постала је значајан догађај на тржишту. Било је тешко замислити да смо у трену, потпуно бесплатно, били наоружани моћним и практичним алатом за рад са великим подацима. Наравно, како се потребе повећавају (на пример, дељење и репликација на више сервера), шема ће постати сложенија. Али према првим утисцима, рад са овом базом података је веома пријатан. Јасно је да је производ направљен „за људе“.

У поређењу са ЕластицСеарцх-ом, трошкови складиштења и обраде трупаца, према прелиминарним проценама, мањи су за пет до десет пута. Другим речима, ако бисмо за тренутни обим података морали да поставимо кластер од неколико машина, онда када користимо ЦлицкХоусе потребна нам је само једна машина мале снаге. Да, наравно, ЕластицСеарцх такође има механизме компресије података на диску и друге карактеристике које могу значајно смањити потрошњу ресурса, али у поређењу са ЦлицкХоусе-ом, то ће захтевати веће трошкове.

Без икаквих посебних оптимизација са наше стране, са подразумеваним подешавањима, учитавање података и преузимање података из базе података ради невероватном брзином. Још увек немамо много података (око 200 милиона записа), али сам сервер је слаб. У будућности можемо користити ову алатку за друге сврхе које се не односе на чување дневника. На пример, за енд-то-енд аналитику, у области безбедности, машинско учење.

На крају, мало о предностима и недостацима.

Против

  1. Учитавање записа у великим серијама. С једне стране, ово је карактеристика, али и даље морате да користите додатне компоненте за баферовање записа. Овај задатак није увек једноставан, али ипак решив. И желео бих да поједноставим шему.
  2. Неке егзотичне функционалности или нове функције често се покваре у новим верзијама. Ово изазива забринутост, смањујући жељу за надоградњом на нову верзију. На пример, машина за табелу Кафка је веома корисна функција која вам омогућава да директно читате догађаје из Кафке, без имплементације потрошача. Али, судећи по броју проблема на Гитхубу, и даље смо опрезни да користимо овај мотор у производњи. Међутим, ако не правите нагле покрете у страну и користите основну функционалност, онда ради стабилно.

Прозодија

  1. Не успорава.
  2. Низак улазни праг.
  3. Отвореног кода.
  4. Бесплатно.
  5. Скалабилност (схардинг/оут-оф-тхе-бок репликација)
  6. Укључен у регистар руског софтвера који препоручује Министарство комуникација.
  7. Доступност званичне подршке од Иандек-а.

Извор: ввв.хабр.цом

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