Хүмүүст зориулсан ClickHouse мэдээллийн сан буюу харь гарагийн технологи

Алексей Лизунов, МХБ-ын Мэдээллийн технологийн газрын алсын зайн үйлчилгээний сувгийн чадамжийн төвийн дарга

Хүмүүст зориулсан ClickHouse мэдээллийн сан буюу харь гарагийн технологи

ELK стекийн (ElasticSearch, Logstash, Kibana) өөр хувилбар болгон бид ClickHouse мэдээллийн санг бүртгэлийн мэдээллийн сан болгон ашиглах талаар судалгаа хийж байна.

Энэ нийтлэлд бид ClickHouse мэдээллийн санг ашиглах туршлага болон туршилтын ажиллагааны урьдчилсан үр дүнгийн талаар ярихыг хүсч байна. Үр дүн нь гайхалтай байсан гэдгийг нэн даруй тэмдэглэх нь зүйтэй.


Хүмүүст зориулсан ClickHouse мэдээллийн сан буюу харь гарагийн технологи

Дараа нь бид системээ хэрхэн тохируулсан, ямар бүрэлдэхүүн хэсгүүдээс бүрдэх талаар илүү дэлгэрэнгүй тайлбарлах болно. Гэхдээ одоо би энэ мэдээллийн баазыг бүхэлд нь, яагаад үүнийг анхаарах нь зүйтэй вэ гэдгийг бага зэрэг ярихыг хүсч байна. ClickHouse мэдээллийн сан нь Yandex-ийн өндөр хүчин чадалтай аналитик багана мэдээллийн сан юм. Энэ нь Yandex үйлчилгээнд ашиглагддаг бөгөөд энэ нь эхлээд Yandex.Metrica-ийн үндсэн мэдээллийн сан юм. Нээлттэй эхийн систем, үнэ төлбөргүй. Хөгжүүлэгчийн байр сууринаас харахад гайхалтай том өгөгдөл байдаг тул тэд үүнийг хэрхэн хэрэгжүүлсэн бэ гэж би үргэлж гайхдаг. Мөн Metrica-ийн хэрэглэгчийн интерфэйс нь өөрөө маш уян хатан, хурдан байдаг. Энэхүү мэдээллийн сантай анх танилцахад: “За, эцэст нь! Хүмүүст зориулж бүтээсэн! Суулгах процессоос эхлээд хүсэлт илгээх хүртэл.

Энэ мэдээллийн санд нэвтрэх босго маш бага байна. Дунд зэргийн чадвартай хөгжүүлэгч ч гэсэн хэдхэн минутын дотор энэ мэдээллийн санг суулгаж, ашиглаж эхлэх боломжтой. Бүх зүйл тодорхой ажилладаг. Линуксыг шинээр ашиглаж байгаа хүмүүс ч суулгацыг хурдан шийдэж, хамгийн энгийн үйлдлүүдийг хийж чадна. Хэрэв өмнө нь 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

logstash

Лог цуглуулагч.

FileBeat-аас лог цуглуулах, мөн RabbitMQ дарааллаас (DMZ-д байгаа серверүүдийн хувьд) лог цуглуулахад ашигладаг.

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

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

Logstash-output-clickhouse

Loagstash залгаас нь логуудыг ClickHouse мэдээллийн сан руу багцлан шилжүүлэхэд зориулагдсан

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

/usr/share/logstash/bin/logstash-plugin суулгах logstash-output-clickhouse

/usr/share/logstash/bin/logstash-plugin суулгах logstash-filter-prune

/usr/share/logstash/bin/logstash-plugin суулгах logstash-filter-multiline

clickhouse

Бүртгэлийн хадгалалт https://clickhouse.yandex/docs/ru/

https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-19.5.3.8-1.el7.x86_64.rpm

https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-client-19.5.3.8-1.el7.x86_64.rpm

Анхаарна уу. 2018 оны XNUMX-р сараас эхлэн RHEL-д зориулсан "хэвийн" rpm бүтээцүүд Yandex репозиторт гарч ирсэн тул та тэдгээрийг ашиглахыг оролдож болно. Суулгах үед бид 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

logstash

FileBeat-аас RabbitMQ дараалал руу чиглүүлэгчийг бүртгэх.

Анхаарна уу. Харамсалтай нь FileBeat нь RabbitMQ руу шууд гардаггүй тул Logstash хэлбэрээр завсрын холбоос шаардлагатай.

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

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

Rabbit 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 (RabitMQ-д шаардлагатай)

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: 40 ГБ
RAM: 8GB
Процессор: Core 2 2Ghz

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-tag-г хадгалах тусдаа талбарууд байгааг анхаарна уу (тэдгээрийг асуулгын мөрийн талбараас хүснэгтэд оруулах үе шатанд задлан шинжилдэг).

