我的要求是通过Java Webservice执行R脚本。 Web服务需要50的并发性。
我们正在使用RServe从Java代码执行R脚本。为了实现这一点,在linux服务器中,我们创建了50个RServe实例实例,从不同的端口启动。在java应用程序内部,创建了一个包含50个RConnection对象的连接池,每个对象都链接到创建的一个RServe实例。对于每次执行,我们从池中获取RConnection,执行R脚本,获取响应值,然后将RConnection返回到池中。
当我们通过单个用户访问来执行webservice时,R执行在1秒内完成。但是,如果我尝试以50的并发性运行相同的Web服务,则在RServe中执行R脚本大约需要30秒。 由于如果用单个用户执行实际的R执行只需1秒,我认为我对RServe做错了。任何指针都会有所帮助。
答案 0 :(得分:0)
虽然我认为最好在Linux上使用一个Rserve实例并让它只是为了并行处理而分叉子进程,但它可能根本不会加速处理。 从您的问题来看,尚不清楚应用程序是否被集中使用,并且是否正在不断处理许多并发请求。如果是这种情况,我假设你的R代码是CPU密集型的,不同的进程只需要共享CPU时间,增加完成所需的时钟时间。
我测试了这种情况,并使用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%,因此所有这些都将仅分配CPU时间的十分之一和因此,与仅使用一个Rserve实例的情况相比,完成时间将缩短10倍。
这不会长20倍,因为单个Rserve进程只会使用一个CPU内核,而另一个内核会“休眠”。
如果你想加快计算,你只需要更多的CPU。此外,如果您不希望拒绝第51个(或第101个或第1001个)并发用户访问,则最好实现消息队列。您可以为队列创建多个worker,这可以在不同的计算机上分配多个CPU的工作负载。