Odamlar uchun ClickHouse ma'lumotlar bazasi yoki begona texnologiyalar

Aleksey Lizunov, ICB Axborot texnologiyalari direksiyasining masofaviy xizmat ko'rsatish kanallari bo'yicha vakolat markazi rahbari

Odamlar uchun ClickHouse ma'lumotlar bazasi yoki begona texnologiyalar

ELK stekiga (ElasticSearch, Logstash, Kibana) muqobil sifatida biz ClickHouse ma'lumotlar bazasidan jurnallar uchun ma'lumotlarni saqlash sifatida foydalanish bo'yicha tadqiqot olib bormoqdamiz.

Ushbu maqolada biz ClickHouse ma'lumotlar bazasidan foydalanish tajribamiz va pilot operatsiyaning dastlabki natijalari haqida gaplashmoqchimiz. Natijalar ta'sirchan bo'lganini darhol ta'kidlash kerak.


Odamlar uchun ClickHouse ma'lumotlar bazasi yoki begona texnologiyalar

Keyinchalik tizimimiz qanday tuzilganligi va u qanday komponentlardan iboratligini batafsilroq tasvirlab beramiz. Ammo endi men ushbu ma'lumotlar bazasi haqida bir oz gaplashmoqchiman va nima uchun unga e'tibor berish kerak. ClickHouse ma'lumotlar bazasi Yandex-dan yuqori samarali tahliliy ustunli ma'lumotlar bazasi. Yandex xizmatlarida foydalaniladi, dastlab bu Yandex.Metrica uchun asosiy ma'lumotlarni saqlash joyidir. Ochiq kodli tizim, bepul. Ishlab chiquvchi nuqtai nazaridan men har doim buni qanday amalga oshirganiga hayron bo'lardim, chunki bu erda juda katta ma'lumotlar mavjud. Metrica foydalanuvchi interfeysining o'zi esa juda moslashuvchan va tez ishlaydi. Ushbu ma'lumotlar bazasi bilan birinchi marta tanishganingizda, sizda shunday taassurot paydo bo'ladi: “Xo'sh, nihoyat! "Xalq uchun" yaratilgan! O'rnatish jarayonidan so'rovlarni yuborishgacha."

Ushbu ma'lumotlar bazasi juda past kirish to'sig'iga ega. Hatto oddiy ishlab chiquvchi ham ushbu ma'lumotlar bazasini bir necha daqiqada o'rnatishi va undan foydalanishni boshlashi mumkin. Hammasi muammosiz ishlaydi. Hatto Linuxda yangi bo'lgan odamlar ham o'rnatishni tezda engishlari va oddiy operatsiyalarni bajarishlari mumkin. Agar ilgari Big Data, Hadoop, Google BigTable, HDFS so'zlarini eshitganida, oddiy ishlab chiquvchi ba'zi terabaytlar, petabaytlar haqida gapirayotgani, bu tizimlarni o'rnatish va ishlab chiqishda ba'zi g'ayritabiiy insonlar ishtirok etgan degan fikrga kelgan bo'lsa, keyin paydo bo'lishi bilan ClickHouse ma'lumotlar bazasidan biz oddiy, tushunarli vositaga ega bo'ldik, uning yordamida siz ilgari erishib bo'lmaydigan muammolarni hal qilishingiz mumkin. Buning uchun bitta o'rtacha mashina va o'rnatish uchun besh daqiqa kifoya qiladi. Ya'ni, bizda, masalan, MySql kabi ma'lumotlar bazasi bor, lekin faqat milliardlab yozuvlarni saqlash uchun! SQL tiliga ega superarxivning bir turi. Odamlarga begona qurollar berilganga o'xshaydi.

Jurnallarni yig'ish tizimimiz haqida

Ma'lumot to'plash uchun standart formatdagi veb-ilovalarning IIS jurnali fayllari qo'llaniladi (biz hozirda ilovalar jurnallarini tahlil qilish bilan shug'ullanamiz, ammo tajriba bosqichidagi asosiy maqsadimiz IIS jurnallarini yig'ishdir).

Biz turli sabablarga ko'ra ELK stekidan butunlay voz kecha olmadik va biz o'zini yaxshi isbotlagan va juda ishonchli va bashoratli tarzda ishlaydigan LogStash va Filebeat komponentlaridan foydalanishda davom etmoqdamiz.

