最近开始使用xgboost on spark跑模型,当准备设置useExternalMemory这个参数时,大致意思是是否使用额外的内存,于是果断设置了true。
但当我在spark集群中提交任务时,跑了很多次,都报/tmp目录存储不够,任务失败。每次跑失败,各种磁盘告警,/tmp目录其实也有20G的存储(这里已经指定了spark.local.dir的目录)。于是,到机器上去看目录下到底生成了啥,看到了好几个34-cache-xxxx的目录。进入文件目录,里面几个大文件,且文件名包含training或者test,可能缓存的是训练集和测试集样本。
但是,我的训练集和测试集是缓存到内存的,根本不可能写入磁盘。这是为什么呢?于是,搜索xgboost on spark(0.72)中的源代码。找到了如下内容:
ml.dmlc.xgboost4j.scala.spark.XGBoost.scala 123行 val taskId = TaskContext.getPartitionId().toString val cacheDirName = if (useExternalMemory) { val dir = Files.createTempDirectory(s"${TaskContext.get().stageId()}-cache-$taskId") Some(dir.toAbsolutePath.toString) } else { None }
看到上面的代码,就可以知道了,当你设置了useExternalMemory后,会将样本信息缓存到/tmp目录下。这个坑真是太大了,估计作者也不知道本地有什么目录,就使用了/tmp目录吧。但是,最大的问题,应该是我没理解好这个参数的含义。
这个参数的英文解释如下:
indicate whether to use external memory cache, by setting this flag as true, the user may save the RAM cost for running XGBoost within Spark。
我翻译大概就是:该参数指定是否需要使用额外的内存,用来节省xgboost中使用的内存资源。
其实我后面想了想memory并不是指内存,而是指存储器。也就是这句话应该这样翻译:
通过将此标志设置为true来指示是否使用外部存储器(也就是指磁盘咯)缓存,用户可以节省在Spark中运行XGBoost的RAM(内存)成本
原来RAM才是内存,memory是指存储器。 如果大家也遇到这个坑,赶紧避开了。将useExternalMemory设置为false,不然xgboost可要用本地/tmp目录作为磁盘缓存,来节省内存。