Các crawler cỡ lớn: xem xét về hiệu quả và tính tin cậy
Các crawler cỡ lớn để có thể gửi yêu cầu tới hàng triệu Web site và tập hợp hàng trăm triệu trang Web, chúng cần các kỹ thuật cao cấp. Trong phần này, chúng ta sẽ tìm hiểu các phần thực thi quan trọng, để một crawler cỡ lớn có thể đảm bảo được về hiệu quả và tính tin cậy:
Chúng cần có khả năng tìm nhiều trang (cỡ hàng trăm đến hàng
nghìn) cùng một lúc để tận dụng thông lượng mạng (network bankdwith) sẵn
có, vì việc tìm nạp một trang có thể sẽ mất một vài giây cho độ trễ trên mạng.
Để việc tìm nạp nhiều trang cùng một lúc có thể thực hiện được,
việc tìm kiếm DNS cần được thực hiện theo luồng, tiến tới song song hóa, khả chuyển giữa nhiều máy chủ DNS.
Mã hóa trạng thái của ngữ cảnh tìm nạp được vào cơ sở dữ liệu,
sử dụng các socket dị bộ, chúng có thể được kiểm tra vòng về việc truyền xong thông tin.
Khi phân tích URL, cần loại trừ được các trùng lặp để giảm thiểu
số lần tìm nạp dư thừa, và tránh các “spider traps”(đồ thị siêu liên kết được xây dựng vô tình hoặc cố ý có thể làm cho crawler mắc kẹt trong đó, tìm nạp một tập vô hạn các URL “giả mạo”)
DNS caching, prefetching và resolution
Để có được hiệu năng tốt hơn, các crawler cỡ lớn thường bao gồm thành phần DNS được tùy biến cho phù hợp. Thành phần này bao gồm: một máy trạm tùy chọn cho việc định địa chỉ, một máy chủ cache (caching server) và một prefetching client.
Client cho việc định địa chỉ: Được cấu hình để xử lý trùng lặp giữa các yêu cầu đang tồn tại; cho phép đưa ra nhiều yêu cầu resolution cùng nhau, hỏi vòng sau đó để hoàn thành từng yêu cầu cụ thể; cho phép load theo mức phân bổ phù hợp giữa nhiều máy chủ DNS.
Caching server: có một bộ nhớ đệm (cache) lớn, liên tục qua các lần DNS restart (with large cache, persistent across DNS restart), thường trú chủ yếu ở bộ nhớ nếu có thể.
Prefetching client: (Với mỗi tên máy chủ chưa từng được giải quyết trước đó, một DNS cục bộ phải qua rất nhiều mạng để có được thông tin; prefetching sinh ra để chèn lên thời gian trễ bất khả kháng đó những tác vụ hữu ích.) Một trang khi vừa được tìm nạp về, tên máy chủ được phân tích ra từ các HREF, các yêu cầu DNS resolution được gửi tới caching server. Prefetching client thường được thực thi nhờ UDP (User Datagram Protocol), không cần kết nối, giao thức liên lạc dựa trên gói (packet-based) - không được đảm bảo về việc giao phát các gói, không chờ tới khi resolution được hoàn thành. Các yêu cầu được thực thi nhằm nạp đầy DNS cache, do đó, việc giải quyết sẽ nhanh hơn khi trang được gọi thực sự.
Các tìm nạp đồng thời - Multiple Concurrent Fetches
Cần quản lý các kết nối multiple concurrent (multiple concurrent), vì một download đơn giản có thể mất một vài giây, nên cần mở nhiều kết nối
socket tới các máy chủ HTTP khác nhau đồng thời. Các máy đa nhân (multi-
CPU) không hữu dụng nhiều vì hiệu năng của việc crawling bị giới hạn bởi mạng và đĩa. Có hai cách tiếp cận: sử dụng multi-threading hoặc sử dụng các socket non-blocking với các event handlers.
Multithreading
Các thread logic thuộc về thread vật lý của điều khiển được cung cấp bởi hệ điều hành hoặc các tiến trình đồng thời (concurrent processes). Các thread không được sinh ra linh động theo mỗi yêu cầu, mà số cố định các thread được cấp phát trước (fixed number of threads allocated in advance).
Sau khi giải quyết tên server, mỗi thread logic tạo ra một client socket
tiêu đề của truy vấn HTTP, đọc socket (theo lời gọi recv) cho tới khi không còn một ký tự nào nữa, cuối cùng đóng socket lại. Lược đồ chương trình đơn giản nhất là dùng các lời gọi hệ thống theo khối (blocking), cho ngưng tiến trình client cho tới khi lời gọi hoàn thành và dữ liệu khả dụng trong bộ đệm của người sử dụng.
Có hai vấn đề với cách tiếp cận theo tiến trình/ thread đồng thời. Thứ nhất là, bất lợi về mặt hiệu năng do việc loại trừ lẫn nhau (mutual exclusion) và truy cập đồng thời vào cấu trúc dữ liệu (data structures). Thứ hai là, khi các thread/process hoàn thành việc tìm nạp trang và bắt đầu thay đổi lưu trữ tài liệu và chỉ số đồng thời, các thao tác input-output xảy ra ngẫu nhiên, làm giảm tốc độ truy cập đĩa.
Các socket nonblocking và xử lý sự kiện
Cách tiếp cận khác là sử dụng các socket nonblocking (không theo khối). Các lời gọi kết nối, gửi và nhận trả về ngay lập tức mà không cần chờ xử lý từ mạng để hoàn thành. Trạng thái của thao tác mạng quay vòng riêng biệt.
Thông thường, một socket nonblocking cung cấp lời gọi hệ thống select, cho phép ứng dụng trì hoãn và chờ tới khi có nhiều dữ liệu hơn được đọc hoặc ghi với socket đó, thời gian chờ có một giới hạn đã được định trước. select có thể điều khiển việc hỏi vòng một vài socket tại cùng một thời điểm, tạm dừng tiến trình gọi cho tới khi có bất kỳ một socket nào trong số đó được đọc hoặc ghi.
Sử dụng select hiệu quả hơn vì: các thread được xử lý theo chuỗi, và đoạn mã để hoàn thành xử lý (quét các liên kết ra bên ngoài, lưu trữ vào đĩa) không bị gián đoạn bởi các công việc khác (chúng vẫn có thể xảy ra nhưng không được xét tới cho tới khi có lời gọi select rõ ràng); không cần sử dụng các khóa (lock) và đèn báo (semaphore) trong xử lý; chỉ có các trang đã hoàn thành được nối tiếp vào log.
Phân tích đường link và chuẩn hóa
Việc phân tích đường link và chuẩn hóa nhằm mục đích đưa ra dạng chuẩn của URL. Công việc lọc và xử lý các URL giúp tránh việc tìm nạp những trang đã biết với những URL khác nhau, do trên các site lớn, có rất nhiều địa chỉ IP được sử dụng cho việc tải tương đương (load balancing); nội dung trên các máy chủ đó có thể phản chiếu nhau, hoặc có thể có cùng hệ thống file hoặc cơ sở dữ liệu. Mặt khác, để tổ chức một số ít địa chỉ IP tương ứng với nhiều site logic, máy chủ ảo (virtual hosting) hoặc “proxy pass” có thể được sử dụng (ánh xạ nhiều site-tên máy chủ khác nhau vào một địa chỉ IP). Các URL có liên quan với nhau cần được dịch (interpreted) thành một
URL cơ sở tuyệt đối (absolute base URL). URL chuẩn Được định dạng như sau
Sử dụng một chuỗi chuẩn với giao thức (hầu hết là http)
Tên máy chủ được chuẩn hóa
Số cổng được thêm vào một cách rõ ràng
Đường dẫn được chuẩn hóa và làm gọn.
Loại trừ Robot
Một bước cần thiết khác nữa là kiểm tra xem máy chủ có cấm crawling một URL đã chuẩn hóa hay không, bằng cách xem trong file robot.txt trên thư mục HTTP thuộc máy chủ, file này chỉ ra một danh sách các tiếp đầu ngữ của đường dẫn (path prefixes) mà crawler không được phép tìm nạp. File robot.txt chỉ có ý nghĩa đối với crawler.
Loại trừ các URL đã thăm
Trước khi thêm một URL mới vào pool làm việc, cần kiểm tra xem nó đã được tìm nạp lần nào chưa, bằng cách kiểm tra lưu trữ theo hàm băm MD5 trên URL.
băm – sẽ làm cho đường dẫn của cùng một máy chủ bị cách xa hơn nhiều so với phạm vi chuẩn (over the range uniformly). Ta phải sử dụng hàm băm hai lớp: các bit ý nghĩa nhất (24bits) được đưa ra bởi việc hashing tên máy chủ cộng thêm với cổng; bit mức thấp hơn (40bits) được đưa ra bởi việc hashing đường dẫn. Giá trị băm của các URL có cùng tên máy chủ sẽ giống nhau ở 24 bit đầu tiên. Các bit có ràng buộc với nhau được sử dụng như là khóa trên cây nhị phân, được lưu ở mức trang (page level), định vị không-thời gian
(spatiotemporal locality) được áp dụng. Cuối cùng, các URL đủ tiêu chuẩn được thêm vào tập công việc, còn được gọi là phía trước (frontier) của crawler. Giá trị băm được thêm vào cây nhị phân.
Bẫy Spider
Các crawler cần tránh bị mắc kẹt (crashing on) ở các ill-formed HTML (thí dụ: trang với 68kB các ký tự null) hay các site khó xác định (misleading) do không xác định được số trang được sinh tự động bởi các CGI script; hoặc đường dẫn theo độ sâu bất kỳ được sinh tự động bởi các liên kết thư mục mềm dẻo hoặc các đặc tính tái ánh xạ (remapping) đường dẫn trong máy chủ HTTP.
Giải pháp cho Spider trap: không công nghệ tự động nào có thể rõ ràng một cách tuyệt đối. Cách tốt nhất là chuẩn bị các thống kê crawl thông thường, thêm vào các site có ảnh hưởng lớn vào module bảo vệ, cấm crawling các nội dung động như là các truy vấn form CGI , loại trừ các URL với dữ liệu không phải dạng văn bản.
Tránh lặp lại việc triển khai các liên kết trên trang trùng lặp
Tránh tìm nạp một trang với các tên gọi khác nhau nhiều lần là một việc làm cần thiết, vì không chỉ giảm bớt được chi phí thời gian và lưu trữ mà còn tránh được việc tìm nạp nhiều lần theo các liên kết ra bên ngoài.
web và các site giống nhau.
Nếu u1 và u2 là trùng lặp tuyệt đối thì có thể xác định rất dễ dàng. Khi nội dung một trang được lưu trữ, thì thông số kiểm tra (digest, thí dụ: MD5) của nó cũng được lưu trữ trong một chỉ số. Khi một trang web được crawled, thông số kiểm tra của nó được đối chiếu lại với chỉ số đó, thực hiện theo cách này sẽ mất một bước kiểm tra. Một cách khác để xác định trùng lặp là lấy nội dung của u1 và u2, băm chúng thành h(u1) và h(u2), rồi biểu diễn liên kết v có quan hệ với chúng theo (h(u1), v) và (h(u2), v). Nếu như u1 và u2 là các bí danh, trình diễn hai liên kết ra bên ngoài của chúng cũng giống nhau, ta có thể tránh được một bước thực thi hàm kiểm tra xem chúng có phải là trang đã biết hay không.
Do chỉ cần có một ký tự đơn được nhập vào cũng có thể làm thay đổi hoàn toàn kết quả (ảnh hưởng tới digest) (Thí dụ: Ngày cập nhật/tên gọi và email của người quản trị) nên cần tìm kiếm những chỗ gần trùng lặp (near-duplicate). Giải pháp là dùng shingling.
Quản lý và theo dõi việc nạp
Theo dõi nạp (load monitor) lưu lại các thay đổi trong thống kê hệ thống như: hiệu năng hiện tại của kết nối WAN (thí dụ: giới hạn băng thông và độ trễ), thao tác được cung cấp hay số socket mở tối đa với mỗi crawler, số các socket đang hoạt động hiện thời.
Quản lý nạp (load manager) sử dụng các thông số thống kê đó để chọn các đơn vị công việc từ tập công việc (work pool) hoặc giới hạn biên
(frontier), đưa ra kế hoạch về tài nguyên mạng, hoặc phân phối các yêu cầu tới các ISP nếu phù hợp.
Các hàng đợi hoạt động với mỗi máy chủ
Nhiều máy chủ Http được bảo vệ chống lại các tấn công DoS (Denial of Service), bằng cách giới hạn tốc độ hoặc tần số phản hồi đối với bất kỳ địa chỉ
IP tĩnh của máy trạm nào.
Một crawler tốt sẽ luôn giới hạn số yêu cầu hoạt động (active requests) tới một địa chỉ IP server: duy trì hàng đợi các yêu cầu tới mỗi server. Các hàng đợi này được trang bị HTTP phiên bản 1.1 có khả năng duy trì socket. Kỹ thuật này giúp giảm tác động của spider trap: không bị ảnh hưởng nhiều bởi những site rất lớn về kích thước và độ sâu, vì crawler tìm nạp các trang ở đó theo mối quan tâm tương đương với một số lượng lớn các site khác.
Lưu trữ văn bản
Lưu trữ văn bản (Text repository) thường là công việc cuối cùng của crawler: gom các trang tìm nạp được vào một nơi lưu trữ. Các thông tin liên quan tới các trang được lưu thành hai phần: Metadata và nội dung trang. Metadata bao gồm các trường như: kiểu nội dung, ngày thay đổi cuối cùng, độ dài nội dung, mã trạng thái HTTP…, thường được quản lý bởi các phần mềm tùy chọn để tránh chi phí cho các hệ quản trị cơ sở dữ liệu quan hệ.
Một trang HTML thông thường 10KB được lưu trữ dạng nén thành 2- 4KB (sử dụng zlib), trong khi hầu hết các hệ thống file có kích thước 4-8KB file block size, nên việc lưu trữ mỗi file cho mỗi trang được crawled về là không khả thi vì xảy ra phân mảnh trong nhóm file (file block fragmentation). Do đó, lưu trữ trang thường được chuyển thành hệ thống lưu trữ tùy chọn, được thiết lập sao cho có thể cung cấp các phương thức truy cập đơn giản cho crawler có thể thêm vào các trang, và cho các chương trình thực thi sau đó (thí dụ: bộ định chỉ mục) có thể tìm lại được tài liệu.
Ở các hệ thống kích thước nhỏ, việc lưu trữ được giới hạn bên trong các đĩa của một máy, có thể sử dụng trình quản lý lưu trữ thông dụng như Berkeley DB, giúp quản lý cơ sở dữ liệu nội trong một file. Nếu trang Web muốn truy cập theo khóa như URL của chúng, cơ sở dữ liệu có thể được cấu hình như là bảng băm hoặc cây nhị phân, giúp xử lý tuần tự việc truy cập một
trang. Nếu như trình xử lý trang sau đó có thể xử lý các trang theo bất kỳ thứ tự nào, như trong trường hợp chỉ mục của công cụ tìm kiếm (search engine indexing), thì cơ sở dữ liệu có thể cấu hình như là log tuần tự các bản ghi trang.
Ở các hệ thống lớn, bộ lưu trữ được phân bổ trên một số máy chủ lưu trữ, kết nối tới crawler thông qua mạng cục bộ tốc độ cao (thí dụ: Ethernet gigabit). Crawler có thể hash mỗi URL ứng với máy chủ lưu trữ cụ thể và gửi tới URL và nội dung trang. Để đạt được thông lượng mạng tổng thể 40GB trong một giờ hay 100Mb trên giây (10 triệu trang trong một giờ, tương đương với 200 giờ cho toàn bộ Web), cần cỡ hai đường leased line mức T3.
Các crawler cỡ lớn thường sử dụng nhiều ISP và một ngân hàng các máy chủ lưu trữ để lưu các trang crawl về được.
Làm tươi các trang đã được crawled về
Chỉ số máy tìm kiếm nên được làm mới, để phản ánh được phiên bản mới nhất của tất cả các trang được crawled về. Trong thực tế, các crawler Web không bao giờ “hoàn thành” công việc của nó, mà chỉ dừng khi đã tập hợp được “đủ” các trang. Các trang có tốc độ thay đổi nội dung rất khác nhau. Hình 2.4 chỉ ra cách sử dụng giao thức Http kiểm tra “If-modified-since” xem một trang có thay đổi kể từ thời điểm nào đó hay không, nếu có thì tìm nạp trang đó, nếu không thì máy chủ sẽ gửi mã phản hồi là không thay đổi và không gửi trang đó nữa. Với một trình duyệt (browser) thì xử lý đó có thể hữu ích, nhưng với một crawler thì không giúp được gì, vì việc giải địa chỉ máy chủ, rồi kết nối một socket TCP tới máy chủ sẽ mất một khoảng thời gian, là lớn đối với việc crawl.
Hình 2.4: Sử dụng truy vấn header “If-modified-since” để kiểm tra xem một trang có cần crawled lại hay không. Trong trường hợp cụ thể này thì
không cần.
Khi một vòng crawling mới bắt đầu, thật rõ ràng nếu biết rằng trang nào đã được thay đổi kể từ lần crawl cuối cùng, và chỉ tìm nạp những trang đó. Điều này là khả thi trong một số ít trường hợp: sử dụng tiêu đề phản hồi Http Expires, như trong hình bcd:
Hình 2.5: Một số site với các thông tin nhanhvề thời gian gửi một thuộc tính Expires trong tiêu đề phản hồi Http.
Với các trang không có thông tin về expiration date, ta cần dự đoán xem việc thăm lại có thể thấy được phiên bản mới hay không. Một crawler có thể truy cập một số thông tin kiểu như điểm phản ánh khả năng một trang có thay đổi hay không, từ đó, nó sẽ tìm nạp các URL theo thứ tự giảm dần của các giá trị điểm đó. Việc xây dựng ước lượng có thể dựa trên giả thuyết: “quá khứ có thể dự đoán tương lai” (recent past predicts the future).
Việc ước lượng tốc độ thay đổi của trang được Brewington và Cybenko