qzs@master:/opt/module/spark-standalone$ sbin/start-all.sh starting org.apache.spark.deploy.master.Master, logging to /opt/module/spark-local/logs/spark-qzs-org.apache.spark.deploy.master.Master-1-master.out localhost: starting org.apache.spark.deploy.worker.Worker, logging to /opt/module/spark-local/logs/spark-qzs-org.apache.spark.deploy.worker.Worker-1-master.out localhost: failed to launch: nice -n 0 /opt/module/spark-local/bin/spark-class org.apache.spark.deploy.worker.Worker --webui-port 8081 spark://master:7077 localhost: at org.apache.spark.deploy.worker.Worker.main(Worker.scala) localhost: Caused by: java.lang.IllegalStateException: java.lang.NoSuchMethodException: java.nio.DirectByteBuffer.<init>(long,int) localhost: at org.apache.spark.unsafe.Platform.<clinit>(Platform.java:62) localhost: ... 16 more localhost: Caused by: java.lang.NoSuchMethodException: java.nio.DirectByteBuffer.<init>(long,int) localhost: at java.base/java.lang.Class.getConstructor0(Class.java:3761) localhost: at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2930) localhost: at org.apache.spark.unsafe.Platform.<clinit>(Platform.java:55) localhost: ... 16 more localhost: 25/03/30 22:58:52 INFO ShutdownHookManager: Shutdown hook called localhost: full log in /opt/module/spark-local/logs/spark-qzs-org.apache.spark.deploy.worker.Worker-1-master.out
时间: 2025-07-16 20:02:38 浏览: 10
<think>好的,用户现在遇到了启动Spark集群的问题。之前已经解决过Java版本的问题,现在运行start-all.sh时,Worker启动失败,报错是java.lang.NoSuchMethodException: java.nio.DirectByteBuffer.<init>(long,int)。需要分析原因并提供解决方案。
首先,用户提供的错误日志显示,问题出在Spark的Worker节点启动时,尝试调用java.nio.DirectByteBuffer的构造函数失败。根据错误信息,这个构造函数需要long和int参数,但Java版本可能不兼容。用户之前设置的是JDK 8,但可能Worker节点实际使用的Java版本不同。
回忆之前的对话,用户之前配置了JAVA_HOME为JDK8,但可能存在配置未完全生效的情况。此时需要检查Worker节点上的Java版本是否确实为8。可能用户虽然设置了JAVA_HOME,但PATH变量可能被覆盖,或者Spark启动脚本没有正确读取环境变量,导致使用了系统默认的Java版本,比如Java 21。
另外,错误中的java.base/java.lang.Class.getConstructor0(Class.java:3761)提示可能使用了Java 9及以上版本,因为Java 9模块化后,某些内部API被限制访问。DirectByteBuffer的构造函数在Java 8中存在,但在更高版本中可能被移除或无法访问,导致NoSuchMethodException。
接下来,可能的解决方案是确保所有节点都使用Java 8,并在Spark配置中显式指定JAVA_HOME。此外,检查Spark的启动脚本是否在Worker节点正确加载了环境变量,或者是否有其他配置文件覆盖了JAVA_HOME的设置。
用户可能没有意识到,虽然主节点配置正确,但Worker节点可能没有相同的配置,尤其是在分布式环境中。需要指导用户检查所有节点的Java版本,并统一配置。另外,可能需要调整Spark的环境脚本,如spark-env.sh,确保JAVA_HOME被正确设置。
还可能涉及到Spark版本与Java版本的兼容性问题,比如Spark某个版本可能需要特定Java版本。用户使用的Spark版本是否支持Java 8?如果用户尝试在Java 11或更高版本运行旧版Spark,可能会出现此类问题。需要确认Spark版本对应的Java要求,并建议用户使用兼容的组合。
此外,错误日志中的路径是/opt/module/spark-local,可能用户使用的是本地模式,但配置可能有误。需要检查spark-env.sh中的配置,确认JAVA_HOME是否正确导出,是否有其他参数影响。
总结步骤:1. 确认所有节点Java版本为8;2. 检查Spark配置中的JAVA_HOME;3. 添加--add-opens参数解决模块访问问题;4. 更新Spark或Java版本以兼容。</think>---
### **问题分析**
你尝试启动 Spark 集群时,Worker 进程启动失败,报错核心信息为:
```log
Caused by: java.lang.NoSuchMethodException: java.nio.DirectByteBuffer.<init>(long,int)
```
结合日志中的 `java.base` 路径(如 `java.base/java.lang.Class`),可以确定 **Worker 进程实际使用的 Java 版本是 Java 9+**(Java 9 开始引入模块化系统,`java.base` 是模块化后的包路径)。而 Spark 3.x 及以下版本在 Java 11+ 中运行时,可能因反射访问受限出现此问题。
---
### **原因定位**
1. **Java 版本冲突**:
- 虽然你通过 `JAVA_HOME` 指定了 Java 8,但 Worker 进程可能未正确继承该配置,实际仍使用系统默认的 Java 21(如 OpenJDK 21)。
- **关键证据**:日志中 `java.base` 表明使用了 Java 9+,而 Java 8 的包路径为 `java.lang.Class`(无模块名)。
2. **Spark 版本与 Java 版本不兼容**:
- Spark 3.2 及以下版本默认兼容 Java 8,对 Java 11+ 需要额外配置(如添加 `--add-opens` 参数)。
- 如果你使用的 Spark 版本较旧,直接运行在 Java 11+ 上会因模块访问限制报错。
---
### **解决方案**
#### **方法 1:强制所有节点使用 Java 8**
确保 **所有节点(包括 Master 和 Worker)** 的默认 Java 版本为 8:
1. 检查全局 Java 版本:
```bash
java -version # 应显示 Java 8
update-alternatives --config java # 切换默认 Java 版本到 8
```
2. 在 Spark 配置文件中显式指定 `JAVA_HOME`:
编辑 `spark-env.sh`(位于 `$SPARK_HOME/conf/`):
```bash
export JAVA_HOME=/opt/module/jdk1.8.0_361
export PATH=$JAVA_HOME/bin:$PATH
```
3. 重启 Spark 集群:
```bash
sbin/stop-all.sh
sbin/start-all.sh
```
---
#### **方法 2:兼容 Java 11+(若必须使用高版本 Java)**
在 `spark-defaults.conf` 中添加 JVM 参数,允许反射访问 `DirectByteBuffer` 的构造函数:
```bash
spark.executor.extraJavaOptions --add-opens=java.base/java.nio=ALL-UNNAMED
spark.driver.extraJavaOptions --add-opens=java.base/java.nio=ALL-UNNAMED
```
重启集群后验证是否生效。
---
#### **方法 3:升级 Spark 版本**
Spark 3.3+ 已修复 Java 11+ 兼容性问题。建议升级 Spark 版本:
```bash
# 下载 Spark 3.5.1(截至 2024 年 3 月的最新稳定版)
wget https://archive.apache.org/dist/spark/spark-3.5.1/spark-3.5.1-bin-hadoop3.tgz
# 解压并替换旧版本
tar -zxvf spark-3.5.1-bin-hadoop3.tgz -C /opt/module/
```
---
### **操作验证**
1. 检查 Worker 日志(路径在报错中给出):
```bash
tail -n 50 /opt/module/spark-local/logs/spark-qzs-org.apache.spark.deploy.worker.Worker-1-master.out
```
确认日志中无 `NoSuchMethodException` 报错。
2. 访问 Spark Web UI(默认端口 8080),确认 Worker 节点已正常注册。
---
### **总结**
- **核心问题**:Spark 进程实际使用了 Java 11+,但代码依赖 Java 8 的 `DirectByteBuffer` 构造函数。
- **推荐方案**:统一使用 Java 8(方法 1),或升级 Spark 到 3.3+(方法 3)。
- **临时规避**:通过 `--add-opens` 绕过模块限制(方法 2)。
阅读全文
相关推荐


















