Hướng dẫn chi tiết scale n8n: Từ VPS đơn lẻ đến hệ thống chịu tải cao

Viewed 1

Hướng dẫn chi tiết scale n8n

Chia sẻ bởi Mì AI

n8n là một công cụ tự động hóa quy trình (automation workflow) cực kỳ mạnh mẽ và linh hoạt. Với giao diện kéo thả trực quan, chúng ta có thể dễ dàng xây dựng những luồng công việc phức tạp mà không cần viết quá nhiều code. Tuy nhiên, khi ứng dụng của bạn phát triển và khối lượng công việc tăng lên, một vấn đề cố hữu sẽ xuất hiện: quá tải.

Một hệ thống n8n cài đặt trên một VPS duy nhất có thể xử lý tốt vài chục, thậm chí vài trăm tác vụ mỗi ngày. Nhưng điều gì sẽ xảy ra khi bạn nhận hàng ngàn yêu cầu cùng lúc, ví dụ như từ một webhook bán hàng trong đợt khuyến mãi lớn? Rất có thể VPS của bạn sẽ bị treo, các tác vụ bị dồn ứ và toàn bộ hệ thống sẽ ngừng hoạt động.

Trong bài viết này, tôi sẽ chia sẻ một kinh nghiệm thực tế về cách "scale n8n" – nâng cấp kiến trúc hệ thống để nó có thể xử lý khối lượng công việc lớn một cách ổn định và hiệu quả, biến n8n từ một công cụ cá nhân trở thành một giải pháp đáng tin cậy cho môi trường production.

Tại sao n8n của bạn bị quá tải? Hiểu rõ giới hạn của mô hình mặc định

Trước khi đi vào giải pháp, chúng ta cần hiểu rõ gốc rễ của vấn đề. Hầu hết chúng ta khi bắt đầu với n8n đều theo một quy trình chung:

  1. Thuê một máy chủ ảo (VPS).
  2. Cài đặt Docker.
  3. Chạy một container n8n duy nhất.

Mô hình này cực kỳ đơn giản và hiệu quả cho các tác vụ nhỏ lẻ. Tuy nhiên, nó có những nhược điểm chí mạng khi cần xử lý tải cao:

  • Một điểm thất bại duy nhất (Single Point of Failure): Toàn bộ gánh nặng xử lý – từ việc nhận yêu cầu webhook, thực thi logic workflow, đến ghi dữ liệu – đều dồn lên một container duy nhất trên một VPS duy nhất. Nếu VPS này gặp sự cố hoặc quá tải, toàn bộ hệ thống của bạn sẽ sụp đổ.
  • Xử lý tuần tự và giới hạn tài nguyên: Khi 1000 yêu cầu webhook đổ về cùng lúc, n8n trên một máy sẽ cố gắng xử lý chúng. CPU và RAM sẽ nhanh chóng đạt đến ngưỡng 100%, gây ra tình trạng treo máy. Các yêu cầu đến sau sẽ bị từ chối hoặc phải chờ rất lâu.
  • Lưu trữ dữ liệu cục bộ: Mặc định, n8n sử dụng cơ sở dữ liệu SQLite để lưu trữ toàn bộ thông tin về workflow, credentials, và lịch sử thực thi. SQLite là một file database nằm ngay trên VPS. Điều này khiến việc mở rộng sang nhiều máy chủ là bất khả thi, vì các máy chủ khác không thể truy cập vào file dữ liệu này.

Chính những hạn chế này khiến mô hình mặc định không phù hợp cho các ứng dụng nghiêm túc, đòi hỏi độ sẵn sàng và khả năng chịu tải cao.

Giới thiệu mô hình scale n8n với Main-Worker, Redis và PostgreSQL

Để giải quyết triệt để vấn đề, chúng ta cần chuyển đổi sang một kiến trúc phân tán. Thay vì một cỗ máy làm tất cả mọi việc, chúng ta sẽ phân chia công việc cho một đội ngũ chuyên biệt. Mô hình này bao gồm bốn thành phần chính:

Sơ đồ kiến trúc bao gồm một Main Node nhận yêu cầu, một hàng đợi Redis ở giữa, một cơ sở dữ liệu PostgreSQL dùng chung, và nhiều Worker Node kết nối vào Redis và PostgreSQL để lấy và thực thi công việc.

