Эффективный способ проверить 10000 фидов блогов в Perl - PullRequest
1 голос
/ 13 декабря 2010

У нас 10 000 блогов, которые мы хотим проверять несколько раз в день на наличие новых сообщений. Мне бы понравились некоторые идеи с примером кода о наиболее эффективном способе сделать это с помощью Perl.

В настоящее время мы просто используем LWP :: UserAgent для загрузки каждого RSS-канала, а затем проверяем каждый URL-адрес полученного канала по таблице базы данных MySQL по уже найденным URL-адресам по одному. Излишне говорить, что это плохо масштабируется и супер неэффективно.

Заранее спасибо за помощь и советы!

Ответы [ 4 ]

3 голосов
/ 13 декабря 2010

К сожалению, вероятно, нет другого способа, кроме как сделать какой-либо опрос.

К счастью, реализация протокола PubSubHubbub может значительно помочь уменьшить количество опросов для каналов, которые его поддерживают..

Для тех фидов, которые не поддерживают PubSubHubbub, вам необходимо убедиться, что вы используете протоколы уровня HTTP (например, заголовки ETags или If-Modified-Since, чтобы знать, когда / когда ресурс былобновлено).Также убедитесь, что вы внедрили какие-то механизмы отсрочки.

2 голосов
/ 13 декабря 2010

Возможно, посмотрите на AnyEvent :: Feed , он асинхронный (с использованием цикла событий AnyEvent) с настраиваемыми интервалами опроса, а также встроенной поддержкой «видимых» статей и поддержкой каналов RSS и Atom. , Возможно, вы можете создать один процесс, опрашивающий каждый канал, или несколько процессов, опрашивающих разные разделы вашего списка каналов.

Из резюме:

      use AnyEvent;
      use AnyEvent::Feed;

      my $feed_reader =
         AnyEvent::Feed->new (
            url      => 'http://example.com/atom.xml',
            interval => $seconds,

            on_fetch => sub {
               my ($feed_reader, $new_entries, $feed, $error) = @_;

               if (defined $error) {
                  warn "ERROR: $error\n";
                  return;
               }
               for (@$new_entries) {
                     my ($hash, $entry) = @_;
                     # $hash a unique hash describing the $entry
                     # $entry is the XML::Feed::Entry object of the new entries
                     # since the last fetch.
               }

            }
         );
0 голосов
/ 13 декабря 2010

10000 не так много.

Тогда вы, вероятно, могли бы справиться, используя простой подход, такой как разветвление некоторых рабочих процессов, которые получают URL-адреса RSS из БД, извлекают их и обновляют базу данных:

for (1..$n) {
  my $pid = fork;
  if (!$pid) {
     defined $pid or die "fork failed";
     my $db = open_db();
     while (1) {
       $url = get_next_url($db) or last;
       $rss = feed_rss($url);
       update_rss($db, $rss);
     }
     exit(0);
  }
}
wait_for_workers(@pid);

Это, учитывая, что вы не можете использовать некоторые из существующих приложений, уже указанных другими респондентами.

0 голосов
/ 13 декабря 2010

Похоже, два вопроса в одном: выбор сравнения.Другие ответили на часть извлечения.Что касается сравнения:

  • Я недавно читал о redis , и это кажется вам подходящим, поскольку он может выполнять много простых операций в секунду(допустим, ~ 80k / s).Поэтому проверка, если у вас уже есть URL, должна идти очень быстро.Хотя на самом деле никогда не использовал его;)

  • Идея: пробовали ли вы сравнивать размер перед анализом RSS?Может сэкономить время, если изменения происходят нечасто.

...