Ngiêm cấm sử đụng PROXY và VPS vào mục đích trái pháp luật bạn sẽ phải chịu toàn bộ trách nhiệm trước pháp luật khi sử dụng dịch vụ của chúng tôi tks!
Luigi pipeline crawl có target: xóa output để chạy lại

Luigi pipeline crawl có target: xóa output để chạy lại đúng phần

Chuyên viên Kỹ thuật ProxyVN 02-24-2026 Đang tính... phút đọc

Luigi pipeline crawl có target là cách dựng pipeline crawl trong đó mỗi công đoạn khai báo tệp đầu ra của nó, và Luigi chỉ chạy công đoạn nào chưa có tệp đó. Muốn chạy lại một bước, chỉ cần xóa tệp đầu ra của bước đó. Nghe đơn giản, nhưng thứ tự kiểm của Luigi có vài chỗ làm người dùng bất ngờ. ProxyVN chạy Luigi 3.8.1 ngày 03/11/2026 với ba công đoạn tải, phân tích và xuất, xóa từng tệp theo nhiều cách, cho một công đoạn sập giữa chừng, rồi ghi lại Luigi chạy lại những gì. Bài ghi rõ kết quả từng ca.

Luigi pipeline crawl có target: mục tiêu và phạm vi không lặp

Phần này chốt bài toán, đầu ra và ranh giới.

Bài toán

Một pipeline crawl chạy mỗi ngày: tải HTML, trích giá, xuất CSV. Khi bước trích giá có lỗi, người vận hành muốn sửa rồi chạy lại từ bước đó, không tải lại trang. Khi máy sập giữa chừng, họ muốn chạy lại và để công cụ tự biết bước nào đã xong, bước nào chưa.

Đầu ra nghiệm thu

Đầu ra là pipeline ba công đoạn dùng tệp làm target, kèm bảng kết quả khi xóa từng tệp đầu ra. Bảng phải cho biết với mỗi cách xóa, Luigi chạy lại công đoạn nào. Có thêm ca công đoạn sập giữa chừng để kiểm xem tệp dở dang có bị coi là hoàn tất không.

Ranh giới với checkpoint của Scrapy và asset của Dagster

Scrapy có cơ chế lưu trạng thái để tiếp tục một lần crawl bị ngắt, ở mức từng request. Dagster ghi lịch sử materialization trong cơ sở dữ liệu. Luigi không lưu trạng thái riêng nào: nó nhìn vào tệp đầu ra. Có tệp nghĩa là xong. Bài tập trung vào hệ quả của quy tắc đó.

Phiên bản đã khóa

Lab dùng luigi 3.8.1, Python 3.12 trên Windows, chạy với bộ lập lịch cục bộ local_scheduler. Không có máy chủ luigid. Mọi ca chạy trong một tiến trình, gọi luigi.build lần lượt. Dữ liệu trang là chuỗi HTML sinh sẵn, không tải từ web.

Ai nên đọc

Người đang chạy pipeline crawl bằng Luigi và từng gặp cảnh xóa tệp mà công đoạn không chạy lại. Người duy trì pipeline cũ dùng Luigi và cần hiểu vì sao dữ liệu hỏng không được dựng lại. Người đang chọn công cụ điều phối và muốn biết mô hình dựa trên tệp có ưu nhược gì.

Mô hình dựa trên tệp có gì khó

Trạng thái nằm ở hệ thống tệp, nên mọi thứ làm thay đổi tệp đều thay đổi trạng thái: một người xóa nhầm, một tập lệnh dọn dẹp chạy sai thư mục, một tệp bị chép đè từ máy khác. Luigi không có nhật ký nào để biết ai đã làm gì. Muốn có lịch sử, phải tự ghi bên ngoài Luigi.

Mô hình dựa trên tệp có gì hay

Không cần cơ sở dữ liệu để lưu trạng thái. Nhìn thư mục là biết công đoạn nào đã xong. Chép thư mục sang máy khác là chép luôn trạng thái. Với pipeline crawl ghi ra tệp theo ngày, mô hình này khớp tự nhiên. Cái giá là phải hiểu đúng Luigi kiểm tệp theo thứ tự nào.

