การส่งบันทึก Nginx json โดยใช้ Vector ไปยัง Clickhouse และ Elasticsearch

การส่งบันทึก Nginx json โดยใช้ Vector ไปยัง Clickhouse และ Elasticsearch

เวกเตอร์ซึ่งออกแบบมาเพื่อรวบรวม แปลง และส่งข้อมูลบันทึก ตัวชี้วัด และเหตุการณ์ต่างๆ

→ Github

เขียนด้วยภาษา Rust มีลักษณะประสิทธิภาพสูงและใช้ RAM ต่ำเมื่อเปรียบเทียบกับระบบอะนาล็อก นอกจากนี้ยังให้ความสนใจอย่างมากกับฟังก์ชันที่เกี่ยวข้องกับความถูกต้องโดยเฉพาะอย่างยิ่งความสามารถในการบันทึกเหตุการณ์ที่ยังไม่ได้ส่งลงในบัฟเฟอร์บนดิสก์และหมุนไฟล์

ในทางสถาปัตยกรรม Vector คือเราเตอร์เหตุการณ์ที่รับข้อความจากหนึ่งรายการขึ้นไป แหล่งที่มาสามารถเลือกใช้กับข้อความเหล่านี้ได้ การแปลงร่างและส่งไปที่หนึ่งหรือหลายรายการ ท่อระบายน้ำ.

Vector เป็นการแทนที่ filebeat และ logstash โดยสามารถทำงานได้ทั้งสองบทบาท (รับและส่งบันทึก) รายละเอียดเพิ่มเติม เว็บไซต์.

หากใน Logstash เชนจะถูกสร้างขึ้นเป็นอินพุต → ตัวกรอง → เอาท์พุต ดังนั้นใน Vector มันก็จะเป็นเช่นนั้น แหล่งที่มาการแปลงอ่างล้างมือ

ตัวอย่างสามารถพบได้ในเอกสารประกอบ

คำแนะนำนี้เป็นคำสั่งที่แก้ไขจาก เวียเชสลาฟ ราคินสกี้. คำแนะนำดั้งเดิมมีการประมวลผล geoip เมื่อทดสอบ geoip จากเครือข่ายภายใน เวกเตอร์แสดงข้อผิดพลาด

Aug 05 06:25:31.889 DEBUG transform{name=nginx_parse_rename_fields type=rename_fields}: vector::transforms::rename_fields: Field did not exist field=«geoip.country_name» rate_limit_secs=30

หากใครต้องการประมวลผล geoip ให้อ้างอิงคำแนะนำดั้งเดิมจาก เวียเชสลาฟ ราคินสกี้.

เราจะกำหนดค่าการรวมกันของ Nginx (บันทึกการเข้าถึง) → Vector (ไคลเอนต์ | Filebeat) → Vector (เซิร์ฟเวอร์ | Logstash) → แยกกันใน Clickhouse และแยกกันใน Elasticsearch เราจะติดตั้งเซิร์ฟเวอร์ 4 เครื่อง แม้ว่าคุณจะสามารถข้ามมันได้ด้วยเซิร์ฟเวอร์ 3 ตัว

การส่งบันทึก Nginx json โดยใช้ Vector ไปยัง Clickhouse และ Elasticsearch

โครงการเป็นเช่นนี้

ปิดการใช้งาน Selinux บนเซิร์ฟเวอร์ทั้งหมดของคุณ

sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
reboot

เราติดตั้งโปรแกรมจำลองเซิร์ฟเวอร์ HTTP + ยูทิลิตี้บนเซิร์ฟเวอร์ทั้งหมด

เราจะใช้โปรแกรมจำลองเซิร์ฟเวอร์ HTTP nodejs-stub-เซิร์ฟเวอร์ จาก แม็กซิม อิกนาเทนโก

Nodejs-stub-server ไม่มี rpm ที่นี่ สร้าง rpm ให้มัน rpm จะถูกสร้างขึ้นโดยใช้ Fedora บริษัท

เพิ่มที่เก็บ antonpatsev/nodejs-stub-server

yum -y install yum-plugin-copr epel-release
yes | yum copr enable antonpatsev/nodejs-stub-server

ติดตั้ง nodejs-stub-server, Apache benchmark และ screen terminal multiplexer บนเซิร์ฟเวอร์ทั้งหมด

