在 Windows 上运行 Apache Hadoop 或 Spark/GeoTrellis 涉及 HDFS 或文件系统操作时的经典问题
您遇到的错误是 在 Windows 上运行 Apache Hadoop 或 Spark/GeoTrellis 涉及 HDFS 或文件系统操作时的经典问题。
错误信息 java.io.FileNotFoundException: Could not locate Hadoop executable: C:\Users\Patch\AppData\Local\Temp\bin\winutils.exe
非常明确地指出了问题所在。
这是因为您的 GeoTrellis/Spark 代码在执行 FileSystem.get(sc.hadoopConfiguration).mkdirs(outputDir)
等操作时,底层调用了 Hadoop 的文件系统 API。在 Windows 环境下,Hadoop 需要一个名为 winutils.exe
的特殊工具来模拟 Linux 的文件权限和操作,但它无法在您的临时目录中找到该文件。
解决方案:配置 winutils.exe
解决此问题的标准且最简单的方法是下载正确的 Hadoop Windows 二进制文件,并配置您的系统或 Spark 应用程序指向它们。
步骤 1: 下载 winutils.exe
您需要下载与您使用的 Hadoop 版本 兼容的 winutils.exe
和相关二进制文件。
- 确定 Hadoop 版本: 检查您的 Spark 或 GeoTrellis 依赖中使用的 Hadoop 版本(例如,通常是 Hadoop 2.7.x 或 3.x)。
- 下载二进制文件: 搜索并下载对应版本的 Hadoop Windows 二进制文件包。
- 一个常用的资源是 steveloughran/winutils 的 GitHub 仓库,其中包含了常见版本的编译好的二进制文件。
步骤 2: 创建本地 Hadoop 目录
在您的本地文件系统上创建一个专用的目录来存放这些文件。
- 创建一个目录,例如:
C:\hadoop\bin
。 - 将下载的
winutils.exe
和hadoop.dll
(如果存在)放到C:\hadoop\bin
目录下。
步骤 3: 配置 Spark/Hadoop 环境变量
您可以通过两种方式告诉 Spark/Hadoop 您的 winutils.exe
在哪里:
选项 A (推荐): 设置系统环境变量
这是最彻底的解决方案,对所有 Spark 应用都有效。
-
设置
HADOOP_HOME
环境变量:- 变量名:
HADOOP_HOME
- 变量值:
C:\hadoop
(指向您创建的根目录,不是bin
目录)
- 变量名:
-
更新
Path
环境变量:- 将
%HADOOP_HOME%\bin
添加到您的系统Path
环境变量中。
- 将
选项 B: 运行时配置 SparkContext
如果您无法修改系统环境变量,可以在代码中配置 Spark 运行时。您需要在创建 SparkContext
之前设置 Hadoop 配置。
在您的测试代码或初始化 SparkContext 的地方(例如 SparkTestBase
或您的 main
函数),添加以下代码:
scala
// 导入 Hadoop Configuration
import org.apache.hadoop.conf.Configuration
// 在创建 SparkContext 之前执行此操作
val hadoopHomeDir = "C:\\hadoop" // 替换为您 winutils.exe 所在的根目录
System.setProperty("hadoop.home.dir", hadoopHomeDir)
// (如果您的程序已经创建了 SparkContext,则可以直接配置)
// val conf = new Configuration()
// conf.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName)
// conf.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName)
// ... 正常创建 SparkContext
// implicit val sc: SparkContext = new SparkContext(...)
总结和快速检查
完成设置后,请重启您的 IDE (IntelliJ IDEA, Eclipse 等),以便新的环境变量生效。
检查项 | 值/路径 | 目的 |
---|---|---|
HADOOP_HOME |
C:\hadoop |
指向 Hadoop 根目录 |
%HADOOP_HOME%\bin |
C:\hadoop\bin |
包含 winutils.exe |
winutils.exe |
位于 C:\hadoop\bin |
允许 Hadoop 在 Windows 上执行文件权限操作 |
解决这个 winutils.exe
缺失的问题后,您的 Spark/GeoTrellis 代码就应该能够成功创建本地文件系统中的目录(如 test/png_pyramid_test/png_test_layer
)并继续执行后续的瓦片生成和保存操作了。