Dùng target/complete của Luigi để chỉ chạy công đoạn còn thiếu với Luigi pipeline crawl có target

Trước khi viết mã, cần nắm ba phương thức của một task Luigi.

requires, output và run

Theo trang Tasks trong tài liệu Luigi, một task khai báo requires để nói nó cần task nào trước, output để nói nó tạo ra target nào, và run để làm việc thật. Luigi gọi run của các task cần trước, rồi mới gọi run của task hiện tại.

complete quyết định có chạy hay không

Mỗi task có phương thức complete. Mặc định, complete trả về đúng khi mọi target trong output đều tồn tại. Luigi chỉ gọi run khi complete trả về sai. Đây là toàn bộ cơ chế quyết định chạy lại.

Luigi kiểm từ đích về gốc

Kiểm từ đích về gốc

Kiểm từ đích về gốc

Khi được yêu cầu chạy task cuối, Luigi kiểm complete của task cuối trước. Nếu task cuối đã hoàn tất, Luigi dừng ở đó, không kiểm các task phía trước. Chỉ khi task cuối chưa hoàn tất, Luigi mới đi ngược lên kiểm requires.

Hành vi này hợp lý khi nhìn từ góc độ hiệu năng: không cần kiểm cả cây nếu đích đã có. Nhưng nó dẫn tới một ca bất ngờ mà lab sẽ cho thấy.

Target không chỉ là tệp cục bộ

Luigi có nhiều loại target: tệp cục bộ, tệp trên kho đối tượng, bảng trong cơ sở dữ liệu. Mọi loại đều có phương thức exists. Lab chỉ dùng LocalTarget, nhưng quy tắc kiểm từ đích về gốc và cách complete hoạt động là chung cho mọi loại. Với target là bảng cơ sở dữ liệu, tồn tại thường nghĩa là có một dòng đánh dấu trong bảng nhật ký.

LocalTarget

LocalTarget là target trỏ tới một tệp trên đĩa. Phương thức exists kiểm tệp có tồn tại không. Phương thức open mở tệp để đọc hoặc ghi. Khi mở để ghi, LocalTarget ghi vào tệp tạm, rồi đổi tên thành tệp thật khi đóng thành công.

Task là lớp, tham số là danh tính

Hai đối tượng Parse cùng tham số day được Luigi coi là cùng một task. Luigi dùng tên lớp và giá trị tham số để nhận diện, không dùng địa chỉ bộ nhớ. Nhờ vậy, Export và một lệnh gọi riêng đều có thể yêu cầu Parse của cùng ngày, và Luigi chỉ chạy nó một lần.

Tham số ngày

Mỗi task trong lab có tham số day. Đường dẫn target chứa ngày, nên mỗi ngày có bộ tệp riêng. Chạy pipeline cho ngày mới không đụng tệp của ngày cũ. Đây là cách dùng Luigi phổ biến nhất cho dữ liệu crawl hằng ngày.

Định nghĩa requires, output Target và complete cho từng task trong Luigi pipeline crawl có target

Phần này trình bày mã của ba task.

Task tải

class Fetch(luigi.Task):
    day = luigi.Parameter()
    def output(self):
        return luigi.LocalTarget(f"data/{self.day}/raw.json")
    def run(self):
        pages = tai_trang()
        with self.output().open("w") as f:
            json.dump(pages, f)

Fetch không cần task nào trước. Trong lab, tai_trang trả về năm trang HTML sinh sẵn. Thực tế, đây là chỗ gọi mạng.

Task phân tích

class Parse(luigi.Task):
    day = luigi.Parameter()
    def requires(self):
        return Fetch(self.day)
    def output(self):
        return luigi.LocalTarget(f"data/{self.day}/parsed.json")
    def run(self):
        pages = json.load(self.input().open())
        rows = [trich_gia(u, h) for u, h in pages.items()]
        with self.output().open("w") as f:
            json.dump(rows, f)

self.input() trả về output của task trong requires, tức raw.json. Parse đọc tệp đó, trích giá, ghi parsed.json.

Vì sao không trả dữ liệu qua bộ nhớ