Umumiy ro'yxatga olish sxemasi quyidagi rasmda ko'rsatilgan:

Odamlar uchun ClickHouse ma'lumotlar bazasi yoki begona texnologiyalar

ClickHouse ma'lumotlar bazasida ma'lumotlarni yozib olishning o'ziga xos xususiyati yozuvlarni katta partiyalarda kamdan-kam (sekundiga bir marta) kiritishdir. Bu, aftidan, ClickHouse ma'lumotlar bazasi bilan birinchi marta ishlashda duch keladigan eng "muammoli" qismdir: sxema biroz murakkablashadi.
ClickHouse-ga ma'lumotlarni to'g'ridan-to'g'ri kiritadigan LogStash uchun plagin bu erda juda ko'p yordam berdi. Ushbu komponent ma'lumotlar bazasi bilan bir xil serverda joylashtirilgan. Shunday qilib, umuman olganda, buni qilish tavsiya etilmaydi, balki amaliy nuqtai nazardan, xuddi shu serverda o'rnatilganda alohida serverlar yaratmaslik uchun. Biz ma'lumotlar bazasi bilan hech qanday nosozlik yoki manba ziddiyatlarini kuzatmadik. Bunga qo'shimcha ravishda, plaginda xatolar yuzaga kelganda qayta ishlash mexanizmi mavjudligini ta'kidlash kerak. Va xatolar bo'lsa, plagin diskka kiritib bo'lmaydigan ma'lumotlar to'plamini yozadi (fayl formati qulay: tahrirlangandan so'ng siz clickhouse-client yordamida tuzatilgan to'plamni osongina kiritishingiz mumkin).

Sxemada foydalaniladigan dasturlarning to'liq ro'yxati jadvalda keltirilgan:

Amaldagi dasturlar ro'yxati

ism

tavsifi

Tarqatish uchun havola

NGINX

Port orqali kirishni cheklash va avtorizatsiyani tashkil qilish uchun teskari proksi

Hozirda sxemada foydalanilmaydi

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

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

FileBeat

Fayl jurnallarini uzatish.

https://www.elastic.co/downloads/beats/filebeat (Windows 64bit uchun tarqatish).

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

LogStash

Jurnal yig'uvchi.

FileBeat-dan jurnallarni to'plash, shuningdek RabbitMQ navbatdagi jurnallarni yig'ish uchun ishlatiladi (DMZ-da joylashgan serverlar uchun).

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

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

Logstash- chiqish-klikxona

Loglarni ClickHouse ma'lumotlar bazasiga to'plamlarda o'tkazish uchun Loagstash plagini

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

/usr/share/logstash/bin/logstash-plugin logstash-output-clickhouse o'rnatish

/usr/share/logstash/bin/logstash-plugin logstash-filter-prune-ni o'rnatish

/usr/share/logstash/bin/logstash-plugin logstash-filter-multiline-ni o'rnatish

ClickHouse

Jurnal saqlash 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

Eslatma. 2018 yil avgust oyidan boshlab RHEL uchun "normal" aylanish tezligi Yandex omborida paydo bo'ldi, shuning uchun siz ulardan foydalanishga harakat qilishingiz mumkin. O'rnatish vaqtida biz Altinity tomonidan tuzilgan paketlardan foydalanardik.

grafana

Jurnallarning vizualizatsiyasi. Boshqaruv panellarini sozlash

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos (64 Bit) - so'nggi versiya

Grafana 4.6+ uchun ClickHouse ma'lumotlar manbai

ClickHouse ma'lumotlar manbai bilan Grafana uchun plagin

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

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

LogStash

Routerni FileBeat dan RabbitMQ navbatiga yozib oling.

Eslatma. Afsuski, FileBeat to'g'ridan-to'g'ri RabbitMQ-ga chiqmaydi, shuning uchun Logstash ko'rinishidagi oraliq havola talab qilinadi.

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

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

Quyon MQ

Xabar navbati. Bu DMZdagi jurnal yozuvlarining buferidir

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 uchun talab qilinadi)

Erlang ish vaqti. RabbitMQ ishlashi uchun talab qilinadi

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

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

ClickHouse ma'lumotlar bazasi bilan server konfiguratsiyasi quyidagi jadvalda keltirilgan:

