RServe — связанный с масштабируемостью

Мое требование - выполнить сценарий R через веб-службу Java. Веб-службе требуется параллелизм 50.

Мы используем RServe для выполнения сценария R из кода Java. Для этого на сервере linux мы создали 50 экземпляров экземпляров RServe, запущенных на разных портах. Внутри Java-приложения создан пул соединений с 50 объектами RConnection, каждый из которых связан с одним из созданных экземпляров RServe . Для каждого выполнения мы извлекаем RConnection из пула, выполняем сценарий R, получаем значение ответа и затем возвращаем RConnection в пул.

Когда мы запускаем веб-сервис с доступом к одному пользователю, выполнение R завершается за 1 секунду. Однако, если я попытаюсь запустить тот же веб-сервис с параллелизмом 50, выполнение сценария R внутри RServe займет около 30 секунд. Поскольку фактическое выполнение R занимает всего 1 секунду, если выполняется с одним пользователем, я думаю, что я делаю что-то не так с RServe. Любые указатели помогут.


person Vaya    schedule 01.09.2015    source источник
comment
Разве RServe не разветвляется по мере необходимости? Просто запустите один и нажмите до 50 запросов...   -  person Dirk Eddelbuettel    schedule 01.09.2015
comment
Насколько я понял, RServe будет принимать по одному входящему запросу за раз. Разве это не правильно? Даже если у меня есть 50 экземпляров, я пытаюсь понять, почему процесс идет медленно.   -  person Vaya    schedule 01.09.2015
comment
Только в Windows, которую, я надеюсь, вы не используете в качестве бэкэнда.   -  person Dirk Eddelbuettel    schedule 01.09.2015
comment
Нет, это не на окнах. Значит ли это, что я могу создать множество экземпляров RConnection, указывающих на один экземпляр RServe. Тем не менее, почему это решит мою проблему? Просто любопытно, когда я запускаю R через RServe, создает ли он новый процесс, который может замедлять его работу?   -  person Vaya    schedule 02.09.2015
comment
RServe может обрабатывать более одного соединения одновременно. Фактически, он был разработан для работы с параллелизмом. Я использовал его в течение нескольких недель, и у меня не было проблем с использованием только одного экземпляра RServe для обработки всех подключений. Вы пробовали использовать только один RServe? Возможно, ОС перегружена, потому что каждому процессу нужно свое пространство памяти и ресурсы. Я думаю, что с помощью одного RServe это лучший подход, и пусть он обрабатывает каждое соединение с использованием потоков unix.   -  person jfcorugedo    schedule 22.09.2015


Ответы (1)


Хотя я думаю, что лучше всего использовать один экземпляр Rserve в Linux и позволить ему просто разветвлять подпроцессы для параллельной обработки, это может совсем не ускорить обработку. Из вашего вопроса неясно, интенсивно ли используется приложение, и много одновременных запросов обрабатываются постоянно. Если это так, я предполагаю, что ваш код R интенсивно использует ЦП, и различные процессы просто должны совместно использовать процессорное время, увеличивая время, необходимое для завершения.

Я протестировал именно такой сценарий и нашел эти результаты с top

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
33839 *****     20   0  269792  57104   3496 R  10.3  1.5   0:15.33 Rserve
33847 *****     20   0  269776  57100   3496 R  10.3  1.5   0:09.86 Rserve
33849 *****     20   0  269792  57104   3496 R  10.3  1.5   0:08.20 Rserve
33855 *****     20   0  269528  56840   3496 R  10.3  1.5   0:04.92 Rserve
29725 *****     20   0  268872  56836   4020 R  10.0  1.5   1360:13 Rserve
33841 *****     20   0  269784  57100   3496 R  10.0  1.5   0:14.42 Rserve
33843 *****     20   0  269796  57104   3496 R  10.0  1.5   0:12.50 Rserve
33844 *****     20   0  269792  57104   3496 R  10.0  1.5   0:11.72 Rserve
33852 *****     20   0  269512  56836   3496 R  10.0  1.5   0:06.38 Rserve
33856 *****     20   0  269520  56836   3496 R  10.0  1.5   0:04.05 Rserve
33842 *****     20   0  269776  57100   3496 R   9.3  1.5   0:13.20 Rserve
33851 *****     20   0  269784  57100   3496 R   9.3  1.5   0:06.69 Rserve
33857 *****     20   0  269512  56836   3496 R   9.3  1.5   0:03.15 Rserve
33834 *****     20   0  269792  57112   3496 R   9.0  1.5   0:18.56 Rserve
33835 *****     20   0  269784  57100   3496 R   9.0  1.5   0:17.33 Rserve
33837 *****     20   0  269776  57100   3496 R   9.0  1.5   0:16.46 Rserve
33846 *****     20   0  269784  57100   3496 R   9.0  1.5   0:10.17 Rserve
33848 *****     20   0  269796  57104   3496 R   9.0  1.5   0:08.61 Rserve
33853 *****     20   0  269532  56840   3496 R   9.0  1.5   0:05.34 Rserve
33858 *****     20   0  269532  56840   3496 R   9.0  1.5   0:02.27 Rserve
33838 *****     20   0  269796  57104   3496 R   8.6  1.5   0:15.74 Rserve

Сумма %CPU составляет 200%, что соответствует двум доступным ядрам CPU.

Как видите, процессы имеют одинаковый приоритет (PR=20), а доли %CPU почти равны, около 10%, так что всем им будет выделено только 1/10 часть процессорного времени и, следовательно, они займут В 10 раз больше времени на выполнение по сравнению со случаем всего с одним экземпляром Rserve.

Это не в 20 раз дольше, потому что один процесс Rserve будет использовать только одно ядро ​​ЦП, оставляя другое ядро ​​«спящим».

Вам просто нужно больше процессоров, если вы хотите ускорить вычисления. Кроме того, если вы не хотите, чтобы 51-му (или 101-му, или 1001-му) одновременно работающему пользователю было отказано в доступе, лучше реализовать очередь сообщений. Вы можете создать несколько рабочих для очереди, которые могут распределять рабочую нагрузку между многими процессорами на разных машинах.

person R. Schreurs    schedule 24.11.2016
comment
Можно, пожалуйста, поподробнее? Как видите, процессы имеют одинаковый приоритет, и доли %CPU практически равны. Все они будут выполняться в 10 раз дольше, чем в случае с одним экземпляром Rserve. Это не 20 раз, потому что один процесс Rserve будет использовать только одно ядро ​​ЦП. - person Chintan Shah; 01.10.2017
comment
@ChintanShah, уточнил последний абзац. - person R. Schreurs; 02.10.2017