Database ClickHouse untuk manusia, atau Teknologi Asing

Alexey Lizunov, kepala pusat kompetensi saluran layanan jarak jauh dari Direktorat Teknologi Informasi ICD



Sebagai alternatif dari tumpukan ELK (ElasticSearch, Logstash, Kibana), kami sedang melakukan penelitian tentang penggunaan database ClickHouse sebagai gudang data untuk log.

Dalam artikel ini, kami ingin berbicara tentang pengalaman kami menggunakan database ClickHouse dan tentang hasil awal dari operasi percontohan. Harus segera dicatat bahwa hasilnya mengesankan.




Selanjutnya, kami akan menjelaskan secara lebih terperinci bagaimana sistem kami dikonfigurasikan dan terdiri dari komponen apa itu. Tetapi sekarang saya ingin berbicara sedikit tentang database ini secara keseluruhan, dan mengapa Anda harus memperhatikannya. Basis data ClickHouse adalah basis data kolom analitik kinerja tinggi dari Yandex. Ini digunakan dalam layanan Yandex, awalnya merupakan gudang data utama untuk Yandex.Metrica. Sistem open-source gratis. Dari sudut pandang pengembang, saya selalu tertarik pada bagaimana mereka mengimplementasikannya, karena ada data yang luar biasa besar. Dan antarmuka pengguna metrik itu sendiri sangat fleksibel dan cepat. Pada kenalan pertama dengan database ini, kesan: β€œYa, akhirnya! Dibuat "untuk orang-orang"! Mulai dari proses instalasi dan diakhiri dengan mengirim permintaan. "

Basis data ini memiliki ambang masuk yang sangat rendah. Bahkan rata-rata pengembang yang terampil dapat menginstal database ini dalam beberapa menit dan mulai menggunakannya. Semuanya bekerja dengan jelas. Bahkan orang yang baru mengenal Linux dapat dengan cepat melewati instalasi dan melakukan operasi sederhana. Sebelumnya, ketika kata Big Data, Hadoop, Google BigTable, HDFS, pengembang biasa memiliki gagasan bahwa mereka berbicara tentang beberapa terabyte, petabyte, bahwa beberapa manusia super terlibat dalam pengaturan dan pengembangan untuk sistem ini, kemudian dengan munculnya database ClickHouse yang kami dapatkan. Alat sederhana dan mudah dipahami untuk menyelesaikan berbagai tugas yang sebelumnya tidak dapat dicapai. Hanya satu mobil yang cukup rata-rata dan lima menit untuk menginstal. Yaitu, kami mendapat basis data seperti, misalnya, MySql, tetapi hanya untuk menyimpan miliaran catatan! Semacam pengawas SQL. Seolah-olah orang diberikan senjata alien.

Tentang sistem pengumpulan log kami


Untuk mengumpulkan informasi, file log IIS dari aplikasi web dengan format standar digunakan (kami juga terlibat dalam penguraian log aplikasi, tetapi tujuan utama pada tahap operasi percontohan bersama kami adalah untuk mengumpulkan log IIS).

Karena berbagai alasan, kami gagal untuk sepenuhnya meninggalkan tumpukan ELK, dan kami terus menggunakan komponen LogStash dan Filebeat, yang telah membuktikan diri dengan baik dan bekerja dengan cukup andal dan dapat diprediksi.

Skema pembalakan umum disajikan pada gambar di bawah ini:



Fitur penulisan data ke database ClickHouse adalah penyisipan catatan yang jarang (sekali per detik) dalam kumpulan besar. Ini, tampaknya, adalah bagian paling "bermasalah" yang Anda temui ketika Anda pertama kali bekerja dengan database ClickHouse: skema ini agak rumit.
Plugin LogStash banyak membantu di sini, yang secara langsung memasukkan data ke dalam ClickHouse. Komponen ini digunakan pada server yang sama dengan database itu sendiri. Jadi, secara umum, tidak disarankan untuk melakukannya, tetapi dari sudut pandang praktis, agar tidak menghasilkan server yang terpisah saat digunakan di server yang sama. Kami tidak melihat adanya kegagalan atau konflik sumber daya dengan database. Selain itu, perlu dicatat bahwa plugin memiliki mekanisme retray jika terjadi kesalahan. Dan jika terjadi kesalahan, plugin menulis ke disk paket data yang tidak dapat dimasukkan (format file nyaman: setelah diedit, Anda dapat dengan mudah memasukkan paket yang diperbaiki menggunakan clickhouse-client).

Daftar lengkap perangkat lunak yang digunakan dalam skema disajikan dalam tabel:

Daftar perangkat lunak yang digunakan
Judul
Deskripsi
Tautan Distribusi

Nginx


Reverse-proxy untuk membatasi akses dan otorisasi port



Saat ini tidak digunakan di sirkuit.


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


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


Filebeat


Transfer log file.


https://www.elastic.co/downloads/beats/filebeat (distribusi untuk Windows 64bit).


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


Logstash


Pengumpul log.



Digunakan untuk mengumpulkan log dari FileBeat, serta untuk mengumpulkan log dari antrian RabbitMQ (untuk server yang ada di DMZ.)


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


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


Logstash- output- clickhouse


Plugin Loagstash untuk mentransfer log ke database ClickHouse dalam batch


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


/ usr / share / logstash / bin / logstash-plugin instal logstash-output-clickhouse


/ usr / share / logstash / bin / logstash-plugin instal logstash-filter-prune


/ usr / share / logstash / bin / logstash-plugin pasang logstash-filter-multiline


Clickhouse


Log repositori 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


Catatan Sejak Agustus 2018, rakitan rpm "normal" untuk RHEL telah muncul di repositori Yandex, sehingga Anda dapat mencoba menggunakannya. Pada saat instalasi, kami menggunakan paket yang dikompilasi oleh Altinity.


Grafana


Visualisasi log. Konfigurasikan Dasbor



https://grafana.com/


https://grafana.com/grafana/download



Redhat & Centos (64 Bit) - Versi Terbaru


Sumber data ClickHouse untuk Grafana 4.6+


Plugin Grafana dengan sumber data ClickHouse


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


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


Logstash


Log router dari FileBeat ke antrian RabbitMQ.


Catatan Sayangnya, FileBeat tidak memiliki output langsung di RabbitMQ, jadi diperlukan tautan lanjutan dalam bentuk Logstash


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


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


Rabbitmq


Antrian pesan Ini adalah buffer entri log di 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 (Diperlukan untuk RabbitMQ)


Erlang runtime. Diperlukan untuk RabbitMQ untuk bekerja


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


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




Konfigurasi server dengan database ClickHouse disajikan dalam tabel berikut:
Judul
Nilai
Catatan

Konfigurasi


HDD: 40GB
RAM: 8GB
Prosesor: Core 2 2Ghz


Penting untuk memperhatikan tips tentang cara mengoperasikan database ClickHouse ( https://clickhouse.yandex/docs/ru/operations/tips/ )


Perangkat lunak seluruh sistem


OS: Server Red Hat Enterprise Linux (Maipo)


JRE (Java 8)




Seperti yang Anda lihat, ini adalah workstation biasa.

Struktur tabel untuk menyimpan log adalah sebagai berikut:

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; 


Kami menggunakan nilai default untuk mempartisi (berdasarkan bulan) dan rincian indeks. Semua bidang praktis sesuai dengan entri log IIS untuk mendaftarkan permintaan http. Secara terpisah, bidang terpisah untuk menyimpan tag utm (mereka diuraikan pada tahap penyisipan ke tabel dari bidang string kueri).

Juga dalam tabel ditambahkan beberapa bidang sistem untuk menyimpan informasi tentang sistem, komponen, server. Lihat tabel di bawah ini untuk deskripsi bidang ini. Dalam satu tabel, kami menyimpan log untuk beberapa sistem.

Judul
Deskripsi
Contoh

fld_app_name


Nama Aplikasi / Sistem
Nilai Valid:


  • site1.domain.com Situs eksternal 1
  • site2.domain.com Situs eksternal 2
  • internal-site1.domain.local Situs internal 1

site1.domain.com

fld_app_module


Modul sistem
Nilai Valid:


  • web - Situs web
  • svc - Layanan situs web
  • intgr - Layanan Integrasi Web
  • bo - Admin (BackOffice)

web


fld_website_name


Nama situs web di IIS


Beberapa sistem dapat digunakan pada satu server, atau bahkan beberapa contoh satu modul sistem


web-main


fld_server_name


Nama server


web1.domain.com


fld_log_file_name


Jalur ke file log di server


C: \ inetpub \ logs \ LogFiles
\ W3SVC1 \ u_ex190711.log

Ini memungkinkan Anda membangun grafik secara efektif di Grafana. Misalnya, melihat permintaan dari frontend sistem tertentu. Ini mirip dengan penghitung situs di Yandex.Metrica.

Berikut adalah beberapa statistik tentang penggunaan basis data selama dua bulan.

Jumlah catatan berdasarkan sistem dan komponen
 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.) 

Jumlah data pada disk
 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. 

Tingkat kompresi data dalam kolom
 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. 


Deskripsi komponen yang digunakan

FileBeat. Transfer File Log


Komponen ini memonitor perubahan dalam file log pada disk dan mentransfer informasi ke LogStash. Itu diinstal pada semua server di mana file log ditulis (biasanya IIS). Ini bekerja dalam mode ekor (mis., Hanya mentransfer catatan yang ditambahkan ke file). Namun secara terpisah, Anda dapat mengonfigurasi seluruh transfer file. Ini berguna ketika Anda perlu mengunduh data dari bulan-bulan sebelumnya. Cukup masukkan file log dalam folder dan dia akan membacanya secara keseluruhan.

Ketika layanan berhenti, data tidak lagi ditransfer ke penyimpanan.

Contoh konfigurasi adalah sebagai berikut:

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 Pengumpul log


Komponen ini dimaksudkan untuk menerima entri log dari FileBeat (atau melalui antrian RabbitMQ), mem-parsing dan menyisipkan bundel ke dalam database ClickHouse.

Untuk memasukkan ke dalam ClickHouse, plugin Logstash-output-clickhouse digunakan. Plugin Logstash memiliki mekanisme untuk mengambil permintaan, tetapi dengan shutdown reguler, lebih baik menghentikan layanan itu sendiri. Ketika Anda berhenti, pesan akan terakumulasi dalam antrian RabbitMQ, jadi jika Anda berhenti untuk waktu yang lama, maka lebih baik menghentikan Filebeats di server. Dalam skema di mana RabbitMQ tidak digunakan (pada jaringan lokal, Filebeat mengirim log langsung ke Logstash), Filebeats bekerja dengan cukup dapat diterima dan aman, sehingga bagi mereka ketidaktercapaian output tidak akan berdampak.

Contoh konfigurasi adalah sebagai berikut:

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. Penyimpanan log


Log untuk semua sistem disimpan dalam satu tabel (lihat bagian awal artikel). Ini dimaksudkan untuk menyimpan informasi tentang permintaan: semua parameter serupa untuk format yang berbeda, misalnya, log IIS, apache, dan log nginx. Untuk log aplikasi yang, misalnya, kesalahan, pesan informasi, peringatan dicatat, tabel terpisah akan disediakan dengan struktur yang sesuai (sekarang pada tahap desain).

Saat mendesain tabel, sangat penting untuk menentukan kunci utama (dimana data akan diurutkan selama penyimpanan). Tingkat kompresi data dan kecepatan kueri bergantung pada ini. Dalam contoh kita, kuncinya adalah
ORDER BY (fld_app_name, fld_app_module, logdatetime)
Yaitu, dengan nama sistem, nama komponen sistem dan tanggal acara. Tanggal asli acara berada di tempat pertama. Setelah memindahkannya ke tempat terakhir, kueri mulai bekerja sekitar dua kali lebih cepat. Mengubah kunci utama akan membutuhkan pembuatan ulang tabel dan memuat ulang data sehingga ClickHouse akan mengurutkan kembali data pada disk. Ini adalah operasi yang sulit, sehingga disarankan untuk memikirkan sebelumnya apa yang harus dimasukkan dalam kunci sortir.

Juga harus dicatat bahwa dalam versi terbaru jenis data LowCardinality telah muncul. Saat menggunakannya, ukuran data terkompresi berkurang tajam untuk bidang-bidang yang memiliki kardinalitas rendah (beberapa opsi).

Sekarang versi 19.6 digunakan, dan kami berencana untuk mencoba memperbarui versi ke yang terbaru. Mereka termasuk fitur luar biasa seperti Adaptive Granularity, Melewati indeks dan codec DoubleDelta, misalnya.

Secara default, selama instalasi, level log konfigurasi diatur untuk dilacak. Log diputar dan diarsipkan, tetapi diperluas hingga satu gigabyte. Jika tidak perlu, maka Anda dapat mengatur tingkat peringatan, maka ukuran log berkurang tajam. Pengaturan pencatatan diatur dalam file config.xml:

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

Beberapa perintah yang bermanfaat
       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 Router log FileBeat ke antrian RabbitMQ


Komponen ini digunakan untuk merutekan log yang berasal dari FileBeat ke antrian RabbitMQ. Ada dua poin:

  1. Sayangnya, FileBeat tidak memiliki plugin output untuk menulis langsung ke RabbitMQ. Dan fungsi seperti itu, dilihat dari ish pada github mereka, tidak direncanakan untuk implementasi. Ada plugin untuk Kafka, tetapi karena alasan tertentu kita tidak bisa menggunakannya di rumah.
  2. Ada persyaratan untuk mengumpulkan log di DMZ. Berdasarkan pada mereka, log pertama-tama harus ditambahkan ke antrian dan kemudian LogStash dari luar membaca entri dari antrian.

Oleh karena itu, justru untuk kasus lokasi server di DMZ bahwa Anda harus menggunakan skema yang sedikit rumit. Contoh konfigurasi adalah sebagai berikut:

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. Antrian pesan


Komponen ini digunakan untuk buffer entri log di DMZ. Perekaman dilakukan melalui sekelompok Filebeat β†’ LogStash. Membaca dilakukan dari luar DMZ melalui LogStash. Saat beroperasi melalui RabboitMQ, sekitar 4 ribu pesan diproses per detik.

Perutean pesan dikonfigurasikan sesuai dengan nama sistem, yaitu berdasarkan data konfigurasi FileBeat. Semua pesan terbagi dalam satu antrian. Jika, karena alasan apa pun, layanan antrian dihentikan, ini tidak akan menyebabkan hilangnya pesan: FileBeats akan menerima kesalahan koneksi dan menunda pengiriman sementara. Dan LogStash, yang dibaca dari antrian, juga akan menerima kesalahan jaringan dan menunggu koneksi untuk melanjutkan. Data, tentu saja, tidak akan lagi ditulis ke dalam basis data.

Instruksi berikut digunakan untuk membuat dan mengonfigurasi antrian:

 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 Dasbor


Komponen ini digunakan untuk memvisualisasikan data pemantauan. Dalam hal ini, Anda harus menginstal sumber data ClickHouse untuk plugin Grafana 4.6+. Kami harus mengubah sedikit untuk meningkatkan efisiensi pemrosesan filter SQL pada dashboard.

Misalnya, kami menggunakan variabel, dan jika tidak disetel di bidang filter, kami ingin agar tidak menghasilkan kondisi dalam formulir WHERE (uriStem = `` AND uriStem! = ''). Dalam hal ini, ClickHouse akan membaca kolom uriStem. Secara umum, kami mencoba berbagai opsi dan akhirnya memperbaiki plugin (macro $ valueIfEmpty) sehingga jika ada nilai kosong, ia akan mengembalikan 1, tanpa menyebutkan kolom itu sendiri.

Dan sekarang Anda dapat menggunakan kueri ini untuk bagan

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

yang dikonversi ke SQL tersebut (perhatikan bahwa bidang uriStem kosong dikonversi menjadi hanya 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 

Kesimpulan


Munculnya database ClickHouse telah menjadi peristiwa penting di pasar. Sulit membayangkan bahwa gratis dalam sekejap, kami dipersenjatai dengan alat yang kuat dan praktis untuk bekerja dengan data besar. Tentu saja, dengan meningkatnya kebutuhan (misalnya, sharding dan replikasi ke beberapa server), skema ini akan menjadi lebih kompleks. Tetapi pada kesan pertama, bekerja dengan database ini sangat bagus. Dapat dilihat bahwa produk tersebut dibuat "untuk manusia."

Dibandingkan dengan ElasticSearch, biaya penyimpanan dan pemrosesan log, menurut perkiraan awal, dikurangi dari lima menjadi sepuluh kali lipat. Dengan kata lain, jika untuk jumlah data saat ini kita harus mengkonfigurasi sekelompok beberapa mesin, maka ketika menggunakan ClickHouse kita hanya perlu satu mesin berdaya rendah. Ya, tentu saja, ElasticSearch juga memiliki mekanisme untuk mengompresi data pada disk dan fitur lain yang dapat secara signifikan mengurangi konsumsi sumber daya, tetapi dibandingkan dengan ClickHouse, ini akan mahal.

Tanpa optimasi khusus untuk bagiannya, pada pengaturan default, memuat data dan mengambil data dari database bekerja dengan kecepatan luar biasa. Sejauh ini kami memiliki sedikit data (sekitar 200 juta catatan), tetapi server itu sendiri lemah. Di masa mendatang, kita dapat menggunakan alat ini untuk tujuan lain yang tidak terkait dengan penyimpanan log. Misalnya, untuk analitik ujung ke ujung, di bidang keamanan, pembelajaran mesin.

Pada akhirnya, sedikit tentang pro dan kontra.

Cons


  1. Mengunduh catatan dalam bundel besar. Ini, di satu sisi, adalah fitur, tetapi Anda masih harus menggunakan komponen tambahan untuk merekam buffer. Tugas ini tidak selalu sederhana, tetapi masih bisa dipecahkan. Dan saya ingin menyederhanakan skema.
  2. Beberapa fungsionalitas eksotis atau fitur baru sering rusak dalam versi baru. Ini menimbulkan kekhawatiran, mengurangi keinginan untuk meningkatkan ke versi baru. Misalnya, mesin tabel Kafka adalah fitur yang sangat berguna yang memungkinkan Anda untuk langsung membaca acara dari Kafka, tanpa penerapan konsumen. Namun dilihat dari banyaknya Isu pada github, kami masih khawatir menggunakan mesin ini dalam produksi. Namun, jika Anda tidak membuat gerakan tajam ke samping dan menggunakan fungsionalitas dasar, maka itu berfungsi secara stabil.

Pro


  1. Itu tidak melambat.
  2. Ambang entri rendah.
  3. Sumber terbuka
  4. Ini gratis.
  5. Timbangan dengan baik (sharding / replikasi out-of-box)
  6. Ini termasuk dalam daftar perangkat lunak Rusia yang direkomendasikan oleh Kementerian Komunikasi.
  7. Kehadiran dukungan resmi dari Yandex.

Source: https://habr.com/ru/post/id472912/


All Articles