Vai trò của từng thành phần trong hệ thống

  • Main Node (Node Chính):

    • Vai trò: Giống như một người "lễ tân" hoặc "điều phối viên". Node này có giao diện người dùng (UI) để bạn thiết kế và quản lý các workflow. Nhiệm vụ chính của nó là tiếp nhận các yêu cầu (ví dụ từ webhook hoặc trigger) và đẩy chúng vào một hàng đợi (queue) chứ không trực tiếp thực thi các tác vụ nặng.
    • Lợi ích: Vì không phải xử lý các tác vụ nặng, Main Node luôn nhẹ nhàng, phản hồi nhanh và hiếm khi bị quá tải.
  • Worker Nodes (Các Node Công Nhân):

    • Vai trò: Đây là những "công nhân" chăm chỉ thực hiện công việc. Chúng không có giao diện người dùng mà chỉ liên tục lắng nghe hàng đợi. Khi có một tác vụ mới trong hàng đợi, một Worker Node sẽ "bốc" tác vụ đó về và thực thi.
    • Lợi ích: Bạn có thể có nhiều Worker Node chạy song song. Khi có 1000 yêu cầu, chúng sẽ được phân bổ đều cho các worker xử lý đồng thời. Nếu cần thêm sức mạnh, bạn chỉ việc "thuê thêm công nhân" – tức là khởi chạy thêm các Worker Node. Quá trình này gọi là scale ngang (horizontal scaling).
  • Redis (Hàng đợi tác vụ):

    • Vai trò: Là "bảng phân công công việc" chung. Redis là một cơ sở dữ liệu trong bộ nhớ (in-memory database) cực nhanh, hoạt động như một hàng đợi tin nhắn (message queue). Main Node đẩy tác vụ vào Redis, và các Worker Node lấy tác vụ từ Redis.
    • Lợi ích: Redis đóng vai trò trung gian, tách biệt hoàn toàn Main Node và Worker Nodes. Nó đảm bảo không có tác vụ nào bị bỏ lỡ và giúp phân phối công việc một cách hiệu quả.
  • PostgreSQL (Cơ sở dữ liệu trung tâm):

    • Vai trò: Là "bộ não" chung của toàn hệ thống. Thay vì dùng SQLite cục bộ, tất cả các node (cả Main và Worker) đều kết nối đến một cơ sở dữ liệu PostgreSQL duy nhất. Đây là nơi lưu trữ toàn bộ thông tin về workflows, credentials, kết nối,...
    • Lợi ích: Khi một Worker Node nhận nhiệm vụ "chạy workflow A", nó sẽ truy vấn vào PostgreSQL để lấy định nghĩa của workflow A và các credentials cần thiết. Điều này đảm bảo tất cả các node đều có quyền truy cập vào cùng một nguồn thông tin nhất quán.

Với kiến trúc này, hệ thống n8n của bạn trở nên linh hoạt, mạnh mẽ và có khả năng chịu tải vượt trội so với mô hình đơn lẻ.

Hướng dẫn cấu hình chi tiết để scale n8n từng bước một

Bây giờ, chúng ta sẽ đi vào phần thực hành. Để đơn giản hóa, tôi sẽ hướng dẫn cài đặt tất cả các thành phần trên cùng một VPS. Trong môi trường production thực tế, bạn nên tách Redis và PostgreSQL ra các máy chủ riêng để tối ưu hiệu năng và độ tin cậy.

Chuẩn bị môi trường cần thiết

  • Một VPS (Ubuntu được khuyến nghị) với Docker và Docker Compose đã được cài đặt.
  • Quyền truy cập SSH vào VPS.

Đầu tiên, hãy tạo các thư mục để lưu trữ dữ liệu:

mkdir ~/n8n-data
mkdir ~/postgres-data

Bước 1: Khởi tạo n8n Main và lấy Encryption Key

Mọi node trong hệ thống n8n phân tán cần một "mật khẩu" chung để mã hóa và giải mã dữ liệu nhạy cảm (như credentials). Mật khẩu này gọi là Encryption Key. Chúng ta sẽ khởi tạo một instance n8n tạm thời để lấy key này.

Tạo file docker-compose.yml với nội dung sau:

version: '3.7'

services:
  n8n_initial:
    image: n8nio/n8n:latest
    container_name: n8n_initial
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    volumes:
      - ~/n8n-data:/home/node/.n8n

Chạy container:

docker-compose up -d

Sau khi container khởi động, chạy lệnh sau để lấy key:

docker exec n8n_initial n8n export:encryption-key

Lệnh này sẽ trả về một key dài. Hãy sao chép và lưu lại key này một cách an toàn. Đây là thông tin cực kỳ quan trọng.

Sau khi đã có key, hãy dừng và xóa container tạm thời này đi:

docker-compose down

Bước 2: Cấu hình Main Node với Redis và PostgreSQL

Bây giờ chúng ta sẽ tạo file cấu hình hoàn chỉnh cho Main Node và các dịch vụ phụ thuộc. Tạo file docker-compose.main.yml:

version: '3.7'

services:
  postgres:
    image: postgres:14
    container_name: n8n_postgres
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=your_strong_password # <-- Thay bằng mật khẩu của bạn
      - POSTGRES_DB=n8n
    volumes:
      - ~/postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 5s
      timeout: 5s
      retries: 10

  redis:
    image: redis:6.2-alpine
    container_name: n8n_redis
    restart: always
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 5s
      retries: 10

  n8n-main:
    image: n8nio/n8n:latest
    container_name: n8n_main
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_ENCRYPTION_KEY=YOUR_ENCRYPTION_KEY_HERE # <-- Dán key của bạn vào đây
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=your_strong_password # <-- Mật khẩu bạn đã đặt ở trên
      - EXECUTIONS_MODE=queue # <-- Chế độ quan trọng nhất
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
    volumes:
      - ~/n8n-data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