Мөн систем, бүрэлдэхүүн хэсэг, серверийн талаарх мэдээллийг хадгалах хэд хэдэн системийн талбаруудыг хүснэгтэд нэмсэн. Эдгээр талбаруудын тайлбарыг доорх хүснэгтээс харна уу. Нэг хүснэгтэд бид хэд хэдэн системийн бүртгэлийг хадгалдаг.

Гарчиг

Тайлбар

Жишээ нь:

fld_app_name

Програм/системийн нэр
Хүчинтэй утгууд:

  • site1.domain.com Гадаад сайт 1
  • site2.domain.com Гадаад сайт 2
  • дотоод сайт1.домайн.локал Дотоод сайт 1

site1.domain.com

fld_app_module

Системийн модуль
Хүчинтэй утгууд:

  • вэб - вэб сайт
  • svc - Вэб сайтын үйлчилгээ
  • intgr - Интеграцийн вэб үйлчилгээ
  • bo - Админ (BackOffice)

вэб

fld_вэб сайтын_нэр

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

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

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. Бүртгэлийн хадгалалт

Бүх системийн бүртгэлийг нэг хүснэгтэд хадгалдаг (өгүүллийн эхнээс үзнэ үү). Энэ нь хүсэлтийн талаарх мэдээллийг хадгалахад зориулагдсан: бүх параметрүүд нь IIS бүртгэл, apache, nginx бүртгэл гэх мэт өөр өөр форматтай төстэй. Жишээлбэл, алдаа, мэдээллийн мессеж, сэрэмжлүүлгийг бүртгэсэн програмын бүртгэлийн хувьд зохих бүтэцтэй тусдаа хүснэгтийг өгөх болно (одоогоор зураг төслийн шатанд).

Хүснэгтийг зохион бүтээхдээ үндсэн түлхүүрийг (хадгалах явцад өгөгдлийг эрэмбэлэх) шийдэх нь маш чухал юм. Мэдээллийн шахалтын түвшин, асуулгын хурд нь үүнээс хамаарна. Бидний жишээн дээр гол зүйл бол
ЗАХИАЛАХ (fld_app_name, fld_app_module, logdatetime)
Энэ нь системийн нэр, системийн бүрэлдэхүүн хэсгийн нэр, үйл явдлын огноо юм. Эхэндээ үйл явдлын огноо хамгийн түрүүнд ирдэг. Сүүлчийн газар руу шилжүүлсний дараа асуулга хоёр дахин хурдан ажиллаж эхлэв. Үндсэн түлхүүрийг өөрчлөхийн тулд хүснэгтийг дахин үүсгэж, өгөгдлийг дахин ачаалах шаардлагатай бөгөөд ClickHouse нь дискэн дээрх өгөгдлийг дахин эрэмбэлдэг. Энэ бол хүнд ажиллагаа учраас эрэмбэлэх түлхүүрт юу оруулах ёстойг сайтар бодож үзэх нь зүйтэй.

LowCardinality өгөгдлийн төрөл харьцангуй сүүлийн үеийн хувилбаруудад гарч ирснийг тэмдэглэх нь зүйтэй. Үүнийг ашиглах үед шахагдсан өгөгдлийн хэмжээ бага кардиналтай талбаруудын хувьд эрс багасдаг (цөөн сонголтууд).

19.6 хувилбарыг одоогоор ашиглаж байгаа бөгөөд бид хамгийн сүүлийн хувилбар руу шинэчлэхээр төлөвлөж байна. Тэдгээр нь дасан зохицох нарийн ширийн чанар, алгасах индекс, DoubleDelta кодлогч зэрэг гайхалтай функцуудтай.

Анхдагч байдлаар, суулгацын үед бүртгэлийн түвшинг ул мөр гэж тохируулдаг. Логуудыг эргүүлж, архивлах боловч үүнтэй зэрэгцэн гигабайт хүртэл өргөждөг. Хэрэв шаардлагагүй бол та анхааруулах түвшинг тохируулж болно, дараа нь бүртгэлийн хэмжээ эрс багасна. Бүртгэлийн тохиргоог config.xml файлд тохируулсан:

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

Зарим хэрэгтэй тушаалууд

Поскольку оригинальные пакеты установки собираются по Debian, то для других версий Linux необходимо использовать пакеты собранные компанией Altinity.
 
Вот по этой ссылке есть инструкции с ссылками на их репозиторий: https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse
sudo yum search clickhouse-server
sudo yum install clickhouse-server.noarch
  
1. проверка статуса
sudo systemctl status clickhouse-server
 
2. остановка сервера
sudo systemctl stop clickhouse-server
 
3. запуск сервера
sudo systemctl start clickhouse-server
 
