【问题标题】:RServe - Scalability relatedRServe - 可扩展性相关
【发布时间】:2015-09-01 20:06:29
【问题描述】:

我的要求是通过 Java Webservice 执行 R 脚本。 webservice需要50并发。

我们正在使用 RServe 从 Java 代码中执行 R 脚本。为此,在 linux 服务器中,我们创建了 50 个 RServe 实例,从不同的端口启动。在 java 应用程序内部,创建了一个包含 50 个 RConnection 对象的连接池,每个对象都链接到一个 RServe 实例 created 。对于每次执行,我们从池中获取一个 RConnection,执行 R 脚本,获取响应值,然后将 RConnection 返回到池中。

当我们执行单用户访问的 web 服务时,R 执行在 1 秒内完成。但是,如果我尝试以 50 的并发性运行相同的 Web 服务,则在 RServe 中执行 R 脚本大约需要 30 秒。 由于如果使用单个用户执行实际的 R 执行只需要 1 秒,我认为我对 RServe 做错了什么。任何指针都会有所帮助。

【问题讨论】:

  • RServe 不是根据需要分叉吗?只需启动一个并通过最多 50 个请求来实现它...
  • 我理解的方式是,RServe 将一次接受一个传入请求。这不正确吗?即使我有 50 个实例,为什么进程变慢也是我试图理解的原因
  • 仅在 Windows 上,希望您不要将其用作后端。
  • 不,这不在 Windows 上。这是否意味着我可以创建许多指向一个 RServe 实例的 RConnection 实例。不过,为什么这会解决我的问题?只是好奇,当我通过 RServe 执行 R 时,它是否会创建可能使其变慢的新进程?
  • RServe 一次可以处理多个连接。事实上,它被设计用来处理并发性。我已经使用它几个星期了,我只使用一个 RServe 实例来处理所有连接没有任何问题。您是否尝试过只使用一个 RServe?也许操作系统过载了,因为每个进程都需要自己的内存空间和资源。我使用一个 RServe 进行瘦身,这是一种更好的方法,并让它使用 unix 线程处理每个连接

标签: r rjava rserve


【解决方案1】:

虽然我认为最好在 Linux 上使用一个 Rserve 实例,让它只 fork 子进程进行并行处理,但它可能根本无法加快处理速度。 从您的问题来看,尚不清楚该应用程序是否被密集使用并且正在不断处理许多并发请求。如果是这种情况,我假设您的 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%,因此所有进程将仅分配 1/10 的 CPU 时间,并且因此,与仅使用一个 Rserve 实例的情况相比,完成时间将增加 10 倍。

这不是长 20 倍,因为单个 Rserve 进程只会使用一个 CPU 内核,而让另一个内核“休眠”。

如果您想加快计算速度,您只需要更多的 CPU。此外,如果您不希望第 51 个(或第 101 个或第 1001 个)并发用户被拒绝访问,最好实现一个消息队列。您可以为队列创建多个工作人员,这可以将工作负载分配到不同机器上的多个 CPU 上。

【讨论】:

  • 您能否详细说明“正如您所看到的,进程具有相同的优先级,并且%CPU 的份额几乎相等。与只有一个 Rserve 实例的情况。这不是 20 次,因为单个 Rserve 进程只会使用一个 CPU 内核。”
  • @ChintanShah,在最后一段详细说明。
猜你喜欢
  • 1970-01-01
  • 2014-02-06
  • 2012-06-03
  • 2013-04-02
  • 1970-01-01
  • 2013-04-08
  • 2010-09-17
  • 2012-10-25
  • 2010-10-04
相关资源
最近更新 更多