Bài học 9: "Chia để trị" và Quản lý luồng dữ liệu với Multiple Pipelines
Chào mừng bạn đến với Bài học 9. Ở Bài 5, chúng ta đã dùng lệnh if - else để xử lý chung log Nginx và log Ứng dụng trong cùng một tệp cấu hình (config). Tuy nhiên, cách làm đó chỉ phù hợp với các dự án nhỏ.
Khi hệ thống lớn lên, nếu bạn nhồi nhét log của Nginx, MySQL, Redis, và hàng chục dịch vụ khác vào chung một tệp logstash.conf, tệp này sẽ dài hàng ngàn dòng. Việc này dẫn đến một cơn ác mộng mang tên: "Nồi lẩu thập cẩm".
Để giải quyết triệt để vấn đề này, Logstash cung cấp một tính năng cực kỳ mạnh mẽ: Multiple Pipelines (Đa luồng).
1. Vấn đề của cấu trúc "Một luồng duy nhất" (Single Pipeline)
Khi chạy Logstash theo cách mặc định (chỉ đọc một tệp cấu hình duy nhất hoặc gộp tất cả tệp trong một thư mục), bạn sẽ gặp 3 rủi ro lớn:
- Rối loạn logic: Mọi đầu vào (Input) đều tự động đi qua mọi bộ lọc (Filter) và đi ra mọi đầu ra (Output). Bạn phải dùng hàng tá lệnh if/else để chặn chúng lại, cực kỳ mệt mỏi và dễ viết sai.
- Chết chùm: Chỉ cần bạn gõ sai một dấu ngoặc } trong phần cấu hình của log MySQL, toàn bộ "nhà máy" Logstash sẽ sập. Quá trình xử lý log Nginx và các log khác cũng bị dừng theo.
- Tranh giành tài nguyên: Log ứng dụng thường nhẹ và ít, trong khi log Nginx thì khổng lồ. Nếu chạy chung, các dòng log nhẹ sẽ phải xếp hàng chờ Nginx xử lý xong, gây ra độ trễ lớn.
2. Giải pháp: Multiple Pipelines là gì?
Multiple Pipelines cho phép bạn chia một "nhà máy" Logstash thành nhiều "băng chuyền" (pipeline) hoạt động hoàn toàn độc lập với nhau.
Mỗi băng chuyền sẽ:
- Đọc một tệp cấu hình riêng biệt.
- Có một luồng Input - Filter - Output riêng, không dính dáng đến băng chuyền khác.
- Sử dụng một lượng nhân công (CPU threads) riêng do bạn chỉ định.
3. Cách cấu hình Đa luồng với pipelines.yml
Thay vì đưa cho Logstash tệp logstash.conf, bạn sẽ mở một tệp hệ thống có tên là pipelines.yml (thường nằm ở /etc/logstash/pipelines.yml). Tại đây, bạn đóng vai trò là "Giám đốc", phân công nhiệm vụ cho từng băng chuyền.
Dưới đây là một mẫu cấu hình pipelines.yml thực tế:
# Băng chuyền 1: Chuyên xử lý Log Nginx
- pipeline.id: nginx_pipeline
path.config: "/etc/logstash/conf.d/nginx.conf"
# Chỉ định băng chuyền này được dùng 4 nhân CPU (vì Nginx có rất nhiều log)
pipeline.workers: 4
# Băng chuyền 2: Chuyên xử lý Log Ứng dụng Backend
- pipeline.id: app_pipeline
path.config: "/etc/logstash/conf.d/app.conf"
# Ứng dụng ít log hơn, chỉ cần cấp 1 nhân CPU để tiết kiệm
pipeline.workers: 1
4. Viết các tệp cấu hình độc lập
Lúc này, trong thư mục /etc/logstash/conf.d/, bạn sẽ tạo ra 2 tệp .conf riêng biệt:
Tệp 1: nginx.conf (Gọn gàng, không cần lệnh if/else dài dòng nữa)
input {
beats { port => 5044 } # Nginx gửi qua cổng 5044
}
filter {
grok { ... }
}
output {
elasticsearch { index => "nginx-logs" }
}
Tệp 2: app.conf
input {
beats { port => 5045 } # App gửi qua cổng 5045
}
filter {
# Logic xử lý hoàn toàn khác biệt
}
output {
elasticsearch { index => "app-logs" }
}
5. Lợi ích vượt trội của kiến trúc này
- An toàn tuyệt đối: Nếu ngày mai bạn chỉnh sửa sai tệp app.conf, thì chỉ có app_pipeline bị sập. Băng chuyền nginx_pipeline vẫn tiếp tục chạy và đẩy log bình thường.
- Tối ưu hiệu năng: Bạn có quyền quyết định cấp bao nhiêu CPU và bao nhiêu dung lượng Hàng đợi (Persistent Queue) cho từng loại log một cách hợp lý.
- Dễ bảo trì: Các kỹ sư làm việc nhóm sẽ không bao giờ giẫm chân lên nhau. Ai phụ trách log nào thì chỉ cần sửa tệp config của log đó.
Chuỗi bài học của chúng ta đã đi từ những khái niệm cơ bản nhất của Logstash đến các cấu hình kiến trúc chuyên sâu ở cấp độ hệ thống thực tế (Production).
Để khép lại series Logstash này, bạn có muốn Bài học 10 (bài cuối cùng) tập trung vào Kỹ năng gỡ lỗi (Troubleshooting) khi gặp các thông báo báo lỗi kinh điển như _grokparsefailure không?
All rights reserved