Quản lý Background Job bằng BullMQ & Redis: Cách tránh cạn kiệt bộ nhớ (OOM)
Bài toán xử lý tác vụ ngầm trong hệ thống Node.js Khi ứng dụng cần gửi hàng ngàn email, nén video hoặc đồng bộ hóa dữ liệu sang bên thứ ba, chúng ta không thể thực thi trực tiếp trong request HTTP vì…
☰ Mục lục bài viết (5 phần) Mở / Đóng mục lục
Bài toán xử lý tác vụ ngầm trong hệ thống Node.js#
Khi ứng dụng cần gửi hàng ngàn email, nén video hoặc đồng bộ hóa dữ liệu sang bên thứ ba, chúng ta không thể thực thi trực tiếp trong request HTTP vì sẽ làm treo server.
BullMQ (dựa trên Redis) là thư viện hàng đợi (Message Queue) được sử dụng phổ biến nhất trong hệ sinh thái Node.js/TypeScript nhờ độ tin cậy và tốc độ cao. Tuy nhiên nếu cấu hình không chuẩn, Redis của bạn sẽ nhanh chóng bị tràn RAM (Out Of Memory - OOM) sau vài ngày hoạt động.
Nguyên nhân số 1 gây tràn RAM trong BullMQ#
Mặc định, sau khi một job hoàn thành (completed) hoặc bị lỗi (failed), BullMQ sẽ lưu trữ toàn bộ dữ liệu payload và kết quả của job đó trong Redis để phục vụ việc xem lại lịch sử.
Nếu hệ thống xử lý 500.000 jobs mỗi ngày, mỗi job nặng 5KB, chỉ sau 1 tuần Redis sẽ ngốn thêm hàng chục GB bộ nhớ và sập hoàn toàn.
Cấu hình tự động dọn dẹp (Job Retention) chuẩn chỉ#
Luôn khai báo tùy chọn removeOnComplete và removeOnFail khi khởi tạo Worker hoặc thêm Job:
import { Queue, Worker } from 'bullmq';
const connection = { host: 'localhost', port: 6379 };
export const emailQueue = new Queue('email_notifications', {
connection,
defaultJobOptions: {
attempts: 3,
backoff: {
type: 'exponential',
delay: 2000, // Thử lại sau 2s, 4s, 8s nếu lỗi
},
// GIẢI PHÁP CHỐNG TRÀN BỘ NHỚ:
removeOnComplete: {
age: 3600 * 24, // Tự xóa sau 24 giờ
count: 1000, // Hoặc chỉ giữ tối đa 1.000 job gần nhất
},
removeOnFail: {
age: 3600 * 24 * 7, // Giữ job lỗi trong 7 ngày để dev điều tra
count: 5000,
}
}
});
3 nguyên tắc sống còn khi vận hành BullMQ#
- Không nhét File Binary hoặc Payload khổng lồ vào Job Data: Chỉ gửi ID (ví dụ:
orderId: 12345), sau đó Worker sẽ tự query database hoặc đọc từ S3. - Cấu hình
maxmemory-policytrên Redis: Đặt thànhnoevictionhoặcvolatile-lruđể tránh trường hợp Redis tự động xóa nhầm các key quan trọng của queue khi hết RAM. - Giám sát Dead Letter Queue: Thường xuyên kiểm tra danh sách các job bị fail vĩnh viễn để fix bug logic trong code của worker.
Góc thảo luận#
Team bạn đang dùng giải pháp nào cho background processing? BullMQ, RabbitMQ, Kafka hay AWS SQS?
Xem thêm nội dung liên quan:
Thảo luận
1 phản hồi
Tham gia thảo luận
Bài liên quan trong #Backend & Microservices
-
Áp dụng Model Context Protocol (MCP) của Anthropic để kết nối AI với Postgres và Docker
Hoàng Nam (Tech Lead) · 💬 1 -
So sánh mô hình Embedding đa ngữ: OpenAI text-embedding-3 vs BGE-M3 vs Cohere
Minh Trí (AI Engineer) · 💬 1 -
Xây dựng Voice AI Agent thời gian thực với WebRTC và Whisper Live: Độ trễ dưới 500ms
Lan Anh (Senior Frontend) · 💬 1 -
Cấu hình Rate Limiting ở tầng Nginx và API Gateway: Chống DDOS Layer 7 hiệu quả
Đức Huy (DevOps Specialist) · 💬 1 -
Tokenization tiếng Việt của các LLM: Tại sao chi phí tiếng Việt đắt gấp 3 lần tiếng Anh?
Minh Trí (AI Engineer) · 💬 1