Запуск для выполнения запросов в многострочном режиме (выполнение после знака ";")
clickhouse-client --multiline
clickhouse-client --multiline --host 127.0.0.1 --password pa55w0rd
clickhouse-client --multiline --host 127.0.0.1 --port 9440 --secure --user default --password pa55w0rd
 
Плагин кликлауза для логстеш в случае ошибки в одной строке сохраняет всю пачку в файл /tmp/log_web_failed.json
Можно вручную исправить этот файл и попробовать залить его в БД вручную:
clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /tmp/log_web_failed__fixed.json
 
sudo mv /etc/logstash/tmp/log_web_failed.json /etc/logstash/tmp/log_web_failed__fixed.json
sudo chown user_dev /etc/logstash/tmp/log_web_failed__fixed.json
sudo clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /etc/logstash/tmp/log_web_failed__fixed.json
sudo mv /etc/logstash/tmp/log_web_failed__fixed.json /etc/logstash/tmp/log_web_failed__fixed_.json
 
выход из командной строки
quit;
## Настройка TLS
https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2
 
openssl s_client -connect log.domain.com:9440 < /dev/null

logstash. FileBeat-аас RabbitMQ дараалал руу чиглүүлэгчийг бүртгэх

Энэ бүрэлдэхүүн хэсэг нь FileBeat-аас ирж буй бүртгэлийг RabbitMQ дараалал руу чиглүүлэхэд ашиглагддаг. Энд хоёр цэг байна:

  1. Харамсалтай нь FileBeat-д RabbitMQ руу шууд бичих гаралтын залгаас байхгүй. Тэдний github дээрх асуудлаас харахад ийм функцийг хэрэгжүүлэхээр төлөвлөөгүй байна. Кафкад зориулсан залгаас байгаа ч зарим шалтгааны улмаас бид үүнийг гэртээ ашиглаж чадахгүй байна.
  2. DMZ-д лог цуглуулахад тавигдах шаардлага байдаг. Тэдгээр дээр үндэслэн логуудыг эхлээд дараалалд нэмж оруулах ёстой бөгөөд дараа нь LogStash нь дарааллын оруулгуудыг гаднаас нь уншдаг.

Тиймээс, серверүүд DMZ-д байрладаг тохиолдолд ийм бага зэрэг төвөгтэй схемийг ашиглах шаардлагатай болдог. Жишээ тохиргоо нь иймэрхүү харагдаж байна:

iis_w3c_logs__filebeat_rabbitmq.conf

input {
 
    beats {
        port => 5044
        type => 'iis'
        ssl => true
        ssl_certificate_authorities => ["/etc/pki/tls/certs/app/ca.pem", "/etc/pki/tls/certs/app/ca-issuing.pem"]
        ssl_certificate => "/etc/pki/tls/certs/app/queue.domain.com.cer"
        ssl_key => "/etc/pki/tls/certs/app/queue.domain.com-pkcs8.key"
        ssl_verify_mode => "peer"
    }
 
}
 
output { 
  #stdout {codec => rubydebug}
 
    rabbitmq {
        host => "127.0.0.1"
        port => 5672
        exchange => "monitor.direct"
        exchange_type => "direct"
        key => "%{[fields][fld_app_name]}"
        user => "q-writer"
        password => "password"
        ssl => false
    }
}

RabbitMQ. мессежийн дараалал

Энэ бүрэлдэхүүн хэсэг нь DMZ дахь бүртгэлийн оруулгуудыг буфер болгоход ашиглагддаг. Бичлэгийг Filebeat → LogStash-ийн багцаар хийдэг. Унших нь 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 шүүлтүүрийг боловсруулах үр ашгийг дээшлүүлэхийн тулд бид үүнийг бага зэрэг өөрчлөх шаардлагатай болсон.

Жишээлбэл, бид хувьсагчдыг ашигладаг бөгөөд хэрэв тэдгээрийг шүүлтүүрийн талбарт тохируулаагүй бол бид үүнийг маягтын WHERE хэсэгт нөхцөл үүсгэхгүй байхыг хүсч байна ( uriStem = » AND uriStem != » ). Энэ тохиолдолд ClickHouse нь uriStem баганыг унших болно. Ерөнхийдөө бид янз бүрийн сонголтуудыг туршиж үзсэн бөгөөд эцэст нь залгаасыг ($valueIfEmpty макро) зассан бөгөөд ингэснээр хоосон утгатай тохиолдолд багана өөрөө дурдагдахгүйгээр 1-ийг буцаана.

Одоо та энэ асуулгыг графикт ашиглаж болно

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

Энэ нь энэ SQL руу орчуулагддаг (хоосон uriStem талбарууд ердөө 1 болж хувирсан гэдгийг анхаарна уу)

