Адамдарға арналған ClickHouse дерекқоры немесе шетелдік технологиялар

Алексей Лизунов, МКБ Ақпараттық технологиялар дирекциясының қашықтан қызмет көрсету арналарының құзыретті орталығының басшысы

Адамдарға арналған ClickHouse дерекқоры немесе шетелдік технологиялар

ELK стекіне (ElasticSearch, Logstash, Kibana) балама ретінде біз ClickHouse дерекқорын журналдарға арналған деректер қоймасы ретінде пайдалану бойынша зерттеу жүргіземіз.

Бұл мақалада біз ClickHouse дерекқорын пайдалану тәжірибеміз және пилоттық операцияның алдын ала нәтижелері туралы айтқымыз келеді. Нәтижелердің әсерлі болғанын бірден айта кету керек.


Адамдарға арналған ClickHouse дерекқоры немесе шетелдік технологиялар

Әрі қарай, біз жүйеміздің қалай конфигурацияланғанын және оның қандай компоненттерден тұратынын толығырақ сипаттайтын боламыз. Бірақ қазір мен жалпы осы дерекқор туралы және неге оған назар аудару керектігі туралы аздап айтқым келеді. ClickHouse дерекқоры Яндекстің жоғары өнімді аналитикалық бағаналы дерекқоры болып табылады. Ол Яндекс қызметтерінде қолданылады, бастапқыда бұл Yandex.Metrica үшін негізгі деректер қоймасы. Ашық бастапқы жүйе, тегін. Әзірлеушінің көзқарасы бойынша, мен әрқашан олардың оны қалай жүзеге асырғаны туралы қызықтыратынмын, өйткені фантастикалық үлкен деректер бар. Ал Metrica пайдаланушы интерфейсінің өзі өте икемді және жылдам. Бұл дерекқормен алғаш танысқанда мынадай әсер пайда болады: «Соңында! Халық үшін жасалған! Орнату процесінен бастап сұрауларды жіберумен аяқталады.

Бұл дерекқордың кіру шегі өте төмен. Тіпті орташа білікті әзірлеуші ​​бұл дерекқорды бірнеше минут ішінде орнатып, оны пайдалана бастайды. Барлығы анық жұмыс істейді. Тіпті Linux жүйесін жаңадан бастаған адамдар да орнатуды жылдам орындап, ең қарапайым әрекеттерді орындай алады. Егер бұрын Big Data, Hadoop, Google BigTable, HDFS сөздерімен қарапайым әзірлеуші ​​​​бұл кейбір терабайттар, петабайттар туралы, кейбір суперадамдар осы жүйелерді баптаумен және әзірлеумен айналысады деген идеяларға ие болса, ClickHouse пайда болуымен дерекқорда біз қарапайым, түсінікті құрал алдық, оның көмегімен сіз бұрын қол жетпеген тапсырмалар ауқымын шеше аласыз. Орнату үшін бір ғана орташа машина және бес минут қажет. Яғни, бізде, мысалы, MySql сияқты деректер базасы бар, бірақ тек миллиардтаған жазбаларды сақтауға арналған! SQL тілі бар белгілі бір супер архиватор. Адамдарға жат планеталықтардың қаруын бергендей.

Біздің журнал жүргізу жүйеміз туралы

Ақпаратты жинау үшін стандартты пішімдегі веб-қосымшалардың IIS журнал файлдары пайдаланылады (біз қазір қолданба журналдарын талдап жатырмыз, бірақ пилоттық кезеңдегі басты мақсат IIS журналдарын жинау).

Түрлі себептерге байланысты біз ELK стекінен толығымен бас тарта алмадық және біз өздерін жақсы дәлелдеген және сенімді және болжамды түрде жұмыс істейтін LogStash және Filebeat компоненттерін пайдалануды жалғастырамыз.

Каротаждың жалпы схемасы төмендегі суретте көрсетілген:

Адамдарға арналған ClickHouse дерекқоры немесе шетелдік технологиялар

ClickHouse дерекқорына деректерді жазу мүмкіндігі - жазбаларды үлкен пакеттерге сирек (секундына бір рет) енгізу. Бұл ClickHouse дерекқорымен бірінші рет жұмыс істеген кезде кездесетін ең «проблемалық» бөлік: схема біршама күрделене түседі.
Деректерді ClickHouse ішіне тікелей кірістіретін LogStash плагині мұнда көп көмектесті. Бұл құрамдас дерекқордың өзі сияқты бір серверде орналастырылған. Сонымен, жалпы айтқанда, оны бір серверде орналастыру кезінде бөлек серверлерді шығармау үшін практикалық тұрғыдан жасау ұсынылмайды. Біз дерекқормен ешқандай ақаулықтарды немесе ресурс қайшылықтарын байқамадық. Сонымен қатар, плагинде қателер болған жағдайда қайталау механизмі бар екенін атап өткен жөн. Қателер болған жағдайда плагин дискіге кірістіру мүмкін емес деректер пакетін жазады (файл пішімі ыңғайлы: өңдеуден кейін 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 64 бит үшін тарату жинағы).

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

журнал қоймасы

Журнал жинағыш.

FileBeat жүйесінен журналдарды жинау үшін, сондай-ақ RabbitMQ кезегінен журналдарды жинау үшін қолданылады (DMZ ішіндегі серверлер үшін).

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

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

Logstash-output-clickhouse

Журналдарды ClickHouse дерекқорына пакеттермен тасымалдауға арналған Loagstash плагині

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 жылдың тамызынан бастап Яндекс репозиторийінде RHEL үшін «қалыпты» айналымдар пайда болды, сондықтан оларды пайдаланып көруге болады. Орнату кезінде біз Altinity құрастырған пакеттерді пайдаландық.

Графана

Журналды визуализациялау. Бақылау тақталарын орнату

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos(64 бит) - соңғы нұсқасы

Grafana 4.6+ үшін ClickHouse деректер көзі

ClickHouse деректер көзі бар Grafana плагині

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

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

журнал қоймасы

Маршрутизаторды 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 үшін қажет)

Erlang орындау уақыты. 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: 40GB
ЖЖҚ: 8GB
Процессор: Core 2 2 ГГц

ClickHouse дерекқорын пайдалану бойынша кеңестерге назар аудару керек (https://clickhouse.yandex/docs/ru/operations/tips/)

Жалпы жүйелік бағдарламалық қамтамасыз ету

ОЖ: 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;

Біз әдепкі бөлуді (ай бойынша) және индекстің түйіршіктілігін қолданамыз. Барлық өрістер іс жүзінде http сұрауларын тіркеуге арналған IIS журнал жазбаларына сәйкес келеді. Бөлек, біз utm-тегтерін сақтауға арналған бөлек өрістер бар екенін атап өтеміз (олар сұраныс жолының өрісінен кестеге кірістіру сатысында талданады).

Сондай-ақ, жүйелер, компоненттер, серверлер туралы ақпаратты сақтау үшін кестеге бірнеше жүйелік өрістер қосылды. Осы өрістердің сипаттамасы үшін төмендегі кестені қараңыз. Бір кестеде біз бірнеше жүйеге арналған журналдарды сақтаймыз.

сипаттамасы

Мысал:

fld_app_name

Қолданба/жүйе атауы
Жарамды мәндер:

  • 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_website_name

IIS жүйесіндегі сайт атауы

Бір серверде бірнеше жүйені немесе тіпті бір жүйелік модульдің бірнеше данасын орналастыруға болады

негізгі веб

fld_server_name

Сервер атауы

web1.domain.com

fld_log_файл_аты

Сервердегі журнал файлына жол

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

журнал қоймасы. Журнал жинағыш

Бұл құрамдас 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"
        }
    }
 
}

pipelines.yml

# This file is where you define your pipelines. You can define multiple.
# For more information on multiple pipelines, see the documentation:
#   https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html
 
- pipeline.id: log_web__filebeat_clickhouse
  path.config: "/etc/logstash/log_web__filebeat_clickhouse.conf"

кликхаус. Журналды сақтау

Барлық жүйелерге арналған журналдар бір кестеде сақталады (мақаланың басын қараңыз). Ол сұраулар туралы ақпаратты сақтауға арналған: барлық параметрлер 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

журнал қоймасы. Маршрутизаторды 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 жиынтығы арқылы жүзеге асырылады. Оқу LogStash арқылы DMZ сыртынан орындалады. 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"

Графана. Бақылау тақталары

Бұл компонент мониторинг деректерін визуализациялау үшін пайдаланылады. Бұл жағдайда Grafana 4.6+ плагиніне арналған ClickHouse деректер көзін орнату қажет. Бақылау тақтасындағы SQL сүзгілерін өңдеу тиімділігін арттыру үшін бізге оны сәл өзгертуге тура келді.

Мысалы, біз айнымалы мәндерді қолданамыз және олар сүзгі өрісінде орнатылмаған болса, онда пішіннің ҚАЙДА ( 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 миллион жазба), бірақ сервердің өзі әлсіз. Біз бұл құралды болашақта журналдарды сақтауға қатысы жоқ басқа мақсаттарда пайдалана аламыз. Мысалы, қауіпсіздік саласында, машиналық оқытуда end-to-end аналитика үшін.

Соңында, жақсы және жаман жақтары туралы аздап.

Минусы

  1. Жазбаларды үлкен партиялармен жүктеу. Бір жағынан, бұл мүмкіндік, бірақ жазбаларды буферлеу үшін әлі де қосымша құрамдастарды пайдалану керек. Бұл тапсырма әрқашан оңай емес, бірақ әлі де шешіледі. Ал мен схеманы жеңілдеткім келеді.
  2. Кейбір экзотикалық функциялар немесе жаңа мүмкіндіктер жиі жаңа нұсқаларда бұзылады. Бұл жаңа нұсқаға жаңартуға деген ұмтылысты азайтып, алаңдаушылық тудырады. Мысалы, Кафка кестесінің қозғалтқышы тұтынушыларды іске асырмай, Кафкадан оқиғаларды тікелей оқуға мүмкіндік беретін өте пайдалы мүмкіндік болып табылады. Бірақ github-тағы мәселелердің санына қарай, біз әлі де бұл қозғалтқышты өндірісте пайдаланбауға тырысамыз. Дегенмен, егер сіз кенеттен бүйірге қимыл жасамасаңыз және негізгі функционалдылықты пайдалансаңыз, онда ол тұрақты жұмыс істейді.

Плюсы

  1. Баяулатпайды.
  2. Төмен кіру шегі.
  3. Ашық дереккөз.
  4. Тегін.
  5. Жақсы масштабтау (қораптан бөлшектеу/көшіру)
  6. Байланыс министрлігі ұсынған ресейлік бағдарламалық қамтамасыз ету реестріне енгізілген.
  7. Яндекстің ресми қолдауының болуы.

Ақпарат көзі: www.habr.com

пікір қалдыру