ism

ma'no

nota

Konfiguratsiya

HDD: 40 GB
RAM: 8GB
Protsessor: yadro 2 2 gigagertsli

ClickHouse ma'lumotlar bazasidan foydalanish bo'yicha maslahatlarga e'tibor berishingiz kerak (https://clickhouse.yandex/docs/ru/operations/tips/)

Tizimli dasturiy ta'minot

OT: Red Hat Enterprise Linux Server (Maipo)

JRE (Java 8)

 

Ko'rib turganingizdek, bu oddiy ish stantsiyasidir.

Jurnallarni saqlash uchun jadvalning tuzilishi quyidagicha:

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;

Biz bo'limlarga bo'lish (oylik) va indeks granularligi uchun standart qiymatlardan foydalanamiz. Barcha maydonlar amalda http so'rovlarini yozish uchun IIS jurnali yozuvlariga mos keladi. Alohida ta'kidlaymizki, utm teglarini saqlash uchun alohida maydonlar mavjud (ular so'rovlar qatori maydonidan jadvalga kiritish bosqichida tahlil qilinadi).

Shuningdek, tizimlar, komponentlar va serverlar haqidagi ma'lumotlarni saqlash uchun jadvalga bir nechta tizim maydonlari qo'shilgan. Ushbu maydonlarning tavsifi uchun quyidagi jadvalga qarang. Bitta jadvalda biz bir nechta tizimlar uchun jurnallarni saqlaymiz.

ism

tavsifi

misol

fld_app_name

Ilova/tizim nomi
Yaroqli qiymatlar:

  • site1.domain.com Tashqi sayt 1
  • site2.domain.com Tashqi sayt 2
  • ichki-sayt1.domain.local Ichki sayt 1

site1.domain.com

fld_app_module

Tizim moduli
Yaroqli qiymatlar:

  • web - veb-sayt
  • svc — Veb-sayt veb-xizmati
  • intgr — Veb integratsiya xizmati
  • bo — Administrator (BackOffice)

veb-

fld_veb-sayt_nomi

IISda sayt nomi

Bitta serverda bir nechta tizimlar yoki hatto bitta tizim modulining bir nechta nusxalari joylashtirilishi mumkin

veb-asosiy

fld_server_name

Server nomi

web1.domain.com

fld_log_fayl_name

Serverdagi jurnal fayliga yo'l

Kimdan:inetpublogsLogFiles
W3SVC1u_ex190711.log

Bu Grafana-da grafiklarni samarali qurish imkonini beradi. Masalan, ma'lum bir tizimning old qismidan so'rovlarni ko'ring. Bu Yandex.Metrica'dagi sayt hisoblagichiga o'xshaydi.

Ikki oy davomida ma'lumotlar bazasidan foydalanish bo'yicha ba'zi statistik ma'lumotlar.

Tizim va komponentlar bo'yicha yozuvlar soni

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

Diskdagi ma'lumotlar hajmi

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.

Ustun ma'lumotlarini siqish nisbati

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.

Amaldagi komponentlarning tavsifi

FileBeat. Fayl jurnallarini uzatish

Ushbu komponent diskdagi jurnal fayllaridagi o'zgarishlarni kuzatib boradi va ma'lumotlarni LogStash-ga uzatadi. Jurnal fayllari yoziladigan barcha serverlarga o'rnatiladi (odatda IIS). Quyruq rejimida ishlaydi (ya'ni, faylga faqat qo'shilgan yozuvlarni uzatadi). Lekin siz uni butun fayllarni uzatish uchun alohida sozlashingiz mumkin. Bu avvalgi oylar uchun ma'lumotlarni yuklab olishingiz kerak bo'lganda qulay. Jurnal faylini jildga qo'ying va u uni to'liq o'qiydi.

Xizmat to'xtatilgach, ma'lumotlar xotiraga ko'proq uzatilishini to'xtatadi.

Misol konfiguratsiyasi quyidagicha ko'rinadi:

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. Jurnal yig'uvchi

Ushbu komponent FileBeat-dan (yoki RabbitMQ navbati orqali) jurnal yozuvlarini qabul qilish, ularni tahlil qilish va ClickHouse ma'lumotlar bazasiga guruhlarga kiritish uchun mo'ljallangan.

ClickHouse-ga kiritish uchun Logstash-output-clickhouse plaginidan foydalaning. Logstash plaginida so'rovlarni qayta ko'rib chiqish mexanizmi mavjud, ammo muntazam o'chirish vaqtida xizmatni o'zi to'xtatgan ma'qul. To'xtatilganda xabarlar RabbitMQ navbatida to'planadi, shuning uchun agar to'xtash uzoq vaqt davom etsa, serverlarda Filebeats-ni to'xtatgan ma'qul. RabbitMQ ishlatilmaydigan sxemada (Filebeat mahalliy tarmog'ida loglarni to'g'ridan-to'g'ri Logstash-ga yuboradi), Filebeats juda maqbul va xavfsiz ishlaydi, shuning uchun ular uchun chiqishning mavjud emasligi hech qanday oqibatlarga olib kelmaydi.

