如何将R自定义库安装至GCS以复用至Dataproc集群?
我之前也踩过这个坑,R的install.packages()确实不支持直接写入GCS路径——它只能识别本地文件系统的路径,gs://开头的GCS地址对它来说就是个“不可写的陌生路径”,所以才会报这个错误。下面是我亲测有效的解决思路,核心是把GCS存储桶挂载成集群节点的本地目录,让R以为是在操作本地文件,实际内容会自动同步到GCS:
步骤1:编写初始化动作脚本挂载GCS
Dataproc支持用初始化动作(Initialization Actions)在集群启动时自动执行脚本,我们可以用这个脚本安装gcsfuse(Google官方的GCS挂载工具),把目标GCS目录挂载到每个节点的本地路径。
创建一个名为mount_gcs_r_libs.sh的脚本,内容如下:
#!/bin/bash # 安装gcsfuse依赖并配置源 echo "deb http://packages.cloud.google.com/apt gcsfuse-bionic main" > /etc/apt/sources.list.d/gcsfuse.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - apt-get update -y apt-get install -y gcsfuse # 创建本地挂载目录(路径可以自定义,只要集群节点统一即可) LOCAL_MOUNT_DIR="/usr/local/lib/R/site-library/gcs_r_libs" mkdir -p $LOCAL_MOUNT_DIR # 挂载GCS存储桶的指定子目录到本地 # 替换成你的GCS桶名和目标子目录 gcsfuse --only-dir r_packages dummy_folder $LOCAL_MOUNT_DIR
把这个脚本上传到你的某个GCS存储桶(比如gs://your-config-bucket/scripts/mount_gcs_r_libs.sh),方便集群创建时调用。
步骤2:创建集群并执行初始化动作
用gcloud命令创建集群时,指定这个初始化动作脚本:
gcloud dataproc clusters create your-cluster-name \ --region us-central1 \ --initialization-actions gs://your-config-bucket/scripts/mount_gcs_r_libs.sh \ --service-account your-service-account@your-project.iam.gserviceaccount.com \ # 其他集群配置参数(比如机器类型、节点数等)
注意:确保你的Dataproc服务账号对dummy_folder桶有读写权限(至少包含storage.objects.*权限)。
步骤3:安装R包到挂载的本地目录
集群启动后,登录主节点或者通过Jupyter/RStudio连接,执行R命令时指定本地挂载目录作为库路径:
install.packages("caret", repos = "http://cran.us.r-project.org", dependencies = TRUE, lib='/usr/local/lib/R/site-library/gcs_r_libs/')
此时R会把包安装到本地挂载的目录,gcsfuse会自动把这些文件同步到GCS的gs://dummy_folder/r_packages/路径下。
步骤4:后续集群复用已安装的包
下次创建新集群时,同样使用上述初始化动作脚本挂载同一个GCS路径,然后在R代码开头添加一行,让R优先从挂载的GCS目录加载包:
# 把挂载目录加入R的库路径列表最前面 .libPaths(c('/usr/local/lib/R/site-library/gcs_r_libs/', .libPaths())) # 直接加载包即可,无需重新安装 library(caret)
注意事项
- 如果需要更新包,只需要在任意一个挂载了该GCS路径的集群上重新执行
install.packages,更新后的包会自动同步到GCS,所有后续集群都能直接使用。 gcsfuse挂载的目录在节点重启后会自动重新挂载(因为初始化动作会在集群启动时执行),不用担心路径失效。- 要是担心挂载性能,可以考虑使用Dataproc的集群存储卷结合GCS,但上面的方法已经足够满足大多数场景的需求。
内容的提问来源于stack exchange,提问作者Regressor