yum -y install stub_http_server screen mc httpd-tools screen

ฉันแก้ไขเวลาตอบสนอง stub_http_server ในไฟล์ /var/lib/stub_http_server/stub_http_server.js เพื่อให้มีบันทึกมากขึ้น

var max_sleep = 10;

มาเปิดตัว stub_http_server กัน

systemctl start stub_http_server
systemctl enable stub_http_server

การติดตั้งคลิกเฮาส์ บนเซิร์ฟเวอร์ 3

ClickHouse ใช้ชุดคำสั่ง SSE 4.2 ดังนั้น เว้นแต่จะระบุไว้เป็นอย่างอื่น การสนับสนุนในโปรเซสเซอร์ที่ใช้จึงกลายเป็นข้อกำหนดของระบบเพิ่มเติม นี่คือคำสั่งเพื่อตรวจสอบว่าโปรเซสเซอร์ปัจจุบันรองรับ SSE 4.2 หรือไม่:

grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"

ก่อนอื่นคุณต้องเชื่อมต่อที่เก็บข้อมูลอย่างเป็นทางการ:

sudo yum install -y yum-utils
sudo rpm --import https://repo.clickhouse.tech/CLICKHOUSE-KEY.GPG
sudo yum-config-manager --add-repo https://repo.clickhouse.tech/rpm/stable/x86_64

ในการติดตั้งแพ็คเกจคุณต้องรันคำสั่งต่อไปนี้:

sudo yum install -y clickhouse-server clickhouse-client

อนุญาตให้ clickhouse-server ฟังการ์ดเครือข่ายในไฟล์ /etc/clickhouse-server/config.xml

<listen_host>0.0.0.0</listen_host>

การเปลี่ยนระดับการบันทึกจากการติดตามเป็นการแก้ไขข้อบกพร่อง

การแก้ปัญหา

การตั้งค่าการบีบอัดมาตรฐาน:

min_compress_block_size  65536
max_compress_block_size  1048576

หากต้องการเปิดใช้งานการบีบอัด Zstd ไม่แนะนำให้แตะการกำหนดค่า แต่ควรใช้ DDL

การส่งบันทึก Nginx json โดยใช้ Vector ไปยัง Clickhouse และ Elasticsearch

ฉันไม่พบวิธีใช้การบีบอัด zstd ผ่าน DDL ใน Google ฉันก็เลยทิ้งมันไว้เหมือนเดิม

เพื่อนร่วมงานที่ใช้การบีบอัด zstd ใน Clickhouse โปรดแบ่งปันคำแนะนำ

หากต้องการสตาร์ทเซิร์ฟเวอร์เป็น daemon ให้รัน:

service clickhouse-server start

ตอนนี้เรามาดูการตั้งค่า Clickhouse กันดีกว่า

ไปที่คลิกเฮาส์

clickhouse-client -h 172.26.10.109 -m

172.26.10.109 — IP ของเซิร์ฟเวอร์ที่ติดตั้ง Clickhouse

มาสร้างฐานข้อมูลเวกเตอร์กันดีกว่า

CREATE DATABASE vector;

ลองตรวจสอบว่ามีฐานข้อมูลอยู่

show databases;

สร้างตาราง vector.logs

/* Это таблица где хранятся логи как есть */

CREATE TABLE vector.logs
(
    `node_name` String,
    `timestamp` DateTime,
    `server_name` String,
    `user_id` String,
    `request_full` String,
    `request_user_agent` String,
    `request_http_host` String,
    `request_uri` String,
    `request_scheme` String,
    `request_method` String,
    `request_length` UInt64,
    `request_time` Float32,
    `request_referrer` String,
    `response_status` UInt16,
    `response_body_bytes_sent` UInt64,
    `response_content_type` String,
    `remote_addr` IPv4,
    `remote_port` UInt32,
    `remote_user` String,
    `upstream_addr` IPv4,
    `upstream_port` UInt32,
    `upstream_bytes_received` UInt64,
    `upstream_bytes_sent` UInt64,
    `upstream_cache_status` String,
    `upstream_connect_time` Float32,
    `upstream_header_time` Float32,
    `upstream_response_length` UInt64,
    `upstream_response_time` Float32,
    `upstream_status` UInt16,
    `upstream_content_type` String,
    INDEX idx_http_host request_http_host TYPE set(0) GRANULARITY 1
)
ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY timestamp
TTL timestamp + toIntervalMonth(1)
SETTINGS index_granularity = 8192;