Misol konfiguratsiyasi quyidagicha ko'rinadi:

log_web__filebeat_clickhouse.conf

input {
 
    beats {
        port => 5044
        type => 'iis'
        ssl => true
        ssl_certificate_authorities => ["/etc/logstash/certs/ca.cer", "/etc/logstash/certs/ca-issuing.cer"]
        ssl_certificate => "/etc/logstash/certs/server.cer"
        ssl_key => "/etc/logstash/certs/server-pkcs8.key"
        ssl_verify_mode => "peer"
 
            add_field => {
                "fld_server_name" => "%{[fields][fld_server_name]}"
                "fld_app_name" => "%{[fields][fld_app_name]}"
                "fld_app_module" => "%{[fields][fld_app_module]}"
                "fld_website_name" => "%{[fields][fld_website_name]}"
                "fld_log_file_name" => "%{source}"
                "fld_logformat" => "%{[fields][fld_logformat]}"
            }
    }
 
    rabbitmq {
        host => "queue.domain.com"
        port => 5671
        user => "q-reader"
        password => "password"
        queue => "web_log"
        heartbeat => 30
        durable => true
        ssl => true
        #ssl_certificate_path => "/etc/logstash/certs/server.p12"
        #ssl_certificate_password => "password"
 
        add_field => {
            "fld_server_name" => "%{[fields][fld_server_name]}"
            "fld_app_name" => "%{[fields][fld_app_name]}"
            "fld_app_module" => "%{[fields][fld_app_module]}"
            "fld_website_name" => "%{[fields][fld_website_name]}"
            "fld_log_file_name" => "%{source}"
            "fld_logformat" => "%{[fields][fld_logformat]}"
        }
    }
 
}
 
filter { 
 
      if [message] =~ "^#" {
        drop {}
      }
 
      if [fld_logformat] == "logformat__iis_with_xrealip" {
     
          grok {
            match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken} %{NOTSPACE:xrealIP} %{NOTSPACE:xforwarderfor}"]
          }
      } else {
   
          grok {
             match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken}"]
          }
 
      }
 
      date {
        match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ]
          timezone => "Etc/UTC"
        remove_field => [ "log_timestamp", "@timestamp" ]
        target => [ "log_timestamp2" ]
      }
 
        ruby {
            code => "tstamp = event.get('log_timestamp2').to_i
                        event.set('logdatetime', Time.at(tstamp).strftime('%Y-%m-%d %H:%M:%S'))
                        event.set('logdate', Time.at(tstamp).strftime('%Y-%m-%d'))"
        }
 
      if [bytesSent] {
        ruby {
          code => "event['kilobytesSent'] = event['bytesSent'].to_i / 1024.0"
        }
      }
 
 
      if [bytesReceived] {
        ruby {
          code => "event['kilobytesReceived'] = event['bytesReceived'].to_i / 1024.0"
        }
      }
 
   
        ruby {
            code => "event.set('clientRealIP', event.get('clientIP'))"
        }
        if [xrealIP] {
            ruby {
                code => "event.set('clientRealIP', event.get('xrealIP'))"
            }
        }
        if [xforwarderfor] {
            ruby {
                code => "event.set('clientRealIP', event.get('xforwarderfor'))"
            }
        }
 
      mutate {
        convert => ["bytesSent", "integer"]
        convert => ["bytesReceived", "integer"]
        convert => ["timetaken", "integer"] 
        convert => ["port", "integer"]
 
        add_field => {
            "clientHostname" => "%{clientIP}"
        }
      }
 
        useragent {
            source=> "useragent"
            prefix=> "browser"
        }
 
        kv {
            source => "uriQuery"
            prefix => "uriQuery__"
            allow_duplicate_values => false
            field_split => "&"
            include_keys => [ "utm_medium", "utm_source", "utm_campaign", "utm_term", "utm_content", "yclid", "region" ]
        }
 
        mutate {
            join => { "uriQuery__utm_source" => "," }
            join => { "uriQuery__utm_medium" => "," }
            join => { "uriQuery__utm_campaign" => "," }
            join => { "uriQuery__utm_term" => "," }
            join => { "uriQuery__utm_content" => "," }
            join => { "uriQuery__yclid" => "," }
            join => { "uriQuery__region" => "," }
        }
 
}
 
