Алексей Лизунов, ръководител на Компетентен център за канали за отдалечено обслужване на дирекция „Информационни технологии“ на МКБ
Като алтернатива на стека ELK (ElasticSearch, Logstash, Kibana), ние правим проучване за използването на базата данни ClickHouse като хранилище на данни за регистрационни файлове.
В тази статия бихме искали да говорим за нашия опит от използването на базата данни ClickHouse и предварителните резултати от пилотната операция. Веднага трябва да се отбележи, че резултатите бяха впечатляващи.
След това ще опишем по-подробно как е конфигурирана нашата система и от какви компоненти се състои. Но сега бих искал да поговоря малко за тази база данни като цяло и защо си струва да й обърнем внимание. Базата данни ClickHouse е високопроизводителна аналитична колонна база данни от Yandex. Използва се в услугите на Yandex, първоначално е основното хранилище за данни за Yandex.Metrica. Система с отворен код, безплатна. От гледна точка на разработчици, винаги съм се чудил как са го внедрили, защото има фантастично големи данни. А самият потребителски интерфейс на Metrica е много гъвкав и бърз. При първото запознаване с тази база данни впечатлението е: „Е, най-накрая! Направено за хората! Започвайки от процеса на инсталиране и завършвайки с изпращане на заявки.
Тази база данни има много нисък праг за влизане. Дори средно квалифициран разработчик може да инсталира тази база данни за няколко минути и да започне да я използва. Всичко работи ясно. Дори хора, които са нови в Linux, могат бързо да се справят с инсталацията и да извършат най-простите операции. Ако по-рано, с думите Big Data, Hadoop, Google BigTable, HDFS, обикновен разработчик имаше идеи, че става въпрос за някакви терабайти, петабайти, че някакви свръхчовеци се занимават с настройки и разработка за тези системи, то с появата на ClickHouse база данни, имаме прост, разбираем инструмент, с който можете да решавате непостижим досега набор от задачи. Отнема само една доста средна машина и пет минути за инсталиране. Тоест имаме такава база данни като например MySql, но само за съхраняване на милиарди записи! Определен суперархиватор с езика SQL. Сякаш на хората бяха връчени оръжията на извънземни.
Относно нашата система за регистриране
За събиране на информация се използват IIS регистрационни файлове на уеб приложения със стандартен формат (в момента също анализираме регистрационни файлове на приложения, но основната цел на пилотния етап е събирането на IIS регистрационни файлове).
Поради различни причини не можахме напълно да изоставим стека ELK и продължаваме да използваме компонентите LogStash и Filebeat, които са се доказали добре и работят доста надеждно и предвидимо.
Общата схема на регистриране е показана на фигурата по-долу:
Характеристика на записване на данни в базата данни ClickHouse е рядко (веднъж в секунда) вмъкване на записи в големи партиди. Това очевидно е най-„проблемната“ част, която срещате, когато за първи път работите с базата данни ClickHouse: схемата става малко по-сложна.
Плъгинът за LogStash, който директно вмъква данни в ClickHouse, помогна много тук. Този компонент е разположен на същия сървър като самата база данни. Така че, общо казано, не е препоръчително да го правите, но от практическа гледна точка, за да не произвеждате отделни сървъри, докато е разположен на същия сървър. Не забелязахме повреди или конфликти на ресурси с базата данни. Освен това трябва да се отбележи, че плъгинът има механизъм за повторен опит в случай на грешки. И в случай на грешки, плъгинът записва на диска пакет от данни, които не могат да бъдат вмъкнати (файловият формат е удобен: след редактиране можете лесно да вмъкнете коригирания пакет с помощта на clickhouse-клиент).
Пълният списък на софтуера, използван в схемата, е представен в таблицата:
Списък на използвания софтуер
Име
описание
Връзка за разпространение
Nginx
Обратно прокси за ограничаване на достъпа по портове и организиране на оторизация
В момента не се използва в схемата
FileBeat
Прехвърляне на файлови дневници.
logstash
Събирач на трупи.
Използва се за събиране на регистрационни файлове от FileBeat, както и за събиране на регистрационни файлове от опашката RabbitMQ (за сървъри, които са в DMZ.)
Logstash-изход-кликхаус
Loagstash плъгин за прехвърляне на регистрационни файлове към базата данни 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
Щракнете върху Къща
Съхранение на регистрационни файлове
Забележка. От август 2018 г. в хранилището на Yandex се появиха „нормални“ rpm компилации за RHEL, така че можете да опитате да ги използвате. По време на инсталацията използвахме пакети, създадени от Altinity.
Графана
Визуализация на дневника. Настройване на табла за управление
Redhat & Centos (64 бита) - най-новата версия
Източник на данни ClickHouse за Grafana 4.6+
Плъгин за Grafana с източник на данни ClickHouse
logstash
Регистрирайте маршрутизатор от FileBeat към RabbitMQ опашка.
Забележка. За съжаление FileBeat не извежда директно към RabbitMQ, така че е необходима междинна връзка под формата на Logstash
RabbitMQ
опашка за съобщения. Това е регистрационният буфер в DMZ
Erlang Runtime (необходим за RabbitMQ)
Време за изпълнение на Erlang. Изисква се, за да работи RabbitMQ
Конфигурацията на сървъра с базата данни ClickHouse е представена в следната таблица:
Име
Стойност
Внимание
Конфигурация
HDD: 40GB
RAM: 8GB
Процесор: Core 2 2 Ghz
Необходимо е да се обърне внимание на съветите за работа с базата данни ClickHouse (
Общ системен софтуер
ОС: Red Hat Enterprise Linux Server (Maipo)
JRE (Java 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-тагове (те се анализират на етапа на вмъкване в таблицата от полето за низ на заявката).
Също така към таблицата са добавени няколко системни полета за съхраняване на информация за системи, компоненти, сървъри. Вижте таблицата по-долу за описание на тези полета. В една таблица съхраняваме логове за няколко системи.
Име
описание
Пример
име_на_приложение
Име на приложение/система
Валидни стойности:
- site1.domain.com Външен сайт 1
- site2.domain.com Външен сайт 2
- internal-site1.domain.local Вътрешен сайт 1
site1.domain.com
fld_app_module
Системен модул
Валидни стойности:
- web - Уеб сайт
- svc - услуга за уеб сайт
- intgr - Интеграционна уеб услуга
- bo - Администратор (BackOffice)
мрежа
fld_име_на_уебсайт
Име на сайта в IIS
Няколко системи могат да бъдат разположени на един сървър или дори няколко екземпляра на един системен модул
уеб основен
име_на_флд_сървър
Име на сървъра
web1.domain.com
fld_log_file_name
Път до лог файла на сървъра
C:inetpublogsLogFiles
W3SVC1u_ex190711.log
Това ви позволява ефективно да изграждате графики в Grafana. Например, прегледайте заявки от интерфейса на определена система. Това е подобно на брояча на сайтове в 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"
clickhouse. Съхранение на регистрационни файлове
Дневниците за всички системи се съхраняват в една таблица (вижте в началото на статията). Предназначен е да съхранява информация за заявки: всички параметри са подобни за различни формати, като например IIS регистрационни файлове, apache и nginx регистрационни файлове. За регистрационните файлове на приложенията, в които например се записват грешки, информационни съобщения, предупреждения, ще бъде предоставена отделна таблица със съответната структура (в момента на етап проектиране).
Когато проектирате таблица, е много важно да вземете решение за първичния ключ (по който данните ще бъдат сортирани по време на съхранение). Степента на компресиране на данните и скоростта на заявките зависят от това. В нашия пример ключът е
ПОРЪЧАЙ ПО (fld_app_name, fld_app_module, logdatetime)
Тоест по името на системата, името на системния компонент и датата на събитието. Първоначално на първо място беше датата на събитието. След като го преместихте на последното място, заявките започнаха да работят около два пъти по-бързо. Промяната на първичния ключ ще изисква повторно създаване на таблицата и презареждане на данните, така че ClickHouse да пресортира данните на диска. Това е тежка операция, така че е добра идея да помислите много какво трябва да бъде включено в ключа за сортиране.
Трябва също да се отбележи, че типът данни LowCardinality се появи относително в последните версии. Когато го използвате, размерът на компресираните данни се намалява драстично за тези полета, които имат ниска кардиналност (малко опции).
В момента се използва версия 19.6 и планираме да опитаме да актуализираме до най-новата версия. Те имат такива прекрасни функции като Adaptive Granularity, Skipping индекси и кодека 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. Тук има две точки:
- За съжаление, FileBeat няма плъгин за изход, който да пише директно в RabbitMQ. И такава функционалност, съдейки по проблема в техния github, не е планирана за внедряване. Има плъгин за Kafka, но по някаква причина не можем да го използваме у дома.
- Има изисквания за събиране на трупи в 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 милиона записа), но самият сървър е слаб. Можем да използваме този инструмент в бъдеще за други цели, които не са свързани със съхраняването на регистрационни файлове. Например за анализи от край до край, в областта на сигурността, машинно обучение.
Накрая малко за плюсовете и минусите.
Против
- Зареждане на записи в големи партиди. От една страна, това е функция, но все пак трябва да използвате допълнителни компоненти за буфериране на записи. Тази задача не винаги е лесна, но все пак разрешима. И бих искал да опростя схемата.
- Някои екзотични функции или нови функции често се повреждат в новите версии. Това предизвиква безпокойство, намалявайки желанието за надграждане до нова версия. Например, Kafka table engine е много полезна функция, която ви позволява директно да четете събития от Kafka, без да внедрявате потребители. Но съдейки по броя на проблемите в github, ние все още внимаваме да не използваме този двигател в производството. Въпреки това, ако не правите внезапни жестове встрани и използвате основната функционалност, тогава тя работи стабилно.
Професионалисти
- Не забавя.
- Нисък праг на влизане.
- Отворен код.
- Безплатно.
- Мащабира добре (шардинг/репликация извън кутията)
- Включен в регистъра на руския софтуер, препоръчан от Министерството на съобщенията.
- Наличието на официална поддръжка от Yandex.
Източник: www.habr.com