为集群上的所有节点开启所有 CPU:snow/snowfall 包

Posted

技术标签:

【中文标题】为集群上的所有节点开启所有 CPU:snow/snowfall 包【英文标题】:Turn on all CPUs for all nodes on a cluster: snow/snowfall package 【发布时间】:2014-10-11 19:08:03 【问题描述】:

我正在开发一个集群,我正在使用snowfall 包在 5 个节点上建立一个套接字集群,每个节点有 40 个 CPU,使用以下命令:

 > sfInit(parallel=TRUE, cpus = 200, type="SOCK", socketHosts=c("host1", "host2", "host3", "host4", "host5"));
 R Version:  R version 3.1.0 (2014-04-10) 

 snowfall 1.84-6 initialized (using snow 0.3-13): parallel execution on 5 CPUs.

当我查看集群报告时,我发现从服务器上的负载比预期的要低得多,并且对它说“在 5 个 CPU 上并行执行”而不是“在 200 个 CPU 上并行执行”这一事实感到不安。这仅仅是对 CPU 的模棱两可的引用,还是每个主机只运行一个 CPU?

编辑:这是一个为什么这与我有关的示例,如果我只使用本地机器并指定最大内核数,我有:

 > sfInit(parallel=TRUE, type="SOCK", cpus = 40);
 snowfall 1.84-6 initialized (using snow 0.3-13): parallel execution on 40 CPUs.

我在单节点 40 CPU 集群上运行相同的作业,耗时 1.4 分钟,而 5 节点,显然 5 CPU 集群耗时 5.22 分钟。对我来说,这证实了我的怀疑,即我在 5 个节点上并行运行,但每个节点上只打开 1 个 CPU。

然后我的问题是:如何打开所有 CPU 以供所有可用节点使用?

编辑:@SimonG 我使用了底层snow 包的初始化,我们可以清楚地看到只有5个节点被打开:

 > cl <- makeSOCKcluster(names = c("host1", "host2", "host3", "host4", "host5"), count = 200)
 > clusterCall(cl, runif, 3)
 [[1]]
 [1] 0.9854311 0.5737885 0.8495582

 [[2]]
 [1] 0.7272693 0.3157248 0.6341732

 [[3]]
 [1] 0.26411931 0.36189866 0.05373248

 [[4]]
 [1] 0.3400387 0.7014877 0.6894910

 [[5]]
 [1] 0.2922941 0.6772769 0.7429913

 > stopCluster(cl)
 > cl <- makeSOCKcluster(names = rep("localhost", 40), count = 40)
 > clusterCall(cl, runif, 3)
 [[1]]
 [1] 0.6914666 0.7273244 0.8925275

 [[2]]
 [1] 0.3844729 0.7743824 0.5392220

 [[3]]
 [1] 0.2989990 0.7256851 0.6390770     

 [[4]]
 [1] 0.07114831 0.74290601 0.57995908

 [[5]]
 [1] 0.4813375 0.2626619 0.5164171

 .
 .
 .

 [[39]]
 [1] 0.7912749 0.8831164 0.1374560

 [[40]]
 [1] 0.2738782 0.4100779 0.0310864

我认为这很清楚地表明了这一点。我绝望地尝试了这个:

 > cl <- makeSOCKcluster(names = rep(c("host1", "host2", "host3", "host4", "host5"), each = 40), count = 200)

并且可以预见地得到:

 Error in socketConnection(port = port, server = TRUE, blocking = TRUE,  : 
   all connections are in use

【问题讨论】:

对此的一些想法:(1.) snowfall 默认情况下将免费使用的 CPU 数量限制为 32 个。有一个命令 (sfSetMaxCPUs) 可以更改它。 (2.) 要测试您的集群是否有效,您使用的示例作业可能不够充分。该作业在一台机器上运行一小段时间。假设主机之间的通信在这里没有保存任何东西实际上是合理的。 据我了解,您担心cpus 参数可能不起作用,给出了socketHosts 的数量。您应该通过制作一个 CPU 密集型且内存和 HDD 较低的作业来更彻底地对此进行基准测试。然后您尝试不同的组合(一台主机、两台主机...... 2 个 CPU、4、8、16......)。这将为您提供更好的基础来判断您的集群是否正常工作。否则很难判断是集群造成的性能成本还是仅是任务造成的性能成本(这可能过于简单或提出错误的要求,从而提高了并行计算的成本。) 【参考方案1】:

在彻底阅读了snow 文档后,我想出了一个(部分)解决方案。

我读到分布式 R 版本一次只能打开 128 个连接,并且发现这是真的。我可以在每个节点上打开 25 个 CPU,但如果我尝试在每个节点上启动 26 个,集群将无法启动。这是需要传递给makeCluster的主机列表的正确结构:

> library(snow);

> unixHost13 <- list(host = "host1");
> unixHost14 <- list(host = "host2");
> unixHost19 <- list(host = "host3");
> unixHost29 <- list(host = "host4");
> unixHost30 <- list(host = "host5");

> kCPUs <- 25;
> hostList <- c(rep(list(unixHost13), kCPUs), rep(list(unixHost14), kCPUs),               rep(list(unixHost19), kCPUs), rep(list(unixHost29), kCPUs), rep(list(unixHost30), kCPUs));
> cl <- makeCluster(hostList, type = "SOCK")
> clusterCall(cl, runif, 3)
[[1]]
[1] 0.08430941 0.64479036 0.90402362

[[2]]
[1] 0.1821656 0.7689981 0.2001639

[[3]]
[1] 0.5917363 0.4461787 0.8000013
.
.
.
[[123]]
[1] 0.6495153 0.6533647 0.2636664

[[124]]
[1] 0.75175580 0.09854553 0.66568129

[[125]]
[1] 0.79336203 0.61924813 0.09473841

我发现一个参考资料说,为了建立连接,需要在 NCONNECTIONS 设置更高的情况下重建 R(请参阅here)。

【讨论】:

以上是关于为集群上的所有节点开启所有 CPU:snow/snowfall 包的主要内容,如果未能解决你的问题,请参考以下文章

将节点添加到 Cassandra 集群会导致现有节点上的 CPU 过载

EMR Hadoop 并未利用所有集群节点

Nodejs利用所有CPU上的所有核心

redis模型:集群

Redis Cluster集群的搭建

Redis实战-Redis集群环境搭建(手动搭建)