output { 
  #stdout {codec => rubydebug}
    clickhouse {
      headers => ["Authorization", "Basic abcdsfks..."]
      http_hosts => ["http://127.0.0.1:8123"]
      save_dir => "/etc/logstash/tmp"
      table => "log_web"
      request_tolerance => 1
      flush_size => 10000
      idle_flush_time => 1
        mutations => {
            "fld_log_file_name" => "fld_log_file_name"
            "fld_server_name" => "fld_server_name"
            "fld_app_name" => "fld_app_name"
            "fld_app_module" => "fld_app_module"
            "fld_website_name" => "fld_website_name"
 
            "logdatetime" => "logdatetime"
            "logdate" => "logdate"
            "serverIP" => "serverIP"
            "method" => "method"
            "uriStem" => "uriStem"
            "uriQuery" => "uriQuery"
            "port" => "port"
            "username" => "username"
            "clientIP" => "clientIP"
            "clientRealIP" => "clientRealIP"
            "userAgent" => "userAgent"
            "referer" => "referer"
            "response" => "response"
            "subresponse" => "subresponse"
            "win32response" => "win32response"
            "timetaken" => "timetaken"
             
            "uriQuery__utm_medium" => "uriQuery__utm_medium"
            "uriQuery__utm_source" => "uriQuery__utm_source"
            "uriQuery__utm_campaign" => "uriQuery__utm_campaign"
            "uriQuery__utm_term" => "uriQuery__utm_term"
            "uriQuery__utm_content" => "uriQuery__utm_content"
            "uriQuery__yclid" => "uriQuery__yclid"
            "uriQuery__region" => "uriQuery__region"
        }
    }
 
}

pipelines.yml

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

ClickHouse. Jurnal saqlash

Barcha tizimlar uchun jurnallar bitta jadvalda saqlanadi (maqolaning boshiga qarang). U so'rovlar haqidagi ma'lumotlarni saqlash uchun mo'ljallangan: barcha parametrlar turli formatlar uchun o'xshashdir, masalan, IIS jurnallari, apache va nginx jurnallari. Masalan, xatolar, ma'lumot xabarlari, ogohlantirishlar qayd etilgan dastur jurnallari uchun tegishli tuzilma bilan (hozirda loyihalash bosqichida) alohida jadval taqdim etiladi.

