Потоки или процессы?
От: Geralt  
Дата: 30.12.04 18:41
Оценка:
Необходимо реализовать приложение под UNIX, которое выполняет head запрос для большого списка URL и некоторым образом обрабатывает полученную информацию. Дополнительные требования таковы, что должен существовать один главный процесс и некоторое количество рабочих процессов. Главный и рабочие процессы должны "общаться" между собой в двух направлениях: главный процесс передает рабочему ссылку и некоторые параметры, рабочий выполняет запрос и возвращает главному результат выполнения.

Первоначально программы была реализована на перле. Сначала с форком, затем с префорком и sysv IPC, затем с использованием ithreads. Но во всех этих случаях можно было (не убивая систему) создать максимум 100 процессов, а скорость работы и нагрузка на систему оставляли желать лучшего. Сейчас я планирую переписать эту же программу на Си, но в виду полного отсутствия опыта программирования на данном языке под UNIX в общем, и многопоточных и мультипроцессорных приложений в частности, решил обратиться за советом к специалистам.

Вариантов решения задачи я вижу четыре:
1. Форк и однонаправленный канал. В родительском процессе устанавливаю URL и нужные параметры, делаю форк. В дочернем процессе выполняю запрос, результаты пишу в канал в виде отформатированной строки. В родителе читаю данные из канала. Т.е. один дочерний процесс выполнят за время своей жизни один запрос.
2. Префорк, SysV IPC и однонаправленный канал. Каждый дочерний процесс работает в цикле: получает URL и параметры из шаровой переменной, выполняет запрос, результаты, как и в предыдущем примере, пишет в канал.
3. Потоки (треды). Так же как и вариант 1 — один запрос за все время жизни дочернего потока.
4. Претрединг. Предварительно формирую нужное количество потоков. Дочерние потоки работают в цикле, получают данные из одной очереди, а результаты отправляют в другую.

Посоветуйте, пожалуйста, оптимальный вариант для решения поставленной задачи, учитывая тот факт, что запрос выполняется продолжительное время (1-3 секунды). После работы с перлом у меня остались некоторые впечатления насчет первого и второго решения. Вариант 1 сильно грузит систему (20-30 форков в секунду) а, второй вариант очень сильно тормозит использование SysV IPC, но без нее не обойтись, т.к. нужно двунаправленное взаимодействие.
Re: Потоки или процессы?
От: aka50 Россия  
Дата: 30.12.04 22:01
Оценка: 3 (1) +1
Здравствуйте, Geralt, Вы писали:

<skip>

Сканер пишем?

G>Вариантов решения задачи я вижу четыре:

G>1. Форк и однонаправленный канал. В родительском процессе устанавливаю URL и нужные параметры, делаю форк. В дочернем процессе выполняю запрос, результаты пишу в канал в виде отформатированной строки. В родителе читаю данные из канала. Т.е. один дочерний процесс выполнят за время своей жизни один запрос.
Для данной задачи -> в топку

G>2. Префорк, SysV IPC и однонаправленный канал. Каждый дочерний процесс работает в цикле: получает URL и параметры из шаровой переменной, выполняет запрос, результаты, как и в предыдущем примере, пишет в канал.

Приемлимо, но слишком простая задача, для этого... к тому же если надо сразу по 1000 ури сканить... 1000 процессов рожать?

G>3. Потоки (треды). Так же как и вариант 1 — один запрос за все время жизни дочернего потока.

Почти тоже самое что и 1, токо быстрее немного... но все равно не эффективно.

G>4. Претрединг. Предварительно формирую нужное количество потоков. Дочерние потоки работают в цикле, получают данные из одной очереди, а результаты отправляют в другую.

Другое название Job Manager. Тоже что и 2, но тоже быстрее. И тоже тут избыточно.

