Log tập trung là gì? Tại sao cần trong microservices (phần 1)
I. Giới thiệu
Để đáp ứng nhu cầu phát triển nhanh chóng, dự án mình làm đã chuyển từ mô hình monolithic
sang microservices
. Tuy nhiên, hệ thống ngày càng phức tạp cũng đặt ra nhiều thách thức. Một trong số đó là vấn đề quản lý và giám sát log:
- Khó khăn trong việc debug: Một request có thể đi qua 5-10 services khác nhau, mỗi service sinh ra log riêng biệt. Khi có lỗi, việc truy vết theo các service mất rất nhiều thời gian.
- Chậm trễ trong phản ứng sự cố: Team thường phát hiện lỗi thông qua phản hồi từ người dùng thay vì chủ động nhận biết qua monitoring system.
- Phân tích hiệu năng không hiệu quả: Việc phân tích bottleneck yêu cầu thu thập và đối chiếu log từ nhiều services, có thể mất vài giờ đến cả ngày.
- Thiếu cái nhìn tổng quan: Không có dashboard thống nhất để theo dõi health của toàn bộ hệ thống, gây khó khăn trong việc phát hiện và xử lý vấn đề.
Ví dụ: Giả sử một đơn hàng gặp lỗi trong quá trình đặt đơn hàng. Trước đây, khi hệ thống chỉ có 1 service, việc tìm kiếm và khắc phục lỗi tương đối đơn giản. Bạn chỉ cần truy cập vào server và tìm kiếm từ khóa error
.
Nhưng khi hệ thống phát triển và có hàng chục service khác nhau liên quan tới một tác vụ. Để tìm ra nguyên nhân, bạn phải lần lượt kiểm tra log của service cart, product, order... Việc này rất tốn thời gian và dễ xảy ra nhầm lẫn.
Để giải quyết những thách thức trên, log tập trung
chính là cứu cánh của chúng ta, nó sinh ra với các mục tiêu:
-
Theo dõi và debug lỗi hệ thống
: Thông qua Correlation ID (trace ID), log tập trung giúp theo dõi toàn bộ hành trình của một request từ lúc vào hệ thống đến khi trả response, giúp việc debug từ vài giờ rút ngắn xuống còn vài phút. -
Giám sát sức khỏe hệ thống
: Tự động phát hiện và cảnh báo các bất thường như error rate tăng đột biến, service có latency cao, hoặc resource usage vượt ngưỡng, giúp team phản ứng trước khi user báo lỗi. -
Phân tích hiệu năng
: Thu thập và visualize các metrics quan trọng như response time, throughput của từng service, giúp team dễ dàng phát hiện bottleneck và có kế hoạch tối ưu phù hợp. -
Phục vụ business analytics
: Tổng hợp các chỉ số kinh doanh như số lượng đơn hàng, tỷ lệ chuyển đổi, hành vi người dùng, giúp team product và marketing đưa ra quyết định dựa trên dữ liệu. -
Đảm bảo security và compliance
: Lưu trữ đầy đủ audit trail cho các thao tác nhạy cảm, phát hiện sớm các dấu hiệu tấn công, đồng thời đáp ứng các yêu cầu về việc lưu trữ log theo quy định.
II. Kiến trúc hệ thống
1. Tổng quan kiến trúc
Một hệ thống log tập trung thường bao gồm 3 thành phần chính log collection
, storage
, vizualization
Log collection: thu thập thông tin từ các nguồn log khác nhau trong hệ thống, thực hiện việc chuẩn hóa format rồi gửi tới storage
. Khi một hệ thống trở nên lớn hơn, log collection thường được tách thành 2 thành phần nhỏ hơn:
Agent
: là một công cụ nhẹ được đi kèm với source server, nó sẽ thu thập log và gửi về collector. VD: filebeat, fluentbitCollector
: hoạt động như một trạm trung chuyển trong hệ thống. Nó tập trung log từ nhiều agent, thực hiện nhiệm vụ như format, lọc dữ liệu không cần thiết và định tuyến log đến đúng nơi lưu trữ. Với cơ chế load balancing tích hợp, nó còn đảm bảo việc phân phối log đồng đều, tránh quá tải cho storage. VD: logstash, fluentd...
Storage: là nơi lưu trữ dài hạn log data, hỗ trợ xây dưnhg index để tối ưu hoá tìm kiếm. VD: Elasticsearch, Loki, ClickHouse...
Visualization: Từ dữ liệu trong storage, nó sẽ tạo ra các dashboard trực quan, nó giúp người dùng dễ dàng theo dõi và phân tích log. Có các hệ thống cảnh báo tích hợp sẽ chủ động thông báo khi phát hiện các bất thường. VD: Kibana, grafana...
Ba thành phần này kết hợp tạo nên một luồn xử lý log hoàn chỉnh, đảm bảo tính sẵn sàng cao và khả năng mở rộng linh hoạt của hệ thống.
2. Mô hình thu thập Log
2.1. Pull Model (Poll-based Collection)
Collector chủ động kéo (pull) log từ các nguồn dữ liệu. Nó sẽ định kỳ quét và thu thập log theo khoảng thời gian đã cấu hình.
Ưu điểm:
Kiểm soát tốt tải hệ thống
: Collector có thể điều chỉnh tần suất pull dựa trên yêu cầu tài nguyên hiện tại.Dễ debug
: Có thể tạm dừng hoặc điều chỉnh việc pull khi cần, giúp việc theo dõi và xử lý sự cố trở nên dễ dàng hơn.Không cần cài đặt agent
: Giảm bớt overhead và phức tạp trên application server, thuận tiện khi không thể cài đặt agent trên tất cả các nguồn.
Nhược điểm:
Độ trễ
: Vì log chỉ được quét và thu thập theo chu kỳ cố định nên có thể gây ra độ trễ trong việc thu thập dữ liệu.Khó mở rộng
: Collector phải đủ mạnh để pull dữ liệu từ nhiều nguồn khác nhau; khi số lượng nguồn tăng lên, việc mở rộng có thể trở nên phức tạp và tốn kém.Tốn băng thông
: Collector phải liên tục poll dữ liệu từ các nguồn, ngay cả khi không có log mới, gây lãng phí băng thông.
2.2. Push Model (Event-driven Collection)
Agent được cài đặt cùng application. Nó chủ động đẩy (push) log đến collector
Ưu điểm:
Realtime
: Log được gửi ngay khi có sự kiện, giúp giảm thiểu độ trễ trong việc thu thập dữ liệu.Hiệu quả băng thông
: Chỉ đẩy log khi có dữ liệu mới, giảm bớt việc tiêu thụ băng thông không cần thiết.Dễ mở rộng
: Có thể triển khai thêm nhiều collector để phân tải (load balancing) giữa các agent.Độ tin cậy cao
: Agent thường có khả năng buffer và retry nếu quá trình truyền gặp sự cố.
Nhược điểm:
Tiêu tốn tài nguyên
: Mỗi server đều cần chạy agent, gây tốn tài nguyên hệ thống, đặc biệt trên các máy có cấu hình thấp.Phức tạp trong quản lý
: Việc triển khai và bảo trì agent trên nhiều máy có thể gây ra phức tạp trong quản lý.Vấn đề bảo mật
: Cần thiết lập các cấu hình bảo mật để bảo vệ giao tiếp giữa agent và collector nhằm tránh rò rỉ dữ liệu.
Có những canh cãi xung quanh 2 model này, xem model nào tốt hơn. Tuy nhiên không có câu trả lời rõ ràng, nó phụ thuộc vào từng hệ thống. Với những công ty lớn có thể kết hợp cả 2 model.
3. Kiến trúc theo quy mô
Về tổng quan thì có 3 thành phần chính nhưng sẽ tuỳ vào từng business mà chúng ta triển khai theo kiến trúc khác nhau. Một trong những cách để xây dựng kiến trúc đó là đi theo quy mô dự án.
3.1. Small Scale (1-10 services)
Đặc điểm của mô hình này là:
- Collector và Agent gộp làm một để giảm độ phức tạp trong triển khai.
- Storage dùng single node và được backup định kỳ.
Ưu điểm:
- Setup đơn giản, chi phí thấp.
- Dễ dàng backup và restore.
- Phù hợp cho ứng dụng MVP hoặc triển khai thử nghiệm.
Nhược điểm:
-
Single point of failure tại storage
: Khi chỉ có một node storage, nếu node này gặp sự cố (như crash, disk full), toàn bộ hệ thống log sẽ ngừng hoạt động vì không có node dự phòng -
Bottleneck khi xử lý volume log lớn
: Single node phải xử lý tất cả các tác vụ đọc/ghi/tìm kiếm log. Khi volume log tăng, node này sẽ quá tải dẫn đến việc xử lý chậm hoặc thậm chí crash -
Không có khả năng xử lý spike traffic
: Khi có đột biến về lượng log (ví dụ: flash sale hoặc sự cố), hệ thống không có cơ chế buffer để xử lý tạm thời, dẫn đến mất log -
Collector và Agent chung
: Một process phải đảm nhiệm cả hai nhiệm vụ thu thập và chuyển tiếp log, dẫn đến cạnh tranh tài nguyên (CPU, memory) và ảnh hưởng hiệu năng
3.2. Medium Scale (10-50 services)
-
Khi hệ thống phát triển lên khoảng vài chục service, cần có sự tách biệt collector và Agent để đảm bảo hiệu năng.
-
Storage cluster với 2-3 node giúp tăng tính sẵn sàng và khả năng chịu lỗi.
-
Buffer queue tại log collection đóng vai trò quan trọng trong việc xử lý spike traffic (traffic tăng đột biến tại một thời điểm) và đảm bảo không mất log khi có sự cố.
Ưu điểm:
- Khả năng chịu lỗi tốt hơn với storage cluster.
- Hiệu năng cao hơn nhờ tách collector và Agent.
- Xử lý được spike traffic.
Nhược điểm:
-
Phức tạp trong việc vận hành cluster
: Team phải xử lý các vấn đề như đồng bộ dữ liệu giữa các node, xử lý split-brain, quản lý node failure và recovery. -
Chi phí infrastructure
: Cần nhiều server hơn cho cluster storage và tách biệt collector/Agent, kèm theo chi phí cho network traffic giữa các node. -
Load balancing cho nhiều region
: Khi các service nằm ở nhiều region khác nhau (như US, EU, Asia), việc tập trung log về một cluster storage sẽ gây độ trễ cao và tốn bandwidth. -
Scale theo chiều ngang
: Không thể dễ dàng thêm node mới vào cluster khi cần mở rộng, vì kiến trúc chưa được thiết kế để phân tán đồng đều workload.
3.3. Large Scale (50+ services)
-
Với hệ thống quy mô lớn, message queue như
Kafka
hoặcRedis
trở thành thành phần không thể thiếu, đóng vai trò buffer layer tin cậy giữa collectors và Agent. -
Multiple log collection clusters giúp phân tán tải và xử lý log theo region hoặc business unit.
-
Distributed storage đảm bảo dữ liệu được bảo vệ và có thể truy cập ngay cả khi có sự cố.
Kiến trúc này phức tạp hơn nhưng đem lại khả năng mở rộng và độ tin cậy cao, phù hợp với các hệ thống enterprise.
Ưu điểm:
- Tính sẵn sàng và khả năng scale cao
- Cân bằng tải hiệu quả giữa các region.
- Độ trễ thấp nhờ phân tán theo vùng địa lý.
- Khả năng xử lý volume log rất lớn.
Nhược điểm:
- Chi phí vận hành và infrastructure cao
Độ phức tạp trong quản lý
: Team phải xử lý nhiều thách thức của distributed system như:- Consistency giữa các node storage
- Network partition và cơ chế recovery
- Monitoring và troubleshooting phức tạp hơn nhiều
- Yêu cầu team có chuyên môn về distributed systems
Việc chọn kiến trúc phù hợp không chỉ dựa vào số lượng service mà còn phải cân nhắc các yếu tố như volume log, yêu cầu về latency, budget và khả năng vận hành của team. Một hệ thống tốt cần có khả năng phát triển theo thời gian khi quy mô tăng lên.
4. Phương thức thu thập log
4.1. File-based Collection (lấy log từ file)
- Model áp dụng: Pull Model
Đây là phương pháp truyền thống và phổ biến nhất trong việc thu thập log. Với phương pháp này, agent theo dõi và đọc các file log mà ứng dụng tạo ra. Một agent thông minh có thể theo dõi quá trình xoay vòng file log (log rotation
).
Log rotation là một kỹ thuật dùng để quản lý các file log khi chúng trở nên quá lớn. Thay vì ứng dụng giữ một file log duy nhất cho đến khi nó đạt đến kích thước tối đa, hệ thống sẽ tự động đổi tên (hoặc "di chuyển") file log hiện tại và tạo một file log mới để tiếp tục ghi dữ liệu log.
Ví dụ, khi một file log đã chứa đủ dữ liệu, hệ thống có thể đổi tên file này thành app.log.1
, sau đó tạo ra một file mới tên là app.log
để tiếp tục ghi log. Quy trình này giúp ngăn chặn việc các file log trở nên quá lớn, khó quản lý và khó phân tích.
Trong quá trình này, log agent
có khả năng phát hiện khi file log đã được xoay vòng và tiếp tục theo dõi các file mới để thu thập log một cách liên tục mà không bị gián đoạn.
Ưu điểm:
Đơn giản và hiệu quả
: Việc triển khai không đòi hỏi thay đổi code ứng dụng, chỉ cần cấu hình agent đúng đường dẫn file log.Tốn ít tài nguyên hệ thống
: do hoạt động độc lập với ứng dụng, phương pháp này tiêu tốn ít tài nguyên hệ thống và giảm thiểu rủi ro ảnh hưởng đến performance của ứng dụng chính.
Nhược điểm:
Gây ra độ trễ (latency)
: Việc thu thập log không thực sự real-time do phải chờ agent quét file theo chu kỳ, có thể gây ra độ trễ trong việc phát hiện vấn đề.Mất mát dữ liệu
: Khi file log bị hỏng hoặc disk bị đầy, việc thu thập log có thể bị gián đoạn và dẫn đến mất mát dữ liệu.
4.2. Direct Shipping (Gửi Log Trực tiếp)
- Model áp dụng: Push Model
Được thiết kế để gửi log trực tiếp từ ứng dụng đến collector thông qua các giao thức mạng như TCP/UDP mà không cần phải lưu log vào file hệ thống trước. Phương pháp này cho phép gửi log theo batch để tối ưu hiệu năng và giảm tải cho network. Với việc sử dụng các protocol đáng tin cậy, tính toàn vẹn của dữ liệu được đảm bảo tốt hơn.
Ưu điểm:
Logging theo thời gian thực
: giúp phát hiện và xử lý vấn đề nhanh chóng.Không phụ thuộc vào filesystem
: giúp tránh được các vấn đề liên quan đến disk space và file corruption.Kiểm xoát linh hoạt
: việc kiểm soát luồng log trở nên linh hoạt hơn với khả năng điều chỉnhbatch size
vàretry policy
.
Nhược điểm
Thay đổi code ứng dụng
: Phải tích hợp logging library, có thể gây khó khăn khi áp dụng cho các hệ thống legacy.Khó duy trì sự ổn định (stability)
: Khi lượng traffic tăng nhanh và việc xử lý lỗi trở nên phức tạp hơn, đặc biệt trong các tình huống network không ổn định hoặc collector bị quá tải.
4.3. Mô hình Sidecar (collector đi kèm với service)
- Model áp dụng: Kết hợp Pull và Push Model
- Collector chạy trong container/pod sẽ pull log từ file được ghi bởi ứng dụng.
- Collector sau đó có thể push log đến hệ thống lưu trữ (như Elasticsearch hoặc hệ thống lưu trữ đám mây).
Mỗi service được đi kèm với một collector riêng chạy cùng container/pod
. Collector này chia sẻ volume với service chính để đọc log, tạo nên một đơn vị triển khai độc lập và tự chủ. Pattern này kết hợp ưu điểm của cả file-based collection và direct shipping.
Ưu điểm:
- Tính
isolation cao
: mỗi service hoàn toàn độc lập về mặt logging, giúp việc scale và maintain trở nên dễ dàng hơn. Configuration có thể được tùy chỉnh riêng cho từng service mà không ảnh hưởng đến các service khác. Đây là một lợi thế lớn trong môi trường container hóa và Kubernetes.
Nhược điểm:
Tốn nhiều tài nguyên hệ thống
hơn do mỗi service cần một collector riêng.Tăng độ phức tạp khi vận hành
: do phải quản lý nhiều collector hơn, số lượng connection đến storage có thể trở thành vấn đề khi số lượng service tăng lên, đòi hỏi một layer trung gian để aggregation.
III. Kết luận
Xây dựng hệ thống log tập trung là một phần quan trọng khi chuyển đổi từ monolithic sang microservices. Việc lựa chọn kiến trúc phù hợp cần dựa trên nhiều yếu tố như khả năng của team, latency, budget... Quan trọng là hệ thống cần được thiết kế với khả năng mở rộng để dễ dàng nâng cấp khi nhu cầu tăng lên mà không phải thay đổi quá nhiều về mặt kiến trúc.
Ở phần sau mình sẽ đi tìm hiểu về các stack phổ biến, đưa ra cái nhìn khách quan nên chọn stack nào cho từng loại dự án và cách triển khai log với EFK stack
.
✏️ System Design VN: https://fb.com/groups/systemdesign.vn
📚 Đọc thêm tài liệu khác: https://roninhub.com/tai-lieu
🎬 Youtube: https://youtube.com/@ronin-engineer
All Rights Reserved