เราตรวจสอบว่ามีการสร้างตารางแล้ว เปิดตัวกันเลย clickhouse-client และทำการร้องขอ

ไปที่ฐานข้อมูลเวกเตอร์กันดีกว่า

use vector;

Ok.

0 rows in set. Elapsed: 0.001 sec.

มาดูตารางกัน

show tables;

┌─name────────────────┐
│ logs                │
└─────────────────────┘

การติดตั้ง elasticsearch บนเซิร์ฟเวอร์ที่ 4 เพื่อส่งข้อมูลเดียวกันไปยัง Elasticsearch เพื่อเปรียบเทียบกับ Clickhouse

เพิ่มคีย์ rpm สาธารณะ

rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

มาสร้าง 2 repo:

/etc/yum.repos.d/elasticsearch.repo

[elasticsearch]
name=Elasticsearch repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md

/etc/yum.repos.d/kibana.repo

[kibana-7.x]
name=Kibana repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

ติดตั้ง elasticsearch และ kibana

yum install -y kibana elasticsearch

เนื่องจากจะมีอยู่ใน 1 ชุด คุณจึงต้องเพิ่มสิ่งต่อไปนี้ลงในไฟล์ /etc/elasticsearch/elasticsearch.yml:

discovery.type: single-node

เพื่อให้เวกเตอร์นั้นสามารถส่งข้อมูลไปยัง elasticsearch จากเซิร์ฟเวอร์อื่น มาเปลี่ยน network.host กัน

network.host: 0.0.0.0

หากต้องการเชื่อมต่อกับ kibana ให้เปลี่ยนพารามิเตอร์ server.host ในไฟล์ /etc/kibana/kibana.yml

server.host: "0.0.0.0"

เก่าและรวม elasticsearch ใน autostart

systemctl enable elasticsearch
systemctl start elasticsearch

และคิบานะ

systemctl enable kibana
systemctl start kibana

การกำหนดค่า Elasticsearch สำหรับโหมดโหนดเดียว 1 ชาร์ด, 0 เรพลิกา เป็นไปได้มากว่าคุณจะมีคลัสเตอร์ที่มีเซิร์ฟเวอร์จำนวนมาก และคุณไม่จำเป็นต้องทำเช่นนี้

สำหรับดัชนีในอนาคต ให้อัปเดตเทมเพลตเริ่มต้น:

curl -X PUT http://localhost:9200/_template/default -H 'Content-Type: application/json' -d '{"index_patterns": ["*"],"order": -1,"settings": {"number_of_shards": "1","number_of_replicas": "0"}}' 

การติดตั้ง เวกเตอร์ เพื่อทดแทน Logstash บนเซิร์ฟเวอร์ 2

yum install -y https://packages.timber.io/vector/0.9.X/vector-x86_64.rpm mc httpd-tools screen

มาตั้งค่า Vector แทน Logstash กันดีกว่า แก้ไขไฟล์ /etc/vector/vector.toml

# /etc/vector/vector.toml

data_dir = "/var/lib/vector"

[sources.nginx_input_vector]
  # General
  type                          = "vector"
  address                       = "0.0.0.0:9876"
  shutdown_timeout_secs         = 30

[transforms.nginx_parse_json]
  inputs                        = [ "nginx_input_vector" ]
  type                          = "json_parser"

