Quay lại blog

Độ ổn định của thu thập dữ liệu quy mô lớn: những vấn đề chỉ lộ ra khi mở rộng

Một tác vụ có thể chạy ổn với mười mục tiêu nhưng giảm độ tin cậy khi tăng lên hàng nghìn. Phân loại lỗi và khử trùng lặp, giới hạn tốc độ và đồng thời, tiếp tục sau gián đoạn, lỗi đường ra mạng, kiểm tra nhất quán và vài chỉ số giám sát chính trở nên quan trọng ở quy mô lớn.

Một script thu thập dữ liệu có thể chạy trơn tru với mười mục tiêu nhưng bắt đầu giảm tỷ lệ thành công khi mở rộng lên hàng nghìn. Bạn đã thêm retry, đổi proxy, chỉnh concurrency, nhưng vấn đề vẫn lặp lại. Khi đào sâu hơn, nút thắt thường không nằm ở logic parsing mà ở vài lớp kỹ thuật chưa được xây dựng. Ở quy mô nhỏ, những vấn đề này có thể hoàn toàn không xuất hiện.

Phân loại lỗi trước để retry thực sự có ý nghĩa

Thu thập dữ liệu chắc chắn sẽ có lỗi. Điều quan trọng là phải phân loại: dao động mạng và reset kết nối có thể retry ngay; giới hạn tốc độ tạm thời cần backoff rồi mới retry; nếu cấu trúc trang thay đổi khiến kết quả parsing rỗng thì retry mười nghìn lần cũng vô ích, cần ghi nhận và cảnh báo; nếu mục tiêu vốn không tồn tại thì đánh dấu hoàn tất; nếu môi trường hoặc đường ra mạng không khởi động được thì đổi sang cái khác rồi thử lại.

Retry mọi lỗi giống nhau là một trong những sai lầm dễ mắc nhất. Nó che giấu các vấn đề cần con người can thiệp trong vòng lặp, đồng thời lãng phí quota và tài nguyên đường ra. Backoff cũng phải có: khoảng cách giữa các lần retry nên tăng dần, nếu không cả lô tác vụ sẽ quay lại cùng một cửa sổ thời gian và khiến rate limiting nặng hơn.

Retry dẫn trực tiếp đến bài toán khử trùng lặp. Một tác vụ có thể được chạy nhiều lần vì retry, nên mỗi tác vụ cần một định danh duy nhất và ổn định — chẳng hạn giá trị sau khi chuẩn hóa URL — và việc ghi dữ liệu phải idempotent theo định danh đó. Nếu không, càng retry nhiều thì dữ liệu bẩn càng nhiều.

Giới hạn tốc độ và concurrency là hai việc khác nhau

Tăng concurrency không đảm bảo throughput tăng theo. Có ba giới hạn cùng lúc tác động: trang đích chịu được bao nhiêu trước khi rate limiting làm giảm throughput tổng, bộ nhớ và CPU của máy cục bộ, và một môi trường hoặc session có thể chạy đồng thời nhiều tác vụ hay không.

Cách ổn định hơn là bắt đầu với concurrency thấp rồi tăng tải từng bước, đồng thời theo dõi tỷ lệ thành công và thời gian phản hồi để tìm điểm mà hiệu năng xấu đi rõ rệt. Giới hạn tốc độ là vấn đề khác: nó kiểm soát nhịp truy cập vào cùng một mục tiêu và không giống concurrency toàn cục. Khi một lô tác vụ phân tán trên nhiều site, mỗi site cần nhịp truy cập riêng.

Tiếp tục sau gián đoạn phụ thuộc vào trạng thái được lưu bền vững

Một tác vụ chạy vài giờ bị gián đoạn là chuyện bình thường; chạy lại từ đầu thường quá tốn kém. Điều kiện là trạng thái phải được lưu: chờ xử lý, đang xử lý, đã hoàn tất, cùng với số lần retry, thời điểm tiếp theo được phép chạy và loại lỗi. Khi process khởi động, hàng đợi phải được khôi phục từ storage thay vì dựng lại từ memory.

Chỉ duy trì hàng đợi trong memory là cách triển khai rất phổ biến vì trông có vẻ chạy được. Khi process chết, toàn bộ tác vụ đang xếp hàng biến mất và số liệu không còn đối chiếu được.