SELECT
t,
groupArray((response, c)) AS groupArr
FROM (
SELECT
(intDiv(toUInt32(logdatetime), 60) * 60) * 1000 AS t, response,
count(*) AS c FROM default.log_web
WHERE (logdate >= toDate(1565061982)) AND (logdatetime >= toDateTime(1565061982)) AND 1 AND (fld_app_name = 'site1.domain.ru') AND (fld_app_module = 'web') AND 1 AND 1 AND 1
GROUP BY
t, response
ORDER BY
t ASC,
response ASC
)
GROUP BY t ORDER BY t ASC

дүгнэлт

ClickHouse мэдээллийн сангийн дүр төрх нь зах зээлд чухал үйл явдал болсон. Бүрэн үнэ төлбөргүй бид агшин зуур том өгөгдөлтэй ажиллах хүчирхэг, практик хэрэгслээр зэвсэглэсэн гэж төсөөлөхөд хэцүү байсан. Мэдээжийн хэрэг, хэрэгцээ нэмэгдэхийн хэрээр (жишээлбэл, олон серверт хуваах, хуулбарлах) схем нь илүү төвөгтэй болно. Гэхдээ анхны сэтгэгдэл дээр энэ мэдээллийн сантай ажиллах нь маш таатай байдаг. Бүтээгдэхүүнийг "хүмүүст зориулж" хийсэн нь харагдаж байна.

ElasticSearch-тэй харьцуулахад бүртгэлийг хадгалах, боловсруулах зардал таваас арав дахин багасна гэж тооцоолсон. Өөрөөр хэлбэл, хэрэв одоогийн хэмжээний өгөгдлийн хувьд бид хэд хэдэн машинаас бүрдсэн кластер байгуулах шаардлагатай байсан бол ClickHouse ашиглах үед бага чадалтай нэг машин хангалттай. Тийм ээ, мэдээжийн хэрэг, ElasticSearch нь дискэн дээрх өгөгдлийг шахах механизм болон нөөцийн зарцуулалтыг мэдэгдэхүйц бууруулах боломжтой бусад функцуудтай боловч ClickHouse-тай харьцуулахад энэ нь илүү үнэтэй байх болно.

Манай талаас ямар ч тусгай оновчлолгүйгээр анхдагч тохиргоон дээр өгөгдөл ачаалах, мэдээллийн сангаас сонгох нь гайхалтай хурдтай ажилладаг. Бидэнд одоогоор тийм ч их мэдээлэл байхгүй (ойролцоогоор 200 сая бичлэг), гэхдээ сервер өөрөө сул байна. Бид энэ хэрэгслийг цаашид бүртгэл хадгалахтай холбоогүй бусад зорилгоор ашиглах боломжтой. Жишээлбэл, аюулгүй байдлын чиглэлээр, машин сургалтын төгсгөл хүртэлх аналитикийн хувьд.

Төгсгөлд нь давуу болон сул талуудын талаар бага зэрэг хэлье.

Минусы

  1. Бичлэгийг их хэмжээгээр ачаалж байна. Нэг талаас, энэ нь онцлог шинж чанартай боловч та бүртгэлийг буфер болгоход нэмэлт бүрэлдэхүүн хэсгүүдийг ашиглах шаардлагатай хэвээр байна. Энэ даалгавар нь үргэлж хялбар биш боловч шийдвэрлэх боломжтой хэвээр байна. Мөн би схемийг хялбарчлахыг хүсч байна.
  2. Зарим чамин функцууд эсвэл шинэ функцууд ихэвчлэн шинэ хувилбаруудад эвдэрч байдаг. Энэ нь санаа зовоож, шинэ хувилбар руу шинэчлэх хүслийг бууруулдаг. Жишээлбэл, Кафка хүснэгтийн хөдөлгүүр нь хэрэглэгчдийг хэрэгжүүлэхгүйгээр Кафкагаас үйл явдлыг шууд унших боломжийг олгодог маш хэрэгтэй функц юм. Гэхдээ github дээрх асуудлуудын тооноос харахад бид энэ хөдөлгүүрийг үйлдвэрлэлд ашиглахгүй байхыг анхаарсаар байна. Гэсэн хэдий ч, хэрэв та хажуу тийшээ гэнэт дохио зангаа хийхгүй, үндсэн функцийг ашиглавал энэ нь тогтвортой ажилладаг.

Плюсы

  1. Удахгүй.
  2. Нэвтрэх босго бага.
  3. Нээлттэй эх сурвалж.
  4. Үнэгүй.
  5. Сайн масштабтай (хайрцагнаас нь хуваах/хуулбарлах)
  6. Харилцаа холбооны яамнаас санал болгосон Оросын програм хангамжийн бүртгэлд оруулсан болно.
  7. Yandex-ээс албан ёсны дэмжлэг байгаа эсэх.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх