Pangkalan Data ClickHouse untuk Manusia, atau Teknologi Alien

Aleksey Lizunov, Ketua Pusat Kompetensi untuk Saluran Perkhidmatan Jauh Direktorat Teknologi Maklumat MKB

Pangkalan Data ClickHouse untuk Manusia, atau Teknologi Alien

Sebagai alternatif kepada timbunan ELK (ElasticSearch, Logstash, Kibana), kami sedang melakukan penyelidikan tentang menggunakan pangkalan data ClickHouse sebagai stor data untuk log.

Dalam artikel ini, kami ingin bercakap tentang pengalaman kami menggunakan pangkalan data ClickHouse dan keputusan awal operasi perintis. Perlu diperhatikan dengan segera bahawa hasilnya sangat mengagumkan.


Pangkalan Data ClickHouse untuk Manusia, atau Teknologi Alien

Seterusnya, kami akan menerangkan dengan lebih terperinci bagaimana sistem kami dikonfigurasikan, dan komponen yang terdiri daripadanya. Tetapi sekarang saya ingin bercakap sedikit tentang pangkalan data ini secara keseluruhan, dan mengapa ia patut diberi perhatian. Pangkalan data ClickHouse ialah pangkalan data kolumnar analitik berprestasi tinggi daripada Yandex. Ia digunakan dalam perkhidmatan Yandex, pada mulanya ia adalah storan data utama untuk Yandex.Metrica. Sistem sumber terbuka, percuma. Dari sudut pandangan pembangun, saya sentiasa tertanya-tanya bagaimana mereka melaksanakannya, kerana terdapat data yang sangat besar. Dan antara muka pengguna Metrica sendiri adalah sangat fleksibel dan pantas. Pada kenalan pertama dengan pangkalan data ini, tanggapannya ialah: “Nah, akhirnya! Dibuat untuk rakyat! Bermula dari proses pemasangan dan berakhir dengan menghantar permintaan.

Pangkalan data ini mempunyai ambang kemasukan yang sangat rendah. Malah pembangun berkemahiran sederhana boleh memasang pangkalan data ini dalam beberapa minit dan mula menggunakannya. Semuanya berfungsi dengan jelas. Malah orang yang baru menggunakan Linux boleh mengendalikan pemasangan dengan cepat dan melakukan operasi yang paling mudah. Jika sebelum ini, dengan perkataan Big Data, Hadoop, Google BigTable, HDFS, seorang pembangun biasa mempunyai idea bahawa ia adalah mengenai beberapa terabait, petabait, bahawa beberapa manusia super terlibat dalam tetapan dan pembangunan untuk sistem ini, maka dengan kemunculan ClickHouse pangkalan data, kami mendapat alat yang ringkas dan mudah difahami yang mana anda boleh menyelesaikan pelbagai tugas yang sebelum ini tidak dapat dicapai. Ia hanya memerlukan satu mesin yang agak sederhana dan lima minit untuk dipasang. Iaitu, kami mendapat pangkalan data seperti, sebagai contoh, MySql, tetapi hanya untuk menyimpan berbilion rekod! Pengarkib super tertentu dengan bahasa SQL. Ia seperti orang telah diserahkan senjata makhluk asing.

Mengenai sistem pembalakan kami

Untuk mengumpul maklumat, fail log IIS bagi aplikasi web format standard digunakan (kami juga sedang menghuraikan log aplikasi, tetapi matlamat utama pada peringkat perintis adalah untuk mengumpul log IIS).

Atas pelbagai sebab, kami tidak dapat meninggalkan timbunan ELK sepenuhnya, dan kami terus menggunakan komponen LogStash dan Filebeat, yang telah membuktikan diri mereka dengan baik dan berfungsi dengan pasti dan boleh diramalkan.

Skim pembalakan umum ditunjukkan dalam rajah di bawah:

Pangkalan Data ClickHouse untuk Manusia, atau Teknologi Alien

Ciri menulis data ke pangkalan data ClickHouse adalah jarang (sekali sesaat) memasukkan rekod dalam kelompok besar. Ini, nampaknya, adalah bahagian paling "bermasalah" yang anda hadapi apabila anda mula-mula bekerja dengan pangkalan data ClickHouse: skim ini menjadi sedikit lebih rumit.
Pemalam untuk LogStash, yang memasukkan data terus ke ClickHouse, banyak membantu di sini. Komponen ini digunakan pada pelayan yang sama dengan pangkalan data itu sendiri. Jadi, secara amnya, tidak disyorkan untuk melakukannya, tetapi dari sudut pandangan praktikal, supaya tidak menghasilkan pelayan berasingan semasa ia digunakan pada pelayan yang sama. Kami tidak melihat sebarang kegagalan atau konflik sumber dengan pangkalan data. Di samping itu, perlu diperhatikan bahawa pemalam mempunyai mekanisme cuba semula sekiranya berlaku ralat. Dan sekiranya berlaku ralat, pemalam menulis ke cakera sekumpulan data yang tidak boleh dimasukkan (format fail adalah mudah: selepas mengedit, anda boleh dengan mudah memasukkan kumpulan yang diperbetulkan menggunakan clickhouse-client).

Senarai lengkap perisian yang digunakan dalam skema dibentangkan dalam jadual:

Senarai perisian yang digunakan

nama

Описание

Pautan pengedaran

Nginx

Proksi terbalik untuk menyekat akses oleh port dan mengatur kebenaran

Pada masa ini tidak digunakan dalam skim ini

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

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

FileBeat

Pemindahan log fail.

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

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

simpanan log

Pengumpul balak.

Digunakan untuk mengumpul log daripada FileBeat, serta mengumpul log daripada baris gilir RabbitMQ (untuk pelayan yang berada dalam DMZ.)

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

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

Logstash-output-clickhouse

Pemalam Loagstash untuk memindahkan log ke pangkalan data ClickHouse secara berkelompok

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

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

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

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

Klik Rumah

Storan log 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. Bermula dari Ogos 2018, binaan rpm "biasa" untuk RHEL muncul dalam repositori Yandex, jadi anda boleh cuba menggunakannya. Pada masa pemasangan, kami menggunakan pakej yang dibina oleh Altinity.

grafana

Visualisasi log. Menyediakan papan pemuka

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos(64 Bit) - versi terkini

Sumber data ClickHouse untuk Grafana 4.6+

Pemalam untuk 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

simpanan log

Log penghala dari FileBeat ke baris gilir RabbitMQ.

Catatan. Malangnya FileBeat tidak mengeluarkan terus ke RabbitMQ, jadi pautan perantaraan dalam bentuk Logstash diperlukan

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

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

RabbitMQ

baris gilir mesej. Ini ialah penimbal log dalam 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)

Masa jalan Erlang. Diperlukan untuk RabbitMQ berfungsi

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

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

Konfigurasi pelayan dengan pangkalan data ClickHouse dibentangkan dalam jadual berikut:

nama

Nilai

Nota

Konfigurasi

HDD: 40GB
RAM: 8GB
Pemproses: Teras 2 2Ghz

Adalah perlu untuk memberi perhatian kepada petua untuk mengendalikan pangkalan data ClickHouse (https://clickhouse.yandex/docs/ru/operations/tips/)

Perisian sistem am

OS: Pelayan Linux Red Hat Enterprise (Maipo)

JRE (Jawa 8)

 

Seperti yang anda lihat, ini adalah stesen kerja biasa.

Struktur jadual untuk menyimpan log adalah seperti 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 pembahagian lalai (mengikut bulan) dan butiran indeks. Semua medan praktikal sepadan dengan entri log IIS untuk log permintaan http. Secara berasingan, kami ambil perhatian bahawa terdapat medan berasingan untuk menyimpan utm-tags (ia dihuraikan pada peringkat memasukkan ke dalam jadual dari medan rentetan pertanyaan).

Juga, beberapa medan sistem telah ditambahkan pada jadual untuk menyimpan maklumat tentang sistem, komponen, pelayan. Lihat jadual di bawah untuk penerangan tentang medan ini. Dalam satu jadual, kami menyimpan log untuk beberapa sistem.

nama

Описание

Contoh

fld_app_name

Nama aplikasi/sistem
Nilai yang sah:

  • site1.domain.com Tapak luaran 1
  • site2.domain.com Tapak luaran 2
  • internal-site1.domain.local Tapak dalaman 1

site1.domain.com

fld_app_module

Modul sistem
Nilai yang sah:

  • web - Laman web
  • svc - Perkhidmatan laman web
  • intgr - Perkhidmatan Web Integrasi
  • bo - Pentadbir (BackOffice)

web

fld_website_name

Nama tapak dalam IIS

Beberapa sistem boleh digunakan pada satu pelayan, atau bahkan beberapa contoh satu modul sistem

utama web

fld_server_name

Nama pelayan

web1.domain.com

nama_fail_log_fld

Laluan ke fail log pada pelayan

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

Ini membolehkan anda membina graf dalam Grafana dengan cekap. Sebagai contoh, lihat permintaan dari bahagian hadapan sistem tertentu. Ini serupa dengan kaunter tapak dalam Yandex.Metrica.

Berikut adalah beberapa statistik mengenai penggunaan pangkalan data selama dua bulan.

Bilangan rekod yang dipecahkan mengikut sistem dan komponennya

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 cakera

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.

Darjah pemampatan data dalam lajur

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.

Penerangan komponen yang digunakan

FileBeat. Memindahkan log fail

Komponen ini menjejaki perubahan pada fail log pada cakera dan menghantar maklumat kepada LogStash. Dipasang pada semua pelayan di mana fail log ditulis (biasanya IIS). Berfungsi dalam mod ekor (iaitu memindahkan hanya rekod yang ditambahkan ke fail). Tetapi secara berasingan ia boleh dikonfigurasikan untuk memindahkan keseluruhan fail. Ini berguna apabila anda perlu memuat turun data dari bulan sebelumnya. Hanya letakkan fail log dalam folder dan ia akan membacanya secara keseluruhan.

Apabila perkhidmatan dihentikan, data tidak lagi dipindahkan ke storan.

Contoh konfigurasi kelihatan seperti ini:

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

simpanan log. Pengumpul Log

Komponen ini direka bentuk untuk menerima entri log daripada FileBeat (atau melalui baris gilir RabbitMQ), menghuraikan dan memasukkan kelompok ke dalam pangkalan data ClickHouse.

Untuk memasukkan ke dalam ClickHouse, pemalam Logstash-output-clickhouse digunakan. Pemalam Logstash mempunyai mekanisme cuba semula permintaan, tetapi dengan penutupan biasa, adalah lebih baik untuk menghentikan perkhidmatan itu sendiri. Apabila dihentikan, mesej akan terkumpul dalam baris gilir RabbitMQ, jadi jika berhenti untuk masa yang lama, maka adalah lebih baik untuk menghentikan Filebeats pada pelayan. Dalam skema di mana RabbitMQ tidak digunakan (pada rangkaian tempatan, Filebeat menghantar log terus ke Logstash), Filebeats berfungsi dengan agak boleh diterima dan selamat, jadi bagi mereka ketidaktersediaan keluaran berlalu tanpa akibat.

Contoh konfigurasi kelihatan seperti ini:

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

talian paip.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. Storan log

Log untuk semua sistem disimpan dalam satu jadual (lihat pada permulaan artikel). Ia bertujuan untuk menyimpan maklumat tentang permintaan: semua parameter adalah serupa untuk format yang berbeza, seperti log IIS, apache dan log nginx. Untuk log aplikasi, di mana, sebagai contoh, ralat, mesej maklumat, amaran direkodkan, jadual berasingan akan disediakan dengan struktur yang sesuai (pada masa ini di peringkat reka bentuk).

Apabila mereka bentuk jadual, adalah sangat penting untuk memutuskan kunci utama (yang mana data akan diisih semasa penyimpanan). Tahap pemampatan data dan kelajuan pertanyaan bergantung pada ini. Dalam contoh kami, kuncinya ialah
PESANAN OLEH (fld_app_name, fld_app_module, logdatetime)
Iaitu, dengan nama sistem, nama komponen sistem dan tarikh acara. Pada mulanya, tarikh acara didahulukan. Selepas mengalihkannya ke tempat terakhir, pertanyaan mula berfungsi kira-kira dua kali lebih pantas. Menukar kunci utama memerlukan mencipta semula jadual dan memuat semula data supaya ClickHouse menyusun semula data pada cakera. Ini adalah operasi yang berat, jadi adalah idea yang baik untuk memikirkan banyak perkara tentang perkara yang perlu disertakan dalam kekunci isihan.

Ia juga harus diperhatikan bahawa jenis data LowCardinality telah muncul dalam versi yang agak terkini. Apabila menggunakannya, saiz data yang dimampatkan dikurangkan secara drastik untuk medan yang mempunyai kardinaliti rendah (beberapa pilihan).

Versi 19.6 sedang digunakan dan kami merancang untuk mencuba mengemas kini kepada versi terkini. Mereka mempunyai ciri yang menarik seperti Adaptive Granularity, Skipping indeks dan codec DoubleDelta, sebagai contoh.

Secara lalai, semasa pemasangan, tahap pengelogan ditetapkan untuk dikesan. Log diputar dan diarkibkan, tetapi pada masa yang sama ia berkembang sehingga gigabait. Jika tidak ada keperluan, maka anda boleh menetapkan tahap amaran, maka saiz log dikurangkan secara drastik. Tetapan pengelogan ditetapkan dalam fail config.xml:

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

Beberapa arahan yang berguna

Поскольку оригинальные пакеты установки собираются по 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

simpanan log. Log penghala dari FileBeat ke baris gilir RabbitMQ

Komponen ini digunakan untuk menghalakan log yang datang dari FileBeat ke baris gilir RabbitMQ. Terdapat dua perkara di sini:

  1. Malangnya, FileBeat tidak mempunyai pemalam output untuk menulis terus ke RabbitMQ. Dan fungsi sedemikian, berdasarkan isu pada github mereka, tidak dirancang untuk dilaksanakan. Terdapat pemalam untuk Kafka, tetapi atas sebab tertentu kami tidak boleh menggunakannya di rumah.
  2. Terdapat keperluan untuk mengumpul log dalam DMZ. Berdasarkan mereka, log mesti terlebih dahulu ditambahkan pada baris gilir dan kemudian LogStash membaca entri dari baris gilir dari luar.

Oleh itu, ia adalah untuk kes di mana pelayan terletak di DMZ bahawa seseorang perlu menggunakan skema yang agak rumit. Contoh konfigurasi kelihatan seperti ini:

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. baris gilir mesej

Komponen ini digunakan untuk menimbal entri log dalam DMZ. Rakaman dilakukan melalui sekumpulan Filebeat → LogStash. Pembacaan dilakukan dari luar DMZ melalui LogStash. Apabila beroperasi melalui RabboitMQ, kira-kira 4 ribu mesej sesaat diproses.

Penghalaan mesej dikonfigurasikan mengikut nama sistem, iaitu berdasarkan data konfigurasi FileBeat. Semua mesej pergi ke satu baris gilir. Jika atas sebab tertentu perkhidmatan beratur dihentikan, maka ini tidak akan membawa kepada kehilangan mesej: FileBeats akan menerima ralat sambungan dan menangguhkan penghantaran buat sementara waktu. Dan LogStash yang membaca dari baris gilir juga akan menerima ralat rangkaian dan menunggu sambungan dipulihkan. Dalam kes ini, data, sudah tentu, tidak lagi akan ditulis ke pangkalan data.

Arahan berikut digunakan untuk membuat dan mengkonfigurasi baris gilir:

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. Papan pemuka

Komponen ini digunakan untuk menggambarkan data pemantauan. Dalam kes ini, anda perlu memasang sumber data ClickHouse untuk pemalam Grafana 4.6+. Kami terpaksa mengubahnya sedikit untuk meningkatkan kecekapan pemprosesan penapis SQL pada papan pemuka.

Sebagai contoh, kami menggunakan pembolehubah, dan jika ia tidak ditetapkan dalam medan penapis, maka kami ingin ia tidak menjana keadaan di WHERE borang ( uriStem = » AND uriStem != » ). Dalam kes ini, ClickHouse akan membaca lajur uriStem. Secara umum, kami mencuba pilihan yang berbeza dan akhirnya membetulkan pemalam (makro $valueIfEmpty) supaya dalam kes nilai kosong ia mengembalikan 1, tanpa menyebut lajur itu sendiri.

Dan kini anda boleh menggunakan pertanyaan ini untuk graf

$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 diterjemahkan kepada SQL ini (perhatikan bahawa medan uriStem kosong telah ditukar kepada 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

Kemunculan pangkalan data ClickHouse telah menjadi peristiwa penting dalam pasaran. Sukar untuk membayangkan bahawa, secara percuma, dalam sekelip mata kami dipersenjatai dengan alat yang berkuasa dan praktikal untuk bekerja dengan data besar. Sudah tentu, dengan peningkatan keperluan (contohnya, sharding dan replikasi kepada berbilang pelayan), skema akan menjadi lebih rumit. Tetapi pada tanggapan pertama, bekerja dengan pangkalan data ini sangat menyenangkan. Ia boleh dilihat bahawa produk itu dibuat "untuk orang ramai."

Berbanding dengan ElasticSearch, kos penyimpanan dan pemprosesan log dianggarkan dapat dikurangkan sebanyak lima hingga sepuluh kali ganda. Dalam erti kata lain, jika untuk jumlah data semasa kami perlu menyediakan kumpulan beberapa mesin, maka apabila menggunakan ClickHouse, satu mesin berkuasa rendah sudah memadai untuk kami. Ya, sudah tentu, ElasticSearch juga mempunyai mekanisme pemampatan data pada cakera dan ciri lain yang boleh mengurangkan penggunaan sumber dengan ketara, tetapi berbanding dengan ClickHouse, ini akan menjadi lebih mahal.

Tanpa sebarang pengoptimuman khas di pihaknya, pada tetapan lalai, memuatkan data dan memilih daripada pangkalan data berfungsi dengan kelajuan yang menakjubkan. Kami belum mempunyai banyak data lagi (kira-kira 200 juta rekod), tetapi pelayan itu sendiri lemah. Kami boleh menggunakan alat ini pada masa hadapan untuk tujuan lain yang tidak berkaitan dengan menyimpan log. Contohnya, untuk analisis hujung ke hujung, dalam bidang keselamatan, pembelajaran mesin.

Pada akhirnya, sedikit tentang kebaikan dan keburukan.

Kekurangan

  1. Memuatkan rekod dalam kelompok besar. Di satu pihak, ini adalah ciri, tetapi anda masih perlu menggunakan komponen tambahan untuk rekod penimbal. Tugas ini tidak selalu mudah, tetapi masih boleh diselesaikan. Dan saya ingin memudahkan skim ini.
  2. Sesetengah fungsi eksotik atau ciri baharu sering pecah dalam versi baharu. Ini menimbulkan kebimbangan, mengurangkan keinginan untuk menaik taraf kepada versi baharu. Sebagai contoh, enjin jadual Kafka ialah ciri yang sangat berguna yang membolehkan anda membaca acara secara langsung daripada Kafka, tanpa melaksanakan pengguna. Tetapi berdasarkan bilangan Isu pada github, kami masih berhati-hati untuk tidak menggunakan enjin ini dalam pengeluaran. Walau bagaimanapun, jika anda tidak membuat gerak isyarat mengejut ke sisi dan menggunakan fungsi utama, maka ia berfungsi dengan stabil.

Kelebihan

  1. Tidak melambatkan.
  2. Ambang kemasukan rendah.
  3. Sumber terbuka.
  4. Percuma.
  5. Skala dengan baik (perpecahan/replikasi di luar kotak)
  6. Termasuk dalam daftar perisian Rusia yang disyorkan oleh Kementerian Perhubungan.
  7. Kehadiran sokongan rasmi dari Yandex.

Sumber: www.habr.com

Tambah komen