[transforms.nginx_parse_add_defaults]
  inputs                        = [ "nginx_parse_json" ]
  type                          = "lua"
  version                       = "2"

  hooks.process = """
  function (event, emit)

    function split_first(s, delimiter)
      result = {};
      for match in (s..delimiter):gmatch("(.-)"..delimiter) do
          table.insert(result, match);
      end
      return result[1];
    end

    function split_last(s, delimiter)
      result = {};
      for match in (s..delimiter):gmatch("(.-)"..delimiter) do
          table.insert(result, match);
      end
      return result[#result];
    end

    event.log.upstream_addr             = split_first(split_last(event.log.upstream_addr, ', '), ':')
    event.log.upstream_bytes_received   = split_last(event.log.upstream_bytes_received, ', ')
    event.log.upstream_bytes_sent       = split_last(event.log.upstream_bytes_sent, ', ')
    event.log.upstream_connect_time     = split_last(event.log.upstream_connect_time, ', ')
    event.log.upstream_header_time      = split_last(event.log.upstream_header_time, ', ')
    event.log.upstream_response_length  = split_last(event.log.upstream_response_length, ', ')
    event.log.upstream_response_time    = split_last(event.log.upstream_response_time, ', ')
    event.log.upstream_status           = split_last(event.log.upstream_status, ', ')

    if event.log.upstream_addr == "" then
        event.log.upstream_addr = "127.0.0.1"
    end

    if (event.log.upstream_bytes_received == "-" or event.log.upstream_bytes_received == "") then
        event.log.upstream_bytes_received = "0"
    end

    if (event.log.upstream_bytes_sent == "-" or event.log.upstream_bytes_sent == "") then
        event.log.upstream_bytes_sent = "0"
    end

    if event.log.upstream_cache_status == "" then
        event.log.upstream_cache_status = "DISABLED"
    end

    if (event.log.upstream_connect_time == "-" or event.log.upstream_connect_time == "") then
        event.log.upstream_connect_time = "0"
    end

    if (event.log.upstream_header_time == "-" or event.log.upstream_header_time == "") then
        event.log.upstream_header_time = "0"
    end

    if (event.log.upstream_response_length == "-" or event.log.upstream_response_length == "") then
        event.log.upstream_response_length = "0"
    end

    if (event.log.upstream_response_time == "-" or event.log.upstream_response_time == "") then
        event.log.upstream_response_time = "0"
    end

    if (event.log.upstream_status == "-" or event.log.upstream_status == "") then
        event.log.upstream_status = "0"
    end

    emit(event)

  end
  """

[transforms.nginx_parse_remove_fields]
    inputs                              = [ "nginx_parse_add_defaults" ]
    type                                = "remove_fields"
    fields                              = ["data", "file", "host", "source_type"]

[transforms.nginx_parse_coercer]

    type                                = "coercer"
    inputs                              = ["nginx_parse_remove_fields"]

    types.request_length = "int"
    types.request_time = "float"

    types.response_status = "int"
    types.response_body_bytes_sent = "int"

    types.remote_port = "int"

    types.upstream_bytes_received = "int"
    types.upstream_bytes_send = "int"
    types.upstream_connect_time = "float"
    types.upstream_header_time = "float"
    types.upstream_response_length = "int"
    types.upstream_response_time = "float"
    types.upstream_status = "int"

    types.timestamp = "timestamp"

[sinks.nginx_output_clickhouse]
    inputs   = ["nginx_parse_coercer"]
    type     = "clickhouse"

    database = "vector"
    healthcheck = true
    host = "http://172.26.10.109:8123" #  Адрес Clickhouse
    table = "logs"

    encoding.timestamp_format = "unix"

    buffer.type = "disk"
    buffer.max_size = 104900000
    buffer.when_full = "block"

    request.in_flight_limit = 20

[sinks.elasticsearch]
    type = "elasticsearch"
    inputs   = ["nginx_parse_coercer"]
    compression = "none"
    healthcheck = true
    # 172.26.10.116 - сервер где установен elasticsearch
    host = "http://172.26.10.116:9200" 
    index = "vector-%Y-%m-%d"

คุณสามารถปรับส่วนTransforms.nginx_parse_add_defaults ได้

ในขณะที่ เวียเชสลาฟ ราคินสกี้ ใช้การกำหนดค่าเหล่านี้สำหรับ CDN ขนาดเล็กและสามารถมีค่าได้หลายค่าใน upstream_*

ตัวอย่างเช่น:

"upstream_addr": "128.66.0.10:443, 128.66.0.11:443, 128.66.0.12:443"
"upstream_bytes_received": "-, -, 123"
"upstream_status": "502, 502, 200"

หากนี่ไม่ใช่สถานการณ์ของคุณ คุณสามารถทำให้ส่วนนี้ง่ายขึ้นได้

มาสร้างการตั้งค่าบริการสำหรับ systemd /etc/systemd/system/vector.service

# /etc/systemd/system/vector.service

[Unit]
Description=Vector
After=network-online.target
Requires=network-online.target

[Service]
User=vector
Group=vector
ExecStart=/usr/bin/vector
ExecReload=/bin/kill -HUP $MAINPID
Restart=no
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=vector