Các task trao đổi dữ liệu qua tệp, không qua biến trong bộ nhớ. Điều này làm mã dài hơn một chút, vì mỗi task phải tự đọc và ghi tệp. Bù lại, mỗi bước có thể chạy riêng, ở tiến trình riêng, thậm chí ở máy riêng, miễn là đọc được tệp của bước trước. Đây là điều kiện để chạy lại từng phần.

Task xuất

Export cần Parse, đọc parsed.json, ghi gia.csv với hai cột url và price. Cấu trúc giống hai task trên. Chạy Export là đủ để Luigi kéo theo cả Parse và Fetch nếu cần.

Trích giá trong lab

Hàm trích giá trong lab cắt chuỗi giữa dấu lớn hơn và dấu nhỏ hơn rồi đổi sang số nguyên. Cách này chỉ đủ cho HTML sinh sẵn. Với trang thật, nên dùng thư viện phân tích HTML. Bài không bàn chuyện trích giá, vì trọng tâm là Luigi quyết định chạy lại thế nào, không phải parser viết ra sao.

Đếm số lần chạy

Mỗi phương thức run tăng một bộ đếm theo tên task. Sau mỗi lần gọi luigi.build, lab in bộ đếm để biết chính xác task nào đã chạy. Không dựa vào log của Luigi, vốn khá dài và khó lọc.

Tên task trong log

Luigi đặt tên task theo tên lớp kèm tham số, ví dụ Parse với day bằng 2026-11-03. Tên này hiện trong log và trong tóm tắt cuối lần chạy. Với nhiều ngày chạy cùng lúc, tên kèm tham số giúp biết task của ngày nào đang lỗi. Đặt tham số có ý nghĩa thay vì số thứ tự là thói quen tốt.

Lệnh chạy

ok = luigi.build([Export("2026-11-03")], local_scheduler=True,
                 detailed_summary=True, log_level="WARNING")
print(ok.status.name)

detailed_summary bằng True trả về đối tượng có trạng thái tổng của lần chạy. local_scheduler bằng True dùng bộ lập lịch trong tiến trình, không cần máy chủ.

Chạy pipeline khi một số target đã có với Luigi pipeline crawl có target

Phần này chạy hai ca đầu tiên.

Trạng thái tổng của lần chạy

Đối tượng trả về từ luigi.build có thuộc tính status. Lab in tên trạng thái sau mỗi ca. SUCCESS khi không có task nào lỗi, FAILED khi có task lỗi. Đây là con số nên dùng để quyết định có gửi cảnh báo hay không.

Lần chạy đầu

Thư mục data trống. Luigi chạy Fetch, Parse, Export, mỗi task một lần. Trạng thái SUCCESS. Thư mục ngày 2026-11-03 có ba tệp raw.json, parsed.json, gia.csv.

Chạy lại khi mọi tệp đã có

Gọi lại luigi.build với cùng task. Không task nào chạy, trạng thái vẫn SUCCESS. Luigi kiểm Export.complete, thấy gia.csv tồn tại, dừng ngay. Đây là hành vi mong đợi: pipeline chạy lại an toàn, không làm gì thừa.

Ý nghĩa với lịch chạy

Có thể đặt lịch chạy pipeline mỗi giờ thay vì mỗi ngày. Những lần chạy sau lần thành công đầu tiên của một ngày sẽ không làm gì. Nếu lần chạy đầu lỗi, lần chạy sau tự làm tiếp phần còn thiếu. Không cần ai theo dõi để chạy lại bằng tay.

SUCCESS không có nghĩa là đã chạy

Trạng thái SUCCESS ở lần chạy thứ hai chỉ có nghĩa là không có gì lỗi. Nó không cho biết có task nào chạy hay không. Muốn biết, phải đọc tóm tắt chi tiết hoặc tự đếm như lab. Báo cáo chỉ dựa vào SUCCESS có thể che giấu việc pipeline không làm gì cả trong nhiều ngày.

Chạy nhiều ngày một lúc

Truyền danh sách nhiều task Export với các ngày khác nhau vào luigi.build, Luigi tự xử lý từng ngày. Ngày nào đã đủ tệp thì bỏ qua, ngày nào thiếu thì chạy phần thiếu. Đây là cách chạy bù sau khi pipeline ngừng vài ngày. Lab chỉ chạy một ngày, nhưng quy tắc không đổi khi có nhiều ngày.