Jadvalni loyihalashda asosiy kalitni tanlash juda muhim (ma'lumotlar saqlash vaqtida saralanadi). Ma'lumotlarni siqish darajasi va so'rovlar tezligi bunga bog'liq. Bizning misolimizda kalit
BUYURTMA BERISH (fld_app_name, fld_app_module, logdatetime)
Ya'ni, tizim nomi, tizim komponentining nomi va voqea sanasi bilan. Dastlab, tadbirning sanasi birinchi bo'lib kelgan. Uni oxirgi joyga o'tkazgandan so'ng, so'rovlar taxminan ikki baravar tez ishlay boshladi. Asosiy kalitni o'zgartirish jadvalni qayta yaratishni va ma'lumotlarni qayta yuklashni talab qiladi, shunda ClickHouse diskdagi ma'lumotlarni qayta tartiblaydi. Bu qiyin operatsiya, shuning uchun tartiblash kalitiga nima kiritilishi kerakligi haqida oldindan yaxshilab o'ylab ko'rish tavsiya etiladi.

Shuni ham ta'kidlash kerakki, LowCardinality ma'lumotlar turi nisbatan so'nggi versiyalarda paydo bo'lgan. Undan foydalanganda siqilgan ma'lumotlarning o'lchami kardinalligi past bo'lgan maydonlar uchun keskin kamayadi (bir nechta variant).

Biz hozirda 19.6 versiyasidan foydalanmoqdamiz va biz oxirgi versiyaga yangilashni rejalashtirmoqdamiz. Ular, masalan, Adaptive Granularity, Skipping indekslari va DoubleDelta kodek kabi ajoyib xususiyatlarga ega.

Odatiy bo'lib, o'rnatish vaqtida konfiguratsiya jurnali darajasi kuzatuvga o'rnatiladi. Jurnallar aylantiriladi va arxivlanadi, lekin ayni paytda ular gigabaytgacha kengayadi. Agar kerak bo'lmasa, siz ogohlantirish darajasini belgilashingiz mumkin, keyin jurnal hajmi keskin kamayadi. Jurnal sozlamalari config.xml faylida ko'rsatilgan:

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

Ba'zi foydali buyruqlar

Поскольку оригинальные пакеты установки собираются по 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. Routerni FileBeat dan RabbitMQ navbatiga yozib oling

Ushbu komponent FileBeat-dan RabbitMQ navbatiga keladigan jurnallarni yo'naltirish uchun ishlatiladi. Bu erda ikkita nuqta bor:

  1. Afsuski, FileBeat-da RabbitMQ-ga to'g'ridan-to'g'ri yozish uchun chiqish plaginlari yo'q. Va bunday funksionallik, ularning github-dagi postiga ko'ra, amalga oshirish rejalashtirilmagan. Kafka uchun plagin bor, lekin ma'lum sabablarga ko'ra uni o'zimiz ishlata olmaymiz.
  2. DMZda jurnallarni yig'ish uchun talablar mavjud. Ularga asoslanib, jurnallar birinchi navbatda navbatga qo'yilishi kerak va keyin LogStash tashqaridan navbatdagi yozuvlarni o'qiydi.

Shuning uchun, ayniqsa, DMZda joylashgan serverlar uchun bunday biroz murakkab sxemadan foydalanish kerak. Misol konfiguratsiyasi quyidagicha ko'rinadi:

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. Xabar navbati

Ushbu komponent DMZdagi jurnal yozuvlarini buferlash uchun ishlatiladi. Yozish Filebeat → LogStash havolasi orqali amalga oshiriladi. O'qish LogStash orqali DMZ tashqarisidan amalga oshiriladi. RabbitMQ orqali ishlaganda soniyasiga 4 mingga yaqin xabar qayta ishlanadi.

Xabar marshruti tizim nomi bilan, ya'ni FileBeat konfiguratsiya ma'lumotlari asosida tuzilgan. Barcha xabarlar bitta navbatga tushadi. Agar biron sababga ko'ra navbatda turish xizmati to'xtatilgan bo'lsa, bu xabar yo'qolishiga olib kelmaydi: FileBeats ulanish xatolarini oladi va vaqtincha yuborishni to'xtatadi. Va navbatdan o'qiydigan LogStash ham tarmoq xatolarini oladi va ulanishning tiklanishini kutadi. Bunday holda, albatta, ma'lumotlar endi ma'lumotlar bazasiga yozilmaydi.

Navbatlarni yaratish va sozlash uchun quyidagi ko'rsatmalar qo'llaniladi:

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. Boshqaruv panellari

Ushbu komponent monitoring ma'lumotlarini vizualizatsiya qilish uchun ishlatiladi. Bunday holda, Grafana 4.6+ plagini uchun ClickHouse ma'lumotlar manbasini o'rnatishingiz kerak. Biz asboblar panelida SQL filtrlarini qayta ishlash samaradorligini oshirish uchun uni biroz o'zgartirishimiz kerak edi.

Misol uchun, biz o'zgaruvchilardan foydalanamiz va agar ular filtr maydonida ko'rsatilmagan bo'lsa, u holda shaklning WHERE da shart yaratmasligini xohlaymiz ( uriStem = "VA uriStem != "). Bunday holda, ClickHouse uriStem ustunini o'qiydi. Shunday qilib, biz turli xil variantlarni sinab ko'rdik va nihoyat plaginni ($valueIfEmpty makrosi) ustunning o'zini eslatmasdan, bo'sh qiymat bo'lsa, 1 ni qaytarish uchun tuzatdik.

Va endi siz ushbu so'rovni grafik uchun ishlatishingiz mumkin

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

bu kabi SQL ga aylantiriladi (bo'sh uriStem maydonlari faqat 1 ga aylantirilganligini unutmang)

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

xulosa

ClickHouse ma'lumotlar bazasining paydo bo'lishi bozorda muhim voqeaga aylandi. Tasavvur qilish qiyin ediki, biz bir zumda, mutlaqo bepul, biz katta ma'lumotlar bilan ishlash uchun kuchli va amaliy vosita bilan qurollanganmiz. Albatta, ehtiyoj ortib borishi bilan (masalan, sharding va bir nechta serverlarga replikatsiya), sxema yanada murakkablashadi. Ammo birinchi taassurotlarga ko'ra, ushbu ma'lumotlar bazasi bilan ishlash juda yoqimli. Mahsulot "odamlar uchun" ishlab chiqarilganligi aniq.

ElasticSearch bilan solishtirganda, jurnallarni saqlash va qayta ishlash xarajatlari, dastlabki hisob-kitoblarga ko'ra, beshdan o'n baravarga kamayadi. Boshqacha qilib aytganda, agar joriy ma'lumotlar hajmi uchun biz bir nechta mashinalar klasterini o'rnatishimiz kerak bo'lsa, ClickHouse-dan foydalanganda bizga faqat bitta kam quvvatli mashina kerak bo'ladi. Ha, albatta, ElasticSearch ham diskdagi ma'lumotlarni siqish mexanizmlariga va resurslar sarfini sezilarli darajada kamaytiradigan boshqa xususiyatlarga ega, ammo ClickHouse bilan solishtirganda bu ko'proq xarajatlarni talab qiladi.

Bizning tarafimizdan hech qanday maxsus optimallashtirishsiz, standart sozlamalar bilan ma'lumotlarni yuklash va ma'lumotlar bazasidan ma'lumotlarni olish ajoyib tezlikda ishlaydi. Bizda hali ko'p ma'lumotlar yo'q (taxminan 200 million yozuv), lekin serverning o'zi zaif. Biz ushbu vositadan kelajakda jurnallarni saqlash bilan bog'liq bo'lmagan boshqa maqsadlarda foydalanishimiz mumkin. Masalan, xavfsizlik, mashinani o'rganish sohasida end-to-end analitika uchun.

Oxirida, ijobiy va salbiy tomonlari haqida bir oz.

Minusy

  1. Yozuvlarni katta partiyalarda yuklash. Bir tomondan, bu xususiyat, lekin siz hali ham yozuvlarni buferlash uchun qo'shimcha komponentlardan foydalanishingiz kerak. Bu vazifa har doim ham oddiy emas, lekin hali ham hal qilinishi mumkin. Va men sxemani soddalashtirmoqchiman.
  2. Ba'zi ekzotik funksiyalar yoki yangi xususiyatlar ko'pincha yangi versiyalarda buziladi. Bu yangi versiyaga o'tish istagini kamaytiradigan xavotirlarni keltirib chiqaradi. Misol uchun, Kafka jadvali dvigateli iste'molchilarni amalga oshirmasdan, Kafka voqealarini bevosita o'qish imkonini beruvchi juda foydali xususiyatdir. Ammo Github-dagi muammolar soniga qarab, biz hali ham ushbu dvigatelni ishlab chiqarishda ishlatishdan ehtiyot bo'lamiz. Biroq, agar siz yon tomonga keskin harakatlar qilmasangiz va asosiy funksiyadan foydalanmasangiz, u barqaror ishlaydi.

Plyusy

  1. Sekinlashmaydi.
  2. Kirish chegarasi past.
  3. Ochiq manba.
  4. Ozod.
  5. Masshtabli (parchalash/qutidan tashqari replikatsiya)
  6. Aloqa vazirligi tomonidan tavsiya etilgan rus dasturiy ta'minot reestriga kiritilgan.
  7. Yandex-dan rasmiy yordamning mavjudligi.

Manba: www.habr.com

a Izoh qo'shish