[Install]
WantedBy=multi-user.target

หลังจากสร้างตารางแล้ว คุณสามารถเรียกใช้ Vector ได้

systemctl enable vector
systemctl start vector

สามารถดูบันทึกเวกเตอร์ได้ดังนี้:

journalctl -f -u vector

ควรมีรายการเช่นนี้ในบันทึก

INFO vector::topology::builder: Healthcheck: Passed.
INFO vector::topology::builder: Healthcheck: Passed.

บนไคลเอนต์ (เว็บเซิร์ฟเวอร์) - เซิร์ฟเวอร์ที่ 1

บนเซิร์ฟเวอร์ที่มี nginx คุณต้องปิดการใช้งาน ipv6 เนื่องจากตารางบันทึกใน clickhouse ใช้ฟิลด์นี้ upstream_addr IPv4 เนื่องจากฉันไม่ได้ใช้ ipv6 ภายในเครือข่าย หากไม่ปิด ipv6 จะมีข้อผิดพลาด:

DB::Exception: Invalid IPv4 value.: (while read the value of key upstream_addr)

บางทีผู้อ่านอาจเพิ่มการรองรับ ipv6

สร้างไฟล์ /etc/sysctl.d/98-disable-ipv6.conf

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

การใช้การตั้งค่า

sysctl --system

มาติดตั้ง nginx กันดีกว่า

เพิ่มไฟล์ที่เก็บ nginx /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

ติดตั้งแพ็คเกจ nginx

yum install -y nginx

ขั้นแรกเราต้องกำหนดค่ารูปแบบบันทึกใน Nginx ในไฟล์ /etc/nginx/nginx.conf

user  nginx;
# you must set worker processes based on your CPU cores, nginx does not benefit from setting more than that
worker_processes auto; #some last versions calculate it automatically

# number of file descriptors used for nginx
# the limit for the maximum FDs on the server is usually set by the OS.
# if you don't set FD's then OS settings will be used which is by default 2000
worker_rlimit_nofile 100000;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