Tệp đầu vào thay đổi không làm chạy lại

Luigi không so nội dung hay thời gian sửa đổi của tệp. Nếu ai đó sửa raw.json bằng tay sau khi parsed.json đã có, Luigi không biết. Parse không chạy lại. Đây là khác biệt lớn với các công cụ dựa vào dấu thời gian như make.

Xóa một output fixture rồi quan sát task được tính lại trong Luigi pipeline crawl có target

Phần này là trọng tâm: xóa từng tệp và xem Luigi chạy lại gì.

Xóa tệp giữa khi tệp cuối còn

Lab xóa parsed.json, giữ gia.csv và raw.json. Gọi luigi.build với Export. Không task nào chạy. parsed.json vẫn không tồn tại sau lần chạy.

Lý do là Luigi kiểm Export trước, thấy gia.csv còn, coi pipeline đã xong, không đi ngược lên. Việc parsed.json mất không được phát hiện. Đây là ca dễ làm người vận hành bối rối nhất: họ xóa tệp để chạy lại bước phân tích, nhưng không gì xảy ra.

Xóa tệp cuối

Tiếp theo, lab xóa gia.csv. Lúc này parsed.json đã mất từ ca trước. Luigi thấy Export chưa xong, đi ngược lên, thấy Parse chưa xong, đi tiếp, thấy Fetch đã xong. Kết quả: Parse chạy một lần, Export chạy một lần, Fetch không chạy.

Ca 4 phụ thuộc ca 3

Ca 4 chạy cả Parse lẫn Export vì parsed.json đã mất từ ca 3. Nếu parsed.json còn, xóa gia.csv chỉ làm Export chạy. Thứ tự các ca trong lab được giữ nguyên để thấy rằng ca 3 đã để lại một lỗ hổng mà không ai biết, cho tới khi tệp cuối cũng bị xóa.

Xóa cả hai

Lab xóa cả parsed.json và gia.csv. Kết quả giống ca trước: Parse và Export chạy, Fetch không chạy. Đây là cách đúng để chạy lại từ bước phân tích: xóa đầu ra của bước đó và của mọi bước phía sau.

Bảng kết quả xóa tệp

Bảng xóa tệp

Bảng xóa tệp

Bảng: Bảng kết quả xóa tệp

Ca

Tệp bị xóa

Tệp còn

Task chạy

1

thư mục trống

không

Fetch, Parse, Export

2

không

cả ba

không task nào

3

parsed.json

raw.json, gia.csv

không task nào

4

gia.csv (parsed.json đã mất)

raw.json

Parse, Export

5

parsed.json, gia.csv

raw.json

Parse, Export

Quy tắc rút ra

Muốn chạy lại một bước, xóa đầu ra của bước đó cùng mọi bước phụ thuộc vào nó. Chỉ xóa đầu ra của bước giữa là không đủ. Với pipeline nhiều bước, nên có tập lệnh nhỏ nhận tên bước và tự xóa các tệp phía sau, thay vì xóa bằng tay.

Vì sao Luigi chọn kiểm từ đích

Nếu Luigi kiểm từ gốc, mỗi lần chạy phải kiểm mọi task trong cây, kể cả những task từ nhiều ngày trước. Với cây lớn, việc này tốn thời gian, nhất là khi target nằm trên mạng. Kiểm từ đích cho phép dừng sớm. Đổi lại, người dùng phải chấp nhận rằng đích còn thì phía trước không được xem xét.

Chạy trực tiếp task giữa

Một cách khác là gọi luigi.build với Parse thay vì Export. Luigi kiểm Parse.complete, thấy parsed.json mất, chạy Parse. Nhưng gia.csv cũ vẫn còn và không được cập nhật. Cách này chỉ đúng khi bạn biết gia.csv cũng cần dựng lại và sẽ xóa nó sau.

Fetch được giữ lại

