Cách hiệu quả nhất (thời gian, chi phí) để cạo 5 triệu trang web?


8

Tôi có một danh sách các trang web mà tôi cần phải cạo, phân tích và sau đó lưu trữ dữ liệu kết quả trong cơ sở dữ liệu. Tổng cộng là khoảng 5.000.000.

Giả định hiện tại của tôi về cách tốt nhất để tiếp cận điều này là triển khai ~ 100 cá thể EC2, cung cấp cho mỗi cá thể 50.000 trang để cạo và sau đó để nó chạy, sau đó khi quá trình hoàn tất hợp nhất các cơ sở dữ liệu lại với nhau. Giả định là sẽ mất khoảng một ngày để chạy (600ms để tải, phân tích và lưu từng trang).

Có ai có kinh nghiệm làm một khối lượng lớn trang cào như vậy trong thời gian giới hạn không? Tôi đã thực hiện một số lượng lớn trước đó (1,5m) nhưng đó là từ một máy duy nhất và chỉ mất hơn một tuần để hoàn thành.

Nút thắt trong tình huống của tôi là tải xuống các trang, phân tích cú pháp là một cái gì đó không quá 2ms, vì vậy một cái gì đó có thể hợp lý hóa quá trình tải xuống các trang là những gì tôi đang tìm kiếm.


Khi bạn nói một danh sách các trang web, đây chỉ là một trang web đơn giản hoặc toàn bộ các trang web như một diễn đàn hay cái gì đó? Ngoài ra ngay cả khi bạn đi thẳng ra ngoài, có các quy tắc phù hợp cho các trang web bạn muốn cạo (hoặc đây chỉ là lý thuyết được đưa ra trước?)
Tombull89

Tôi có nhiều trường hợp câu trả lời này có liên quan đến tôi, vì câu hỏi tôi đã đưa ra một con số tùy ý có thể dễ dàng hình dung và loại trang web khác nhau, nhưng đối với câu hỏi có thể giả định rằng đó là một diễn đàn bị loại bỏ nếu bạn thích. Việc trang web có cho phép nạo hay không là vấn đề không (dù sao đối với câu hỏi)
sam

Để làm rõ quan điểm về loại trang web: mỗi trang web độc lập với bất kỳ trang nào khác, chúng có thể được loại bỏ theo bất kỳ thứ tự nào và không phụ thuộc vào trang khác bị loại bỏ. Nó có thể được thực hiện tiến, lùi, ngẫu nhiên, điều đó không thành vấn đề.
sam

Tôi hiểu rồi. Tôi không biết EC2 sẽ xử lý các bản tải xuống như thế nào, nhưng một số người dùng SF khác thường có thể có một số ý tưởng. Ngoài ra, ngoài chủ đề, nhưng đây có phải citricsquid từ MinecraftForums không? Đó là một cái tên khá ... độc đáo.
Tombull89

mmhmm đó là tôi
sam

Câu trả lời:


7

Làm việc với giả định rằng thời gian tải xuống (và do đó sử dụng băng thông) là yếu tố hạn chế của bạn, tôi sẽ đưa ra các đề xuất sau:

Đầu tiên, chọn các trường hợp m1.lund. Trong ba 'mức' hiệu suất I / O (bao gồm băng thông), các phiên bản m1.large và m1.xlarge đều cung cấp hiệu suất I / O 'cao'. Vì nhiệm vụ của bạn không bị ràng buộc bởi CPU, nên ít tốn kém nhất trong số này sẽ là lựa chọn thích hợp hơn.

Thứ hai, cá thể của bạn sẽ có thể tải xuống nhanh hơn nhiều so với bất kỳ trang web nào có thể phục vụ các trang - không tải xuống một trang tại một thời điểm nhất định, chạy đồng thời nhiệm vụ - bạn có thể thực hiện đồng thời ít nhất 20 trang (mặc dù , Tôi đoán bạn có thể có thể làm 50-100 mà không gặp khó khăn). (Lấy ví dụ về việc tải xuống từ một diễn đàn từ nhận xét của bạn - đó là một trang động sẽ mất thời gian để tạo máy chủ - và có những người dùng khác sử dụng băng thông trang web đó, v.v.). Tiếp tục tăng đồng thời cho đến khi bạn đạt đến giới hạn của băng thông thể hiện. (Tất nhiên, không thực hiện nhiều yêu cầu đồng thời cho cùng một trang).

Nếu bạn thực sự đang cố gắng tối đa hóa hiệu suất, bạn có thể xem xét khởi chạy các trường hợp trong các khu vực phù hợp về mặt địa lý để giảm thiểu độ trễ (nhưng điều đó sẽ yêu cầu định vị địa lý tất cả các URL của bạn, điều này có thể không thực tế).