Xử lý riêng lỗi proxy và đường ra mạng

Đường ra bị mục tiêu chặn, proxy mất kết nối hoặc node khu vực bị trôi trạng thái sẽ xảy ra liên tục ở quy mô lớn. Đây không phải ngoại lệ mà là trạng thái bình thường. Hãy xem đường ra như tài nguyên có thể thay thế: khi tác vụ lỗi, trước tiên xác định đó là rate limiting từ mục tiêu hay đường ra không dùng được; trường hợp đầu thì backoff, trường hợp sau thì đổi đường ra và retry. Đồng thời ghi lại tỷ lệ lỗi của từng đường ra và loại bỏ các nhóm có dấu hiệu suy giảm rõ rệt.

Ngược lại, nếu mọi tác vụ dùng chung một đường ra, một tác vụ có thể làm hỏng đường truyền và ảnh hưởng toàn bộ phần còn lại. Khi điều tra, bạn còn phải lần ngược log để tìm tác vụ nào đã gây ra vấn đề.

Kiểm tra tính nhất quán của dữ liệu

Chạy xong không đồng nghĩa dữ liệu đúng. Sau khi ghi vào kho dữ liệu, cần trả lời được vài câu hỏi: số tác vụ hoàn tất có khớp với số dòng đã ghi không, tỷ lệ kết quả parsing rỗng là bao nhiêu, tỷ lệ thiếu trường quan trọng có tăng bất thường không, và có bao nhiêu dòng trùng lặp?

Các kiểm tra này không cần phức tạp. Lấy mẫu theo từng lô là đủ, nhưng phải có người xem kết quả. Ở quy mô lớn, dữ liệu sai có thể phiền phức hơn không có dữ liệu.

Nên theo dõi những chỉ số nào

Không cần tham quá nhiều chỉ số. Một vài chỉ số phản ánh sức khỏe hệ thống là đủ.

  • Tỷ lệ thành công và phân bố loại lỗi, để biết loại lỗi nào đang tăng
  • Độ dài hàng đợi và thời gian chờ trung bình; backlog tăng liên tục cho thấy đầu vào và năng lực xử lý không cân bằng
  • Số môi trường đang hoạt động và số process liên quan; tăng một chiều trong thời gian dài thường cho thấy rò rỉ ở khâu thu hồi tài nguyên
  • Sản lượng trên một đơn vị thời gian, để đánh giá throughput có bị rate limiting kìm lại hay không
  • Tỷ lệ lỗi của đường ra, để quyết định có nên thay một nhóm node hay không

Nếu chỉ một trong các chỉ số này biến động một chiều trong thời gian dài, hãy kiểm tra logic thu hồi tài nguyên và retry trước.

Tách riêng lớp môi trường

Nhìn tổng thể, các vấn đề trên dẫn đến cùng một kết luận: lớp môi trường phải được quản lý độc lập với script. Pooling môi trường đòi hỏi môi trường được điều phối tập trung thay vì nằm rải rác trong từng script; thu hồi tài nguyên đòi hỏi trạng thái có thể truy vấn thay vì để script tự xử lý; retry bằng môi trường khác hoặc đường ra khác chỉ khả thi khi môi trường có thể được điều phối độc lập.

Script chỉ phụ trách logic; lớp môi trường quản lý tài nguyên và danh tính. Trong kiến trúc kiểu này, PurpleMark đảm nhiệm lớp đó bằng cách cung cấp tài nguyên môi trường có thể tạo theo lô, gắn với đường ra mạng độc lập và truy vấn trạng thái.

Ranh giới tuân thủ

Khả năng mở rộng không có nghĩa là có thể thu thập dữ liệu tùy ý. Hãy tuân thủ quy tắc robots và điều khoản dịch vụ của site đích, không thu thập thông tin cá nhân, không vượt qua các biện pháp bảo vệ kỹ thuật và kiểm soát tần suất request để không ảnh hưởng hoạt động bình thường của dịch vụ. Độ ổn định là một vấn đề kỹ thuật; việc có được phép thu thập hay không là vấn đề khác. Cả hai đều phải đáp ứng.