# provides the configuration file context in which the directives that affect connection processing are specified.
events {
    # determines how much clients will be served per worker
    # max clients = worker_connections * worker_processes
    # max clients is also limited by the number of socket connections available on the system (~64k)
    worker_connections 4000;

    # optimized to serve many clients with each thread, essential for linux -- for testing environment
    use epoll;

    # accept as many connections as possible, may flood worker connections if set too low -- for testing environment
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

log_format vector escape=json
    '{'
        '"node_name":"nginx-vector",'
        '"timestamp":"$time_iso8601",'
        '"server_name":"$server_name",'
        '"request_full": "$request",'
        '"request_user_agent":"$http_user_agent",'
        '"request_http_host":"$http_host",'
        '"request_uri":"$request_uri",'
        '"request_scheme": "$scheme",'
        '"request_method":"$request_method",'
        '"request_length":"$request_length",'
        '"request_time": "$request_time",'
        '"request_referrer":"$http_referer",'
        '"response_status": "$status",'
        '"response_body_bytes_sent":"$body_bytes_sent",'
        '"response_content_type":"$sent_http_content_type",'
        '"remote_addr": "$remote_addr",'
        '"remote_port": "$remote_port",'
        '"remote_user": "$remote_user",'
        '"upstream_addr": "$upstream_addr",'
        '"upstream_bytes_received": "$upstream_bytes_received",'
        '"upstream_bytes_sent": "$upstream_bytes_sent",'
        '"upstream_cache_status":"$upstream_cache_status",'
        '"upstream_connect_time":"$upstream_connect_time",'
        '"upstream_header_time":"$upstream_header_time",'
        '"upstream_response_length":"$upstream_response_length",'
        '"upstream_response_time":"$upstream_response_time",'
        '"upstream_status": "$upstream_status",'
        '"upstream_content_type":"$upstream_http_content_type"'
    '}';

    access_log  /var/log/nginx/access.log  main;
    access_log  /var/log/nginx/access.json.log vector;      # Новый лог в формате json

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

เพื่อไม่ให้การกำหนดค่าปัจจุบันของคุณเสียหาย Nginx อนุญาตให้คุณมีหลายคำสั่ง access_log

access_log  /var/log/nginx/access.log  main;            # Стандартный лог
access_log  /var/log/nginx/access.json.log vector;      # Новый лог в формате json

อย่าลืมเพิ่มกฎเพื่อเข้าสู่ระบบสำหรับบันทึกใหม่ (หากไฟล์บันทึกไม่ได้ลงท้ายด้วย .log)

ลบ default.conf ออกจาก /etc/nginx/conf.d/

rm -f /etc/nginx/conf.d/default.conf

เพิ่มโฮสต์เสมือน /etc/nginx/conf.d/vhost1.conf

server {
    listen 80;
    server_name vhost1;
    location / {
        proxy_pass http://172.26.10.106:8080;
    }
}

เพิ่มโฮสต์เสมือน /etc/nginx/conf.d/vhost2.conf

server {
    listen 80;
    server_name vhost2;
    location / {
        proxy_pass http://172.26.10.108:8080;
    }
}

เพิ่มโฮสต์เสมือน /etc/nginx/conf.d/vhost3.conf

server {
    listen 80;
    server_name vhost3;
    location / {
        proxy_pass http://172.26.10.109:8080;
    }
}

เพิ่มโฮสต์เสมือน /etc/nginx/conf.d/vhost4.conf

server {
    listen 80;
    server_name vhost4;
    location / {
        proxy_pass http://172.26.10.116:8080;
    }
}

เพิ่มโฮสต์เสมือน (172.26.10.106 ip ของเซิร์ฟเวอร์ที่ติดตั้ง nginx) ให้กับเซิร์ฟเวอร์ทั้งหมดไปยังไฟล์ /etc/hosts:

172.26.10.106 vhost1
172.26.10.106 vhost2
172.26.10.106 vhost3
172.26.10.106 vhost4

และถ้าทุกอย่างพร้อมแล้ว

nginx -t 
systemctl restart nginx

ตอนนี้เรามาติดตั้งกันเอง เวกเตอร์

yum install -y https://packages.timber.io/vector/0.9.X/vector-x86_64.rpm

มาสร้างไฟล์การตั้งค่าสำหรับ systemd /etc/systemd/system/vector.service

[Unit]
Description=Vector
After=network-online.target
Requires=network-online.target

[Service]
User=vector
Group=vector
ExecStart=/usr/bin/vector
ExecReload=/bin/kill -HUP $MAINPID
Restart=no
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=vector

[Install]
WantedBy=multi-user.target

และกำหนดค่าการแทนที่ Filebeat ในการกำหนดค่า /etc/vector/vector.toml ที่อยู่ IP 172.26.10.108 คือที่อยู่ IP ของเซิร์ฟเวอร์บันทึก (Vector-Server)

data_dir = "/var/lib/vector"

[sources.nginx_file]
  type                          = "file"
  include                       = [ "/var/log/nginx/access.json.log" ]
  start_at_beginning            = false
  fingerprinting.strategy       = "device_and_inode"

[sinks.nginx_output_vector]
  type                          = "vector"
  inputs                        = [ "nginx_file" ]

  address                       = "172.26.10.108:9876"

อย่าลืมเพิ่มผู้ใช้เวกเตอร์ในกลุ่มที่ต้องการเพื่อให้เขาสามารถอ่านไฟล์บันทึกได้ ตัวอย่างเช่น nginx ใน centos จะสร้างบันทึกที่มีสิทธิ์ของกลุ่ม adm

usermod -a -G adm vector

มาเริ่มบริการเวกเตอร์กันดีกว่า

systemctl enable vector
systemctl start vector

สามารถดูบันทึกเวกเตอร์ได้ดังนี้:

journalctl -f -u vector

ควรมีรายการเช่นนี้ในบันทึก

INFO vector::topology::builder: Healthcheck: Passed.

การทดสอบความเครียด

เราทำการทดสอบโดยใช้เกณฑ์มาตรฐาน Apache

มีการติดตั้งแพ็คเกจ httpd-tools บนเซิร์ฟเวอร์ทั้งหมด

เราเริ่มการทดสอบโดยใช้เกณฑ์มาตรฐาน Apache จากเซิร์ฟเวอร์ที่แตกต่างกัน 4 ตัวบนหน้าจอ ขั้นแรก เราเปิดตัวเทอร์มินัลมัลติเพล็กเซอร์หน้าจอ จากนั้นจึงเริ่มการทดสอบโดยใช้เกณฑ์มาตรฐาน Apache วิธีการทำงานกับหน้าจอคุณสามารถดูได้ใน статье.

จากเซิร์ฟเวอร์ที่ 1

while true; do ab -H "User-Agent: 1server" -c 100 -n 10 -t 10 http://vhost1/; sleep 1; done

จากเซิร์ฟเวอร์ที่ 2

while true; do ab -H "User-Agent: 2server" -c 100 -n 10 -t 10 http://vhost2/; sleep 1; done

จากเซิร์ฟเวอร์ที่ 3

while true; do ab -H "User-Agent: 3server" -c 100 -n 10 -t 10 http://vhost3/; sleep 1; done

จากเซิร์ฟเวอร์ที่ 4

while true; do ab -H "User-Agent: 4server" -c 100 -n 10 -t 10 http://vhost4/; sleep 1; done

มาตรวจสอบข้อมูลใน Clickhouse กัน

ไปที่คลิกเฮาส์

clickhouse-client -h 172.26.10.109 -m

การสร้างแบบสอบถาม SQL

SELECT * FROM vector.logs;

┌─node_name────┬───────────timestamp─┬─server_name─┬─user_id─┬─request_full───┬─request_user_agent─┬─request_http_host─┬─request_uri─┬─request_scheme─┬─request_method─┬─request_length─┬─request_time─┬─request_referrer─┬─response_status─┬─response_body_bytes_sent─┬─response_content_type─┬───remote_addr─┬─remote_port─┬─remote_user─┬─upstream_addr─┬─upstream_port─┬─upstream_bytes_received─┬─upstream_bytes_sent─┬─upstream_cache_status─┬─upstream_connect_time─┬─upstream_header_time─┬─upstream_response_length─┬─upstream_response_time─┬─upstream_status─┬─upstream_content_type─┐
│ nginx-vector │ 2020-08-07 04:32:42 │ vhost1      │         │ GET / HTTP/1.0 │ 1server            │ vhost1            │ /           │ http           │ GET            │             66 │        0.028 │                  │             404 │                       27 │                       │ 172.26.10.106 │       45886 │             │ 172.26.10.106 │             0 │                     109 │                  97 │ DISABLED              │                     0 │                0.025 │                       27 │                  0.029 │             404 │                       │
└──────────────┴─────────────────────┴─────────────┴─────────┴────────────────┴────────────────────┴───────────────────┴─────────────┴────────────────┴────────────────┴────────────────┴──────────────┴──────────────────┴─────────────────┴──────────────────────────┴───────────────────────┴───────────────┴─────────────┴─────────────┴───────────────┴───────────────┴─────────────────────────┴─────────────────────┴───────────────────────┴───────────────────────┴──────────────────────┴──────────────────────────┴────────────────────────┴─────────────────┴───────────────────────

ค้นหาขนาดของโต๊ะใน Clickhouse

select concat(database, '.', table)                         as table,
       formatReadableSize(sum(bytes))                       as size,
       sum(rows)                                            as rows,
       max(modification_time)                               as latest_modification,
       sum(bytes)                                           as bytes_size,
       any(engine)                                          as engine,
       formatReadableSize(sum(primary_key_bytes_in_memory)) as primary_keys_size
from system.parts
where active
group by database, table
order by bytes_size desc;

มาดูกันว่า Clickhouse ใช้บันทึกจำนวนเท่าใด

การส่งบันทึก Nginx json โดยใช้ Vector ไปยัง Clickhouse และ Elasticsearch

ขนาดตารางบันทึกคือ 857.19 MB

การส่งบันทึก Nginx json โดยใช้ Vector ไปยัง Clickhouse และ Elasticsearch

ขนาดของข้อมูลเดียวกันในดัชนีใน Elasticsearch คือ 4,5GB

หากคุณไม่ได้ระบุข้อมูลในเวกเตอร์ในพารามิเตอร์ Clickhouse จะใช้เวลา 4500/857.19 = 5.24 เท่าน้อยกว่าใน Elasticsearch

ในเวกเตอร์ ฟิลด์การบีบอัดจะใช้เป็นค่าเริ่มต้น

โทรเลขแชทโดย คลิกเฮาส์
โทรเลขแชทโดย ElasticSearch
โทรเลขแชทโดย "การรวบรวมและการวิเคราะห์ระบบ собщений"

ที่มา: will.com

เพิ่มความคิดเห็น