Một điều cần lưu ý là băng thông thể hiện có thể thay đổi, đôi khi bạn sẽ có hiệu suất cao hơn và vào những lúc khác bạn sẽ có hiệu suất thấp hơn. Trong các trường hợp nhỏ hơn, sự thay đổi về hiệu suất có ý nghĩa hơn vì các liên kết vật lý được chia sẻ bởi nhiều máy chủ hơn và bất kỳ liên kết nào có thể làm giảm băng thông khả dụng của bạn. Giữa các phiên bản m1.lund, trong mạng EC2 (cùng vùng khả dụng), bạn sẽ nhận được thông lượng gigabit lý thuyết.

Nói chung, với AWS, hầu như luôn hiệu quả hơn khi đi với một thể hiện lớn hơn so với nhiều trường hợp nhỏ hơn (trừ khi bạn đặc biệt xem xét một cái gì đó như failover, v.v., nơi bạn cần nhiều phiên bản).

Tôi không biết thiết lập của bạn đòi hỏi gì, nhưng trước đây tôi đã thử điều này (từ 1 đến 2 triệu liên kết, được cập nhật định kỳ), cách tiếp cận của tôi là duy trì cơ sở dữ liệu về các liên kết thêm các liên kết mới khi chúng được tìm thấy và bỏ qua các quy trình để cạo và phân tích các trang. Một URL sẽ được truy xuất (ngẫu nhiên) và được đánh dấu là đang tiến hành trên cơ sở dữ liệu, tập lệnh sẽ tải xuống trang và nếu thành công, hãy đánh dấu url như đã tải xuống trong cơ sở dữ liệu và gửi nội dung đến một tập lệnh khác phân tích trang, liên kết mới đã được thêm vào cơ sở dữ liệu khi chúng được tìm thấy. Ưu điểm của cơ sở dữ liệu ở đây là tập trung hóa - nhiều tập lệnh có thể truy vấn cơ sở dữ liệu đồng thời và (miễn là giao dịch là nguyên tử) người ta có thể yên tâm rằng mỗi trang sẽ chỉ được tải xuống một lần.

Một vài điểm được đề cập thêm - có giới hạn (tôi tin là 20) về số lượng phiên bản theo yêu cầu bạn có thể chạy cùng một lúc - nếu bạn dự định vượt quá các giới hạn đó, bạn sẽ cần yêu cầu AWS tăng tài khoản của bạn Hạn mức. Sẽ rất kinh tế hơn cho bạn khi chạy các trường hợp giao ngay và tăng quy mô số của bạn khi giá giao ngay thấp (có thể là một trường hợp theo yêu cầu để giữ mọi thứ có tổ chức và các trường hợp giao ngay, còn lại).

Nếu thời gian có mức độ ưu tiên cao hơn chi phí đối với bạn, thì các trường hợp tính toán cụm cung cấp băng thông 10Gbps - và sẽ mang lại băng thông tải xuống lớn nhất.

Tóm tắt: thử một vài phiên bản lớn (thay vì nhiều phiên bản nhỏ) và chạy nhiều bản tải xuống đồng thời trên mỗi phiên bản - thêm nhiều phiên bản nếu bạn thấy mình bị giới hạn băng thông, hãy chuyển sang các phiên bản lớn hơn nếu bạn thấy mình bị ràng buộc CPU / bộ nhớ.


4

Chúng tôi đã cố gắng làm một cái gì đó tương tự, và đây là 5 xu của tôi:

  1. Nhận 2-3 máy chủ chưa được kiểm tra giá rẻ, ví dụ: không trả tiền cho băng thông.

  2. Sử dụng python với asyncore. Asyncore là cách cũ để làm mọi thứ, nhưng chúng tôi thấy nó hoạt động nhanh hơn bất kỳ phương pháp nào khác. Nhược điểm là tra cứu DNS đang bị chặn, tức là không "song song". Sử dụng asyncore, chúng tôi đã quản lý để quét URL 1M trong 40 phút, sử dụng các lõi XEON 4, RAM 8 GB. Tải trung bình trên máy chủ ít hơn 4 (đó là tuyệt vời cho 4 lõi).

  3. Nếu bạn không thích asyncore, hãy thử gevent. Nó thậm chí không chặn DNS. Sử dụng gevent, 1M đã được tải xuống trong khoảng 50 phút trên cùng một phần cứng. Tải trung bình trên máy chủ là rất lớn.

Lưu ý rằng chúng tôi đã kiểm tra rất nhiều thư viện Python, như các grequest, curl, liburl / liburl2, nhưng chúng tôi đã không kiểm tra Twisted .

  1. Chúng tôi đã kiểm tra PHP + curl + một số quy trình, nó đã thực hiện công việc trong khoảng một giờ, nhưng tải trung bình trên máy chủ là rất lớn.

"Unmetered" thường có nghĩa là "chúng tôi tắt bạn khi chúng tôi cảm thấy như vậy", theo kinh nghiệm của tôi.
ceejayoz

theo kinh nghiệm của tôi, "Unmetered" có nghĩa là giới hạn ở mức 100 MBit hoặc hơn
Nick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.