Ở mọi ca từ 2 tới 5, Fetch không chạy lại vì raw.json còn. Đây là lợi ích chính của mô hình: sửa parser không phải tải lại trang. Với crawl vài nghìn URL, điều này tiết kiệm nhiều giờ và giảm tải cho website nguồn.

Kiểm output dở dang và điều kiện được coi là hoàn tất trong Luigi pipeline crawl có target

Phần này thử hai cách một task có thể để lại tệp dở dang, và cách viết complete chặt hơn.

Parse sập giữa chừng khi dùng LocalTarget.open

Lab xóa parsed.json và gia.csv, rồi bật cờ làm Parse ném lỗi sau khi đã ghi dòng đầu tiên. Luigi báo FAILED. Kiểm thư mục: parsed.json không tồn tại. Có một tệp tên parsed.json-luigi-tmp kèm dãy số.

LocalTarget.open ghi vào tệp tạm. Khi khối with thoát vì lỗi, tệp tạm không được đổi tên. Tệp thật không xuất hiện, nên lần chạy sau Parse vẫn được coi là chưa xong. Đây là hành vi đúng.

Ghi nguyên tử nghĩa là gì

Ghi nguyên tử nghĩa là người khác chỉ thấy hoặc không có tệp, hoặc có tệp đầy đủ, không bao giờ thấy tệp đang ghi dở. LocalTarget làm điều này bằng cách ghi vào tệp tạm cùng thư mục rồi đổi tên. Trên cùng một ổ đĩa, đổi tên là thao tác gần như tức thời, nên không có lúc nào tệp đích ở trạng thái nửa vời.

Tệp tạm bị bỏ lại

Tệp tạm không bị xóa sau khi lỗi. Với pipeline chạy lâu, các tệp tạm tích tụ trong thư mục dữ liệu. Chúng không ảnh hưởng tới logic của Luigi, nhưng chiếm chỗ và gây nhiễu khi đọc thư mục. Nên có bước dọn định kỳ các tệp có đuôi luigi-tmp.

Task ghi tệp bằng open thường

Biến thể ParseNaive ghi thẳng vào đường dẫn target bằng hàm open của Python, rồi sập sau khi ghi một phần. Luigi báo FAILED. Nhưng parsed_naive.json tồn tại, chứa đúng một đoạn JSON dở dang.

Lần chạy sau coi tệp dở là xong

Tệp dở bị coi là xong

Tệp dở bị coi là xong

Lab tắt cờ lỗi, chạy lại ParseNaive. Không task nào chạy. Tệp dở dang tồn tại, nên complete trả về đúng, Luigi coi task đã xong. Dữ liệu hỏng nằm đó mãi cho tới khi ai đó phát hiện và xóa bằng tay.

Đây là lỗi nguy hiểm nhất của lab. Mọi task Luigi nên ghi đầu ra qua phương thức open của target, không ghi thẳng vào đường dẫn.

Tìm task ghi bằng open thường

Trong pipeline cũ, cách nhanh để tìm task có nguy cơ là tìm trong mã những chỗ gọi open với đường dẫn lấy từ output().path. Mỗi chỗ như vậy nên đổi sang self.output().open. Với thư viện ghi tệp riêng như pandas, có thể ghi ra đường dẫn tạm rồi đổi tên, hoặc truyền đối tượng tệp từ target.open vào hàm ghi.

Tệp cuối bị hỏng

Lab ghi đè gia.csv bằng một tệp chỉ có một dòng dữ liệu, trong khi parsed.json có năm dòng. Chạy Export với complete mặc định: không task nào chạy, vì gia.csv tồn tại.

complete chặt hơn

class ExportStrict(Export):
    def complete(self):
        if not super().complete():
            return False
        n = len(json.load(self.input().open()))
        m = sum(1 for _ in self.output().open()) - 1
        return n == m and mtime(self.output()) >= mtime(self.input())

ExportStrict ghi đè complete: ngoài việc tệp phải tồn tại, số dòng gia.csv phải bằng số dòng parsed.json, và gia.csv phải mới hơn parsed.json. Chạy ExportStrict trên gia.csv hỏng: Export chạy lại một lần, gia.csv có lại đủ năm dòng.

Cái giá của complete chặt