G>Посоветуйте, пожалуйста, оптимальный вариант для решения поставленной задачи, учитывая тот факт, что запрос выполняется продолжительное время (1-3 секунды). После работы с перлом у меня остались некоторые впечатления насчет первого и второго решения. Вариант 1 сильно грузит систему (20-30 форков в секунду) а, второй вариант очень сильно тормозит использование SysV IPC, но без нее не обойтись, т.к. нужно двунаправленное взаимодействие.

Все гораздо проще...

Для данной конкертной задачи это все нафиг не нужно.... быстрее всего будет работать FSM в одном процессе. Ни синхронизации, ни рождения чего бы то ни было... тупо и надежно (если сильно не мудрить с логикой, иначе threads). Так реализован bind.

Вот библиотека, которая позволяет реализовать FSM в пределах одного процесса без всякого гимора.
http://www.monkey.org/~provos/libevent/

ЗЫ: там же есть ссылки на разные сканеры на этой либе... можете проверить сначала как это работает будете приятно удивлены.
Re[2]: Потоки или процессы?
От: Geralt  
Дата: 31.12.04 07:10
Оценка:
Большое спасибо за ответ.

A>Сканер пишем?

Скорее чекер живых URL с некоторой дополнительной функциональностью.

G>>1. Форк и однонаправленный канал.

A>Для данной задачи -> в топку
Я тоже так рассуждал. От 30-40 форков в секунду ни одна система не будет в восторге.

G>>2. Префорк, SysV IPC и однонаправленный канал.

A>Приемлимо, но слишком простая задача, для этого... к тому же если надо сразу по 1000 ури сканить... 1000 процессов рожать?
На перле у меня получалось родить 100 процессов, но там каждый процесс включает в себя интерпретатор и весит около 5-8 метров. Плюс какие-то неясные проблемы с sysv IPC, которые не позволяли изменять шаровый массив размером более 10 элементов, поэтому приходилось действовать по следующей схеме: родитель проверяет пуст ли хеш параметров, если да, локает, пишет в него, анлокает. Дочерние процессы "набрасываются" на хеш. Тот, кто успевает его локнуть получает параметры, опустошает и анлокает. Родитель замечает, что хэш пуст и пишет в него новые значения. И т.д. Таким образом в секунду происходило 30-60 локов, анлоков и записей в шаровую переменную, что тоже очень сильно грузило систему.

G>>4. Претрединг.

A>Другое название Job Manager. Тоже что и 2, но тоже быстрее. И тоже тут избыточно.
В обще-то я склонялся к этому варианту т.к. считал его самым быстрым и наименее ресурсоемким.

A>Для данной конкертной задачи это все нафиг не нужно.... быстрее всего будет работать FSM в одном процессе.

What does FSM mean? =)

A>Вот библиотека, которая позволяет реализовать FSM в пределах одного процесса без всякого гимора.

A>http://www.monkey.org/~provos/libevent/
Уже изучаю. Большое спасибо.

A>ЗЫ: там же есть ссылки на разные сканеры на этой либе... можете проверить сначала как это работает будете приятно удивлены.

Постараюсь проверить в ближайшее время. Учитывая тот факт, что единичным заданием является выполнение head запроса, а затем get в случае, если некоторые данные (время модификации, например) удовлетворяют некоторым критериям, каково количество заданий может обрабатываться в секунду (канал очень широкий =)?

И, чтоб не создавать дополнительную тему, какие существуют библиотеки по типу libwww для перл (классы Request, Response, Cookies, работа с SSL и т.д.)?
Re: Потоки или процессы?
От: Maxim S. Shatskih Россия  
Дата: 01.01.05 00:48
Оценка:
G>2. Префорк, SysV IPC и однонаправленный канал. Каждый дочерний процесс работает в

Я бы срисовал дизайн Апача. Префорк, и сокеты вместо SysV IPC. Можно UNIX-domain сокеты, если поддержка сети тут не нужна.

