2012-02-22 25 views
7

Tôi bắt đầu tìm hiểu về trình thu thập dữ liệu web gần đây và tôi đã tạo một trình thu thập mẫu với Ruby, AnemoneMongodb để lưu trữ. Tôi đang thử nghiệm trình thu thập thông tin trên một trang web công cộng lớn với hàng tỷ liên kết.Ruby, Mongodb, Anemone: trình thu thập dữ liệu web có thể bị rò rỉ bộ nhớ?

Trình thu thập thông tin.rb đang lập chỉ mục thông tin chính xác, mặc dù khi tôi kiểm tra việc sử dụng bộ nhớ trong giám sát hoạt động, nó cho thấy bộ nhớ liên tục phát triển. Tôi chỉ chạy trình thu thập thông tin trong khoảng 6-7 giờ và bộ nhớ đang hiển thị 1.38GB cho mongod và 1.37GB cho quá trình Ruby. Dường như nó tăng khoảng 100MB mỗi giờ.

Dường như tôi có thể bị rò rỉ bộ nhớ? Là một cách tối ưu hơn, tôi có thể đạt được cùng một lần thu thập dữ liệu mà không cần bộ nhớ vượt khỏi tầm kiểm soát để nó có thể chạy lâu hơn?

# Sample web_crawler.rb with Anemone, Mongodb and Ruby. 

require 'anemone' 

# do not store the page's body. 
module Anemone 
    class Page 
    def to_hash 
     {'url' => @url.to_s, 
     'links' => links.map(&:to_s), 
     'code' => @code, 
     'visited' => @visited, 
     'depth' => @depth, 
     'referer' => @referer.to_s, 
     'fetched' => @fetched} 
    end 
    def self.from_hash(hash) 
     page = self.new(URI(hash['url'])) 
     {'@links' => hash['links'].map { |link| URI(link) }, 
     '@code' => hash['code'].to_i, 
     '@visited' => hash['visited'], 
     '@depth' => hash['depth'].to_i, 
     '@referer' => hash['referer'], 
     '@fetched' => hash['fetched'] 
     }.each do |var, value| 
     page.instance_variable_set(var, value) 
     end 
     page 
    end 
    end 
end 


Anemone.crawl("http://www.example.com/", :discard_page_bodies => true, :threads => 1, :obey_robots_txt => true, :user_agent => "Example - Web Crawler", :large_scale_crawl => true) do | anemone | 
    anemone.storage = Anemone::Storage.MongoDB 

    #only crawl pages that contain /example in url 
    anemone.focus_crawl do |page| 
    links = page.links.delete_if do |link| 
     (link.to_s =~ /example/).nil? 
    end 
    end 

    # only process pages in the /example directory 
    anemone.on_pages_like(/example/) do | page | 
    regex = /some type of regex/ 
    example = page.doc.css('#example_div').inner_html.gsub(regex,'') rescue next 

    # Save to text file 
    if !example.nil? and example != "" 
     open('example.txt', 'a') { |f| f.puts "#{example}"} 
    end 
    page.discard_doc! 
    end 
end 
+0

Bạn có tìm ra nguyên nhân gây ra rò rỉ không? Nếu bạn nghĩ đó là lỗi trong Anemone, bạn có báo cáo nó trên [tracker theo dõi vấn đề] của họ không (https://github.com/chriskite/anemone/issues)? –

+0

Các vấn đề liên quan được đề cập trên trình theo dõi vấn đề Anemone bao gồm: [rò rỉ bộ nhớ?] (Https://github.com/chriskite/anemone/issues/49), [rò rỉ bộ nhớ hoặc xử lý bộ nhớ không hiệu quả] (https://github.com/chriskite/anemone/issues/29) và [Sửa lỗi OutOfMemory cho các trang web lớn] (https://github.com/chriskite/anemone/pull/30) –

+0

Tôi đã báo cáo nó cùng lúc với việc đăng bài ở đây trên SO. Tôi đã có thể thu thập dữ liệu nhiệm vụ của mình yêu cầu bằng cách thêm các bản sửa lỗi được đề xuất và nó làm cho quá trình thu thập dữ liệu của tôi kéo dài hơn rất nhiều, mặc dù tbh việc sử dụng ram tăng đều đặn, không nhanh như trước đây. Tôi vẫn không chắc chắn nguyên nhân gây rò rỉ bộ nhớ. – viotech

Trả lời

3

Tôi cũng gặp vấn đề với điều này, nhưng tôi đang sử dụng redis làm kho dữ liệu.

đây là bánh xích của tôi:

require "rubygems" 

require "anemone" 

urls = File.open("urls.csv") 
opts = {discard_page_bodies: true, skip_query_strings: true, depth_limit:2000, read_timeout: 10} 

File.open("results.csv", "a") do |result_file| 

    while row = urls.gets 

    row_ = row.strip.split(',') 
    if row_[1].start_with?("http://") 
     url = row_[1] 
    else 
     url = "http://#{row_[1]}" 
    end 
    Anemone.crawl(url, options = opts) do |anemone| 
     anemone.storage = Anemone::Storage.Redis 
     puts "crawling #{url}"  
     anemone.on_every_page do |page| 

     next if page.body == nil 

     if page.body.downcase.include?("sometext") 
      puts "found one at #{url}"  
      result_file.puts "#{row_[0]},#{row_[1]}" 
      next 

     end # end if 

     end # end on_every_page 

    end # end crawl 

    end # end while 

    # we're done 
    puts "We're done." 

end # end File.open 

tôi áp dụng các bản vá từ here đến file core.rb tôi trong ngọc hải quỳ:

35  # Prevent page_queue from using excessive RAM. Can indirectly limit ra te of crawling. You'll additionally want to use discard_page_bodies and/or a  non-memory 'storage' option 
36  :max_page_queue_size => 100, 

...

(Sau đây đã từng nằm trên đường 155)

157  page_queue = SizedQueue.new(@opts[:max_page_queue_size]) 

và tôi có một công việc định kỳ hàng giờ làm:

#!/usr/bin/env python 
import redis 
r = redis.Redis() 
r.flushall() 

để thử và giảm mức sử dụng bộ nhớ của Redis. Tôi đang khởi động lại một thu thập dữ liệu khổng lồ ngay bây giờ, vì vậy chúng tôi sẽ xem nó như thế nào!

Tôi sẽ báo cáo lại với kết quả ...

1

Tôi đang làm điều gì đó tương tự và tôi nghĩ rằng có thể bạn chỉ đang tạo nhiều tải dữ liệu.

Bạn không lưu nội dung để giúp yêu cầu bộ nhớ.

Cải tiến duy nhất khác mà tôi có thể nghĩ là sử dụng Redis thay vì Mongo vì tôi thấy nó có khả năng mở rộng nhiều hơn cho bộ nhớ của Anemone.

Kiểm tra kích thước dữ liệu bạn có trong mongo - Tôi thấy rằng tôi đã tiết kiệm được một số lượng lớn hàng.

Các vấn đề liên quan