complete chặt phải đọc tệp mỗi lần Luigi kiểm. Với tệp lớn, việc đếm dòng tốn thời gian, và Luigi có thể gọi complete nhiều lần trong một lần chạy. Nên chỉ kiểm những gì rẻ: số dòng ghi trong một tệp nhỏ đi kèm, hoặc kích thước tệp, hoặc dấu thời gian.

complete chặt cho mọi bước hay chỉ bước cuối

Viết complete chặt cho mọi bước làm Luigi đọc nhiều tệp hơn mỗi lần kiểm. Với pipeline crawl, bước cuối là thứ người dùng đọc, nên đáng kiểm kỹ nhất. Các bước giữa có thể dùng complete mặc định nếu đã ghi nguyên tử. Lab chỉ viết complete chặt cho Export vì lý do đó.

Dấu thời gian giải quyết ca tệp đầu vào đổi

Điều kiện gia.csv phải mới hơn parsed.json cũng xử lý được ca sửa tệp đầu vào bằng tay đã nói ở trên. Khi parsed.json được dựng lại, gia.csv cũ hơn nó, complete trả về sai, Export chạy lại. Đây là cách đưa một phần hành vi của make vào Luigi.

Đầu ra nghiệm thu: pipeline file targets cùng thử xóa một output và xác nhận task được chạy lại của Luigi pipeline crawl có target

Phần cuối gom kết quả thành bộ bàn giao.

Bộ bàn giao

Bộ bàn giao gồm tệp lab.py với ba task, hai biến thể ParseNaive và ExportStrict, và mười một ca chạy in kết quả. Người nhận chạy lại lab.py, phải thấy ca xóa parsed.json không làm gì, ca xóa gia.csv chạy Parse và Export, ca ParseNaive để lại tệp dở bị coi là xong.

Tiêu chí đạt

Chạy lại khi mọi tệp đã có thì không task nào chạy. Xóa đầu ra của một bước và các bước sau thì đúng các bước đó chạy lại, bước trước không chạy. Task sập không để lại tệp đích. Tệp đích hỏng được phát hiện bằng complete chặt.

Ghi một tệp đánh dấu

Một mẫu khác là để mỗi task ghi thêm tệp đánh dấu nhỏ chứa số dòng và mã băm của đầu ra, rồi dùng tệp đó làm target. complete đọc tệp đánh dấu thay vì đọc cả tệp dữ liệu. Cách này rẻ khi tệp dữ liệu lớn. Lab chưa thử, nhưng nó kết hợp được ưu điểm của complete chặt với chi phí kiểm thấp.

Quy tắc dựng pipeline crawl bằng Luigi

Mỗi bước một target, đường dẫn chứa ngày. Ghi qua target.open để có ghi nguyên tử. Chạy lại một bước bằng cách xóa đầu ra của nó và của các bước sau. Viết complete chặt cho bước cuối nếu tệp có thể bị sửa ngoài pipeline. Dọn tệp tạm định kỳ.

Khi nào cần proxy với Luigi pipeline crawl có target

Luigi không gọi mạng, task Fetch của bạn mới gọi. Proxy, nếu cần, cấu hình trong mã của Fetch. Parse và Export xử lý tệp trên đĩa, không cần mạng. Nhờ target, sửa parser không phải tải lại trang, nghĩa là không phải dùng thêm băng thông proxy.

Với website được phép thu thập nhưng hiển thị khác theo vùng, có lúc cần IP tại Việt Nam để Fetch nhận đúng trang. Khi đó anh em có thể mua proxy tĩnh Việt Nam tại trang chủ ProxyVN. Proxy không sửa tệp dở dang và không làm complete đúng hơn. Vai trò hợp lệ của proxy trong thu thập dữ liệu được phân tích ở bài Web Scraping proxy là gì.

Ghi nhãn mạng vào tệp đầu ra

Nếu Fetch có thể chạy qua nhiều cấu hình mạng, ghi nhãn cấu hình vào raw.json hoặc vào một tệp đi kèm. Khi giá trong gia.csv lạ, nhãn này giúp biết dữ liệu đến từ vùng nào. Đừng ghi chuỗi proxy có mật khẩu vào tệp dữ liệu, vì thư mục dữ liệu thường được chép đi nhiều nơi.