А то и вовсе использовал бы Апач как таковой (специально запущенный) вместе с mod_perl, и слал бы ему вопросы на протоколе HTTP. Он бы там что-то делал, и выдавал мне ответ.

Запрос выполняется 3 секунды в худшем случае. Значит, чтобы выполнить 30 запросов в секунду — надо 10 процессов. Это нормально и не тяжело.

Не знаю, правда, можно ли попросить mod_perl или mod_php4 сделать загрузку скрипта из файла и построение байткода _еще в головном апаче_, чтобы рабочие процессы реюзили готовый байткод. Если еще и это удастся сделать — вообще супер.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[3]: Потоки или процессы?
От: aka50 Россия  
Дата: 01.01.05 11:45
Оценка:
Здравствуйте, Geralt, Вы писали:

G>Большое спасибо за ответ.


A>>Сканер пишем?

G>Скорее чекер живых URL с некоторой дополнительной функциональностью.

G>>>2. Префорк, SysV IPC и однонаправленный канал.

A>>Приемлимо, но слишком простая задача, для этого... к тому же если надо сразу по 1000 ури сканить... 1000 процессов рожать?
G>На перле у меня получалось родить 100 процессов, но там каждый процесс включает в себя интерпретатор и весит около 5-8 метров. Плюс какие-то неясные проблемы с sysv IPC, которые не позволяли изменять шаровый массив размером более 10 элементов, поэтому приходилось действовать по следующей схеме: родитель проверяет пуст ли хеш параметров, если да, локает, пишет в него, анлокает. Дочерние процессы "набрасываются" на хеш. Тот, кто успевает его локнуть получает параметры, опустошает и анлокает. Родитель замечает, что хэш пуст и пишет в него новые значения. И т.д. Таким образом в секунду происходило 30-60 локов, анлоков и записей в шаровую переменную, что тоже очень сильно грузило систему.

G>>>4. Претрединг.

A>>Другое название Job Manager. Тоже что и 2, но тоже быстрее. И тоже тут избыточно.
G>В обще-то я склонялся к этому варианту т.к. считал его самым быстрым и наименее ресурсоемким.
A>>Для данной конкертной задачи это все нафиг не нужно.... быстрее всего будет работать FSM в одном процессе.
G>What does FSM mean? =)

Любой межпроцессный IPC довольно медленная штука... если нет супер необходимости не стоит ее использовать.
Такую архитектуру нужно использовать только для публичных сервисов, типа apache. Где нужна безопастность.
Если нужна именно скорость, то либо threads либо FSM. Finite State Machine. В простонародии "конечный автомат"
В принципе возможен вариант для многопроцессорных машин, когда таких FSM-процессов рождается по кол-ву процов.
Но сетевуха одна, по этому сильного выигрыша не получится.

A>>ЗЫ: там же есть ссылки на разные сканеры на этой либе... можете проверить сначала как это работает будете приятно удивлены.

G>Постараюсь проверить в ближайшее время. Учитывая тот факт, что единичным заданием является выполнение head запроса, а затем get в случае, если некоторые данные (время модификации, например) удовлетворяют некоторым критериям, каково количество заданий может обрабатываться в секунду (канал очень широкий =)?

Ограничения только по ширине канала. Т.е. допустим канал 300кб (по инету быстрее наврядли будет работать).
Время отклика сервера 35мс. Итого на скан одного сервера тратится (нижняя граница)
1. 35 * 3 = 105мс (syn+sack+ack)
2. 35 + 35 = 70мс (head)
Итого суммарный объем трафика будет где-то ~1к и 175мс на запрос.

Получаем при 300кб за 175мс = 300запросов. за секунду 300 * 1000 / 175 = 1714 запросов в секунду. или 10к в минуту.

Это естветвенно нижняя граница. В принципе ping сканер работает с такой скоростью на данной библиотеке, но там и пакетов всего 2 .
По этому реальная скорость будет где-то 1000 запростов в минуту (опять же зависит от опрашиваемых URL). Если они будут все тупить,
то одновременно можно хоть 10к сокетов открыть (на забуть FD_SETSIZE поправить). И однвовременно ждать со всех них ответ.
При этом это будет всго один процесс .