Giải thích các thông số quan trọng:

  • N8N_ENCRYPTION_KEY: Sử dụng key bạn đã lấy ở bước 1.
  • DB_TYPE=postgresdb: Chỉ định n8n sử dụng PostgreSQL thay vì SQLite.
  • EXECUTIONS_MODE=queue: Đây là "công tắc" chuyển n8n sang chế độ Main Node. Nó sẽ đẩy tác vụ vào hàng đợi thay vì tự thực thi.
  • QUEUE_BULL_REDIS_HOST=redis: Cấu hình để n8n kết nối đến dịch vụ Redis.

Khởi chạy hệ thống Main Node:

docker-compose -f docker-compose.main.yml up -d

Lúc này, bạn có thể truy cập n8n qua địa chỉ http://<IP_CUA_BAN>:5678 và bắt đầu tạo workflow như bình thường.

Bước 3: Triển khai các Worker Node

Bây giờ là lúc "thuê thêm công nhân". Chúng ta sẽ tạo một file cấu hình riêng cho các worker. Tạo file docker-compose.worker.yml:

version: '3.7'

services:
  n8n-worker:
    image: n8nio/n8n:latest
    # Tên container nên là duy nhất cho mỗi worker
    # container_name: n8n_worker_1 
    restart: always
    command: worker # <-- Chạy container ở chế độ worker
    environment:
      - N8N_ENCRYPTION_KEY=YOUR_ENCRYPTION_KEY_HERE # <-- Dùng CÙNG MỘT key
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=<IP_CUA_MAY_CHU_MAIN> # <-- IP của máy chủ chạy Main Node
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=your_strong_password # <-- Cùng mật khẩu DB
      - EXECUTIONS_MODE=queue 
      - QUEUE_BULL_REDIS_HOST=<IP_CUA_MAY_CHU_MAIN> # <-- IP của máy chủ chạy Main Node
      - QUEUE_BULL_REDIS_PORT=6379
    volumes:
      - ~/n8n-data:/home/node/.n8n # Worker vẫn cần truy cập một số file cấu hình chung

Giải thích các thông số quan trọng:

  • command: worker: Chỉ định container này sẽ chạy với vai trò là một Worker Node.
  • DB_POSTGRESDB_HOSTQUEUE_BULL_REDIS_HOST: Phải trỏ đến địa chỉ IP của máy chủ đang chạy Main Node, PostgreSQL và Redis. Nếu bạn cài worker trên máy khác, hãy thay bằng IP tương ứng.
  • Không có ports: Worker không cần mở port ra ngoài vì chúng không có giao diện người dùng.

Để khởi chạy nhiều worker, bạn có thể dùng lệnh scale của Docker Compose:

docker-compose -f docker-compose.worker.yml up -d --scale n8n-worker=4

Lệnh này sẽ tạo ra 4 container worker chạy song song.

Kiểm tra kết quả và những lưu ý khi vận hành

Bây giờ, hãy quay lại giao diện của Main Node, mở một workflow bất kỳ và thực thi nó. Nếu bạn theo dõi log của các container worker (docker logs <ten_container_worker> -f), bạn sẽ thấy các tác vụ được phân phối và thực thi trên các worker khác nhau. Main Node sẽ không còn phải gánh vác việc xử lý nữa.

Những bước cần làm tiếp theo:

  • Bảo mật: Đảm bảo Redis và PostgreSQL của bạn được bảo vệ bằng mật khẩu mạnh và chỉ cho phép truy cập từ các IP của Main/Worker Node.
  • High Availability (HA): Trong môi trường production, bạn nên xem xét thiết lập cụm (cluster) cho Redis và PostgreSQL để tránh có điểm thất bại duy nhất.
  • Tự động hóa: Sử dụng các công cụ như Kubernetes (K8s) có thể giúp bạn tự động hóa việc scale các worker lên hoặc xuống dựa trên tải thực tế, giúp tối ưu chi phí và hiệu năng.

Kết luận

Việc chuyển đổi từ một n8n đơn lẻ sang kiến trúc Main-Worker là một bước tiến quan trọng để xây dựng một hệ thống tự động hóa mạnh mẽ, đáng tin cậy và sẵn sàng cho production. Mặc dù quá trình cài đặt ban đầu có vẻ phức tạp hơn, nhưng lợi ích về khả năng chịu tải, tính ổn định và khả năng mở rộng mà nó mang lại là vô cùng to lớn.

Hy vọng rằng những chia sẻ từ kinh nghiệm thực tế này sẽ giúp bạn tự tin hơn trong việc scale n8n và khai thác tối đa tiềm năng của công cụ tuyệt vời này.

0 Answers