Fetch lỗi giữa chừng vì proxy

Nếu proxy chết khi Fetch đang tải, Fetch nên ném lỗi thay vì ghi raw.json với những trang tải được. Ghi một phần qua target.open rồi thoát bình thường sẽ tạo raw.json thiếu trang, và Luigi coi là xong. Cấu hình chuỗi proxy đúng định dạng cho Fetch được giải thích trong bài định dạng proxy.

Theo dõi pipeline không có giao diện

Với bộ lập lịch cục bộ, Luigi không có giao diện web. Muốn theo dõi, nên ghi lại kết quả luigi.build mỗi lần chạy: trạng thái, task nào đã chạy, task nào lỗi. Ghi vào một tệp nhật ký theo ngày là đủ cho pipeline nhỏ. Máy chủ luigid có giao diện, nhưng chỉ giữ trạng thái trong bộ nhớ, không thay được nhật ký riêng.

Quyền ghi thư mục

Nếu tiến trình chạy Luigi không có quyền ghi vào thư mục dữ liệu, LocalTarget.open sẽ lỗi ngay khi tạo tệp tạm. Lỗi rõ ràng, dễ sửa. Ca khó hơn là có quyền tạo tệp nhưng không có quyền xóa, khi đó tệp tạm không đổi tên được. Nên chạy pipeline bằng một tài khoản riêng có toàn quyền trên thư mục dữ liệu.

Những gì lab chưa thử

Lab chưa thử máy chủ luigid, chưa thử target trên S3 hay HDFS, chưa thử nhiều worker chạy song song. Lab cũng chưa thử task có nhiều target trong output, nơi complete đòi mọi target đều có. Tệp tạm trên hệ thống tệp khác Windows có thể đặt tên khác.

Checklist Luigi pipeline crawl có target

Checklist

Checklist

  • Mỗi task một LocalTarget, đường dẫn chứa ngày.
  • Ghi đầu ra qua target.open, không dùng open thường.
  • Nhớ Luigi kiểm task cuối trước, dừng nếu nó xong.
  • Chạy lại một bước: xóa đầu ra của nó và các bước sau.
  • Fetch ném lỗi thay vì ghi thiếu trang.
  • complete chặt cho bước cuối khi cần.
  • Dọn tệp luigi-tmp định kỳ.
  • Đếm task chạy thay vì chỉ đọc SUCCESS.

Câu hỏi thường gặp về Luigi pipeline crawl có target

Luigi biết task đã xong bằng cách nào?

Bằng complete, mặc định kiểm mọi target trong output có tồn tại không.

Vì sao xóa tệp giữa mà task không chạy lại?

Vì Luigi kiểm task cuối trước. Lab xóa parsed.json, gia.csv còn, Luigi coi đã xong và không chạy gì.

Task sập có để lại tệp hỏng không?

Không, nếu ghi qua LocalTarget.open. Lab chỉ thấy tệp tạm luigi-tmp. Ghi bằng open thường thì có, và lần sau bị coi là xong.

Luigi có chạy lại khi tệp đầu vào thay đổi không?

Không. Phải tự viết complete so dấu thời gian, như ExportStrict trong lab.

Chạy lại pipeline nhiều lần có hại không?

Không. Lab chạy lại khi mọi tệp đã có, không task nào chạy.

Luigi có cần proxy không?

Không. Chỉ task Fetch gọi mạng mới có thể cần.

Luigi pipeline crawl có target và những điều cần nhớ

Luigi pipeline crawl có target dựa trọn vào một quy tắc: có tệp là xong. Lab trên Luigi 3.8.1 cho thấy xóa tệp giữa không làm gì nếu tệp cuối còn. Ghi qua target.open không để lại tệp hỏng, còn ghi bằng open thường thì để lại tệp dở bị coi là hoàn tất mãi mãi. Muốn chạy lại một bước, xóa đầu ra của nó và mọi bước sau, và viết complete chặt cho bước cuối khi tệp có thể bị sửa. Cần IP tĩnh cho task tải trang trước khi dựng Luigi pipeline crawl có target, liên hệ Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam.

TIN TỨC LIÊN QUAN