G>И, чтоб не создавать дополнительную тему, какие существуют библиотеки по типу libwww для перл (классы Request, Response, Cookies, работа с SSL и т.д.)?

С перлом работал очень давно... да и то на сторное сервера... там такое пользовать не приходилось.


ЗЫ: сорри если где-то прогнал , 1-е число однако .
Re[2]: Потоки или процессы?
От: aka50 Россия  
Дата: 01.01.05 11:50
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

G>>2. Префорк, SysV IPC и однонаправленный канал. Каждый дочерний процесс работает в


MSS>Я бы срисовал дизайн Апача. Префорк, и сокеты вместо SysV IPC. Можно UNIX-domain сокеты, если поддержка сети тут не нужна.

Сокеты хорошо, если объем передаваемых/принимаемых данных < 8k, иначе будут возникать блокировки на unix сокетах, потому как буфер в ядрах
разных ос разный и небольшой (процесс будет заблокирован, пока данные не будут считаны с другого конца или надо в nonBLOCK,
а это уже FSM).

MSS>А то и вовсе использовал бы Апач как таковой (специально запущенный) вместе с mod_perl, и слал бы ему вопросы на протоколе HTTP. Он бы там что-то делал, и выдавал мне ответ.

Апач — тормоз . Он слишком универсален.


MSS>Запрос выполняется 3 секунды в худшем случае. Значит, чтобы выполнить 30 запросов в секунду — надо 10 процессов. Это нормально и не тяжело.

Это очень много... дело не в 3 секундах... допустим надо просканить 100 урлов. В схеме с NONBLOCK connect можно просто поднять 100 коннектов и ждать
ответ 3 секунды. При этом всего один процесс.
Re[2]: Потоки или процессы?
От: Аноним  
Дата: 01.01.05 18:32
Оценка:
MSS>Запрос выполняется 3 секунды в худшем случае. Значит, чтобы выполнить 30 запросов в секунду — надо 10 процессов. Это нормально и не тяжело.

Нужно не 10, а 90 процессов.
Re: Потоки или процессы?
От: c-smile Канада http://terrainformatica.com
Дата: 01.01.05 19:03
Оценка:
Здравствуйте, Geralt, Вы писали:

Посмотри на curl и libcurl.
http://curl.haxx.se/
Насколько я понял это примерно то что тебе надо.
Re: Потоки или процессы?
От: achmed Удмуртия https://www.linkedin.com/in/nail-achmedzhanov-9907188/
Дата: 04.01.05 11:30
Оценка:
Здравствуйте, Geralt, Вы писали:

G>Необходимо реализовать приложение под UNIX <skip>


Если основное время работы клиентов заключается в ожидании
(при блокирующем чтении) то все можно реализовать в одном
процессе используя ассинхронные сокеты, так же можно было
сделать на perl.
Re[3]: Потоки или процессы?
От: Maxim S. Shatskih Россия  
Дата: 05.01.05 08:56
Оценка:
A>Сокеты хорошо, если объем передаваемых/принимаемых данных < 8k, иначе будут возникать блокировки на unix сокетах, потому как буфер в ядрах
A>разных ос разный и небольшой (процесс будет заблокирован, пока данные не будут считаны

Когда вопрошатель пишет вопрос, то остановки по ходу этого ему только полезны. А исполнитель должен читать вопрос, передав в read() как можно более гигантский буфер, тогда размер самого буфера в сокете будет пофиг.

То же самое и в обратную сторону.

Чем Апач тормоз для такой задачи — не знаю. Укажи узкие места, на которых будет пустопорожний простой в Апаче на такой задаче.
Занимайтесь LoveCraftом, а не WarCraftом!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.