Веб-сканер в Ruby: как добиться лучшей производительности? - PullRequest
2 голосов
/ 14 января 2011

Я пишу сканер, который должен иметь возможность анализировать несколько страниц одновременно.Я использую Nokogiri для парсинга, который очень хорош и решает все мои задачи, но я не знаю, как добиться лучшей производительности.

Я использую потоки для одновременного выполнения множества запросов open-uri, и это ускоряет процесс, но кажется, что это все еще далеко от потенциала, который я могу реализовать с одного сервера.Должен ли я использовать несколько процессов?Каковы ограничения потоков и процессов, которые могут быть запущены для одного приложения ruby?

Другими словами: как добиться максимальной производительности в этом случае.

Ответы [ 5 ]

4 голосов
/ 14 января 2011

Мне действительно нравятся Typhoeus и Hydra для обработки нескольких запросов одновременно.

Typhoeus - это http-сторона клиента, а Hydra - часть, которая обрабатывает несколько запросов. Примеры хороши, так что просмотрите их и посмотрите.

3 голосов
/ 23 августа 2012

Эй, другой способ - использовать комбинацию Nokogiri и IronWorker ( IronMQ и IronCache ).

Смотрите полную запись в блоге на тему здесь

3 голосов
/ 14 января 2011

Хотя кажется, что вы не ищете что-то настолько сложное, я нашел этот тезис интересным прочитанным некоторое время назад: Строительные блоки масштабируемого веб-сканера - Марк Сигер .

Вусловия потоков / ограничения процесса. Ruby имеет очень низкий потенциал потоков.Стандартные Ruby (MRI / YARV) и Rubinius не поддерживают одновременное выполнение потоков, если только не используется расширение, специально созданное для его поддержки.В зависимости от того, сколько у вас проблем с производительностью в IO и сколько в обработке, я мог бы предложить использовать EventMachine .

Многопроцессорность, однако Ruby работает очень хорошо, пока выу нас есть хороший менеджер / база данных для всех процессов, с которыми необходимо обмениваться данными, а затем запуск нескольких процессов должен масштабироваться так, как позволяет ваша вычислительная мощность.

1 голос
/ 10 марта 2011

Если вы хотите что-то легкое, перейдите на http://anemone.rubyforge.org/
Если вы хотите что-то быстрое, напишите что-нибудь с помощью eventmachine / em-http-request

Я обнаружил, что redis - это отличный многоцелевой инструмент для очередиуправление, кеширование и тд.Вы также можете использовать специализированные вещи, такие как beanstalkd / active mq / ..., но, по крайней мере, в моем случае я не нашел их большим преимуществом по сравнению с Redis.Особенно нагрузка на бэкэнд-систему может быть узким местом, поэтому тщательно выбирайте свою базу данных и обращайте внимание на то, что вы экономите

1 голос
/ 14 января 2011

Мы используем комбинацию ActiveMQ / Active Messaging, Event Machine и многопоточности для решения этой проблемы.Мы начнем с большого списка URL для получения.Затем мы разбиваем их на пакеты по 100 URL-адресов на пакет.Каждая партия затем помещается в ActiveMQ.Затем у нас есть массив процессов опроса / потребителя, слушающих очередь.Все эти потребители могут находиться на одном компьютере или могут быть распределены по нескольким компьютерам.Массив потребителей может быть сколь угодно большим, чтобы поддерживать столько параллелизма, сколько мы хотим.Потребители используют Active Messaging, что является хорошей интеграцией Ruby с ActiveMQ.

Когда потребитель получает сообщение для обработки пакета из 100 URL-адресов, он запускает Event Machine для создания пула потоков, который может обрабатывать несколько сообщений.в несколько потоков.Как и вы, мы используем Nokogiri для обработки каждого URL.

Таким образом, существует три уровня параллелизма:

1) Несколько одновременных запросов на процесс потребителя, поддерживаемый Event Machine и потоками.

2) Несколько пользовательских процессов на компьютере.

3) Несколько компьютеров.

...