The root scratch dir: /tmp/hive on HDFS should be writable. Current permissions are: rw-rw-rw-

本文介绍了解决在Windows 10系统上运行Spark Shell时出现的java.lang.NullPointerException问题的方法。该错误通常由缺少winutils.exe文件引起,此文件对于初始化Hive上下文至关重要。文章提供了下载和配置所需文件的具体步骤。

It is easy to follow the instructions on http://spark.apache.org/docs/latest/ and download Spark 1.6.0 (Jan 04 2016) with the “Pre-build for Hadoop 2.6 and later” package type from http://spark.apache.org/downloads.html

image

However, when you try to run spark-shell on your Windows 10 (64-bit) machine, you may receive a java.lang.RuntimeException: java.lang.NullPointerException (not found: value sqlContext)

java.lang.RuntimeException: java.lang.NullPointerException
        at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:522)
at org.apache.spark.sql.hive.client.ClientWrapper.<init>(ClientWrapper.scala:194)
at org.apache.spark.sql.hive.client.IsolatedClientLoader.createClient(IsolatedClientLoader.scala:238)
at org.apache.spark.sql.hive.HiveContext.executionHive$lzycompute(HiveContext.scala:218)
at org.apache.spark.sql.hive.HiveContext.executionHive(HiveContext.scala:208)
at org.apache.spark.sql.hive.HiveContext.functionRegistry$lzycompute(HiveContext.scala:462)
at org.apache.spark.sql.hive.HiveContext.functionRegistry(HiveContext.scala:461)
at org.apache.spark.sql.UDFRegistration.<init>(UDFRegistration.scala:40)
at org.apache.spark.sql.SQLContext.<init>(SQLContext.scala:330)
at org.apache.spark.sql.hive.HiveContext.<init>(HiveContext.scala:90)
at org.apache.spark.sql.hive.HiveContext.<init>(HiveContext.scala:101)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.apache.spark.repl.SparkILoop.createSQLContext(SparkILoop.scala:1028)
at $iwC$$iwC.<init>(<console>:15)
at $iwC.<init>(<console>:24)
at <init>(<console>:26)
at .<init>(<console>:30)
at .<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.spark.repl.SparkIMain$ReadEvalPrint.call(SparkIMain.scala:1065)
at org.apache.spark.repl.SparkIMain$Request.loadAndRun(SparkIMain.scala:1346)
at org.apache.spark.repl.SparkIMain.loadAndRunReq$1(SparkIMain.scala:840)
at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:871)
at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:819)
at org.apache.spark.repl.SparkILoop.reallyInterpret$1(SparkILoop.scala:857)
at org.apache.spark.repl.SparkILoop.interpretStartingWith(SparkILoop.scala:902)
at org.apache.spark.repl.SparkILoop.command(SparkILoop.scala:814)
at org.apache.spark.repl.SparkILoopInit$$anonfun$initializeSpark$1.apply(SparkILoopInit.scala:132)
at org.apache.spark.repl.SparkILoopInit$$anonfun$initializeSpark$1.apply(SparkILoopInit.scala:124)
at org.apache.spark.repl.SparkIMain.beQuietDuring(SparkIMain.scala:324)
at org.apache.spark.repl.SparkILoopInit$class.initializeSpark(SparkILoopInit.scala:124)
at org.apache.spark.repl.SparkILoop.initializeSpark(SparkILoop.scala:64)
at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1$$anonfun$apply$mcZ$sp$5.apply$mcV$sp(SparkILoop.scala:974)
at org.apache.spark.repl.SparkILoopInit$class.runThunks(SparkILoopInit.scala:159)
at org.apache.spark.repl.SparkILoop.runThunks(SparkILoop.scala:64)
at org.apache.spark.repl.SparkILoopInit$class.postInitialization(SparkILoopInit.scala:108)
at org.apache.spark.repl.SparkILoop.postInitialization(SparkILoop.scala:64)
at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply$mcZ$sp(SparkILoop.scala:991)
at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945)
at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945)
at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
at org.apache.spark.repl.SparkILoop.org$apache$spark$repl$SparkILoop$$process(SparkILoop.scala:945)
at org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:1059)
at org.apache.spark.repl.Main$.main(Main.scala:31)
at org.apache.spark.repl.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.NullPointerException
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1012)
at org.apache.hadoop.util.Shell.runCommand(Shell.java:482)
at org.apache.hadoop.util.Shell.run(Shell.java:455)
at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:715)
at org.apache.hadoop.util.Shell.execCommand(Shell.java:808)
at org.apache.hadoop.util.Shell.execCommand(Shell.java:791)
at org.apache.hadoop.fs.FileUtil.execCommand(FileUtil.java:1097)
at org.apache.hadoop.fs.RawLocalFileSystem$DeprecatedRawLocalFileStatus.loadPermissionInfo(RawLocalFileSystem.java:582)
at org.apache.hadoop.fs.RawLocalFileSystem$DeprecatedRawLocalFileStatus.getPermission(RawLocalFileSystem.java:557)
at org.apache.hadoop.hive.ql.session.SessionState.createRootHDFSDir(SessionState.java:599)
at org.apache.hadoop.hive.ql.session.SessionState.createSessionDirs(SessionState.java:554)
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:508)
… 62 more

<console>:16: error: not found: value sqlContext
import sqlContext.implicits._
^
<console>:16: error: not found: value sqlContext
import sqlContext.sql

image

This issue is often caused by a missing winutils.exe file that Spark needs in order to initialize the Hive context, which in turn depends on Hadoop, which requires native libraries on Windows to work properly. Unfortunately, this happens even if you are using Spark in local mode without utilizing any of the HDFS features directly.

To resolve this problem, you need to:

  • download the 64-bit winutils.exe (106KB)
  • copy the downloaded file winutils.exe into a folder like C:\hadoop\bin (or C:\spark\hadoop\bin)
  • set the environment variable HADOOP_HOME to point to the above directory but without \bin. For example:
    • if you copied the winutils.exe to C:\hadoop\bin, set HADOOP_HOME=C:\hadoop
    • if you copied the winutils.exe to C:\spark\hadoop\bin, set HADOOP_HOME=C:\spark\hadoop

image

Double-check that the environment variable HADOOP_HOME is set properly by opening the Command Prompt and running echo %HADOOP_HOME%

image

You will also notice that when starting the spark-shell.cmd, Hive will create a C:\tmp\hive folder. If you receive any errors related to permissions of this folder, use the following commands to set that permissions on that folder:

  • List current permissions: %HADOOP_HOME%\bin\winutils.exe ls \tmp\hive
  • Set permissions: %HADOOP_HOME%\bin\winutils.exe chmod 777 \tmp\hive
  • List updated permissions: %HADOOP_HOME%\bin\winutils.exe ls \tmp\hive

image

When you re-run the spark-shell, it should work as expected.

image

Related Spark JIRAs and StackOverflow threads:

I’m looking forward to your feedback and questions via Twitter https://twitter.com/ArsenVlad

Tags  Spark Windows 10
<think> 我们遇到了Hive运行时关于HDFS目录`/tmp/hive`的权限问题。错误信息明确指出:`The root scratch dir: /tmp/hive on HDFS should be writable. Current permissions are: rwxr-xr-x`。虽然当前权限`rwxr-xr-x`(即755)允许所有用户读取和执行,但**写入权限**仅对所有者开放。因此,我们需要确保运行Hive的用户(这里是root)对该目录有写入权限。 ### 解决方案步骤 #### 1. 确认当前目录权限 首先,我们检查HDFS上`/tmp/hive`目录的当前权限: ```bash hdfs dfs -ls /tmp ``` 如果输出显示`/tmp/hive`的权限是`drwxr-xr-x`,则验证了错误信息。 #### 2. 修改目录权限(推荐方法) 我们需要为目录添加组或其他用户的写入权限。以下是两种安全的方法: **方法一:为组用户添加写入权限(推荐)** ```bash hdfs dfs -chmod g+w /tmp/hive ``` 此命令将组用户的权限从`r-x`变为`rwx`(如果目录的组是`supergroup`,且运行Hive的用户属于该组,则有效)。 **方法二:为所有用户添加写入权限(宽松,适用于测试环境)** ```bash hdfs dfs -chmod 777 /tmp/hive ``` > **注意**:在生产环境中,应避免使用777权限,以保持安全性。 #### 3. 验证修改结果 再次检查权限: ```bash hdfs dfs -ls /tmp ``` 期望输出(方法一): ``` drwxrwxr-x ... /tmp/hive ``` 或(方法二): ``` drwxrwxrwx ... /tmp/hive ``` #### 4. 重新运行Hive 尝试执行Hive命令,验证问题是否解决: ```bash hive -e "SHOW DATABASES;" ``` ### 永久解决方案:更改Hive的临时目录 为了避免系统目录`/tmp/hive`的权限冲突,我们可以自定义Hive的临时目录: #### 1.HDFS上创建专用目录 ```bash # 创建目录(以root用户操作HDFS,或使用hdfs用户) sudo -u hdfs hdfs dfs -mkdir -p /user/hive/tmp sudo -u hdfs hdfs dfs -chmod 777 /user/hive/tmp # 或更严格的权限 ``` #### 2. 修改`hive-site.xml` 在Hive的配置文件中添加以下属性: ```xml <property> <name>hive.exec.scratchdir</name> <value>/user/hive/tmp</value> </property> ``` #### 3. 重启Hive服务(如果适用) 如果Hive作为服务运行,重启以使配置生效。 ### 原理说明 - Hive需要一个临时目录(`scratchdir`)来存储中间结果和作业相关文件。 - 默认目录是`/tmp/hive`,其权限可能不匹配运行Hive的用户。 - 通过`hive.exec.scratchdir`可以自定义此目录路径[^1]。 ### 相关问题扩展 1. **如何解决`/user/hive/warehouse`目录的WRITE权限拒绝问题?** 类似地,使用`hdfs dfs -chmod`调整权限,或修改`hive.metastore.warehouse.dir`属性指向一个有写入权限的目录[^1]。 2. **Hadoop代理用户(hadoop.proxyuser)配置有哪些安全风险?** 开放代理(如`hadoop.proxyuser.root.groups=*`)允许root用户模拟任意用户,可能导致权限滥用。应在生产环境中限制为必要的最小集合[^4]。 3. **Kerberos认证环境下如何解决Hive权限问题?** 在Kerberos环境中,需确保: - Hive服务主体有权限访问HDFS目录。 - 用户通过kinit获取凭证后,其权限由HDFS的ACL或用户组映射决定。 4. **HDFS目录权限(755/777)设置的最佳实践是什么?** - 遵循最小权限原则:755(所有者读写执行,其他用户只读执行)适用于大多数目录。 - 避免使用777,除非在完全隔离的测试环境中。 - 敏感目录(如`/tmp`)应定期清理并监控。 > **关键点**:始终确保Hive进程用户对相关HDFS目录有适当的读写权限。 §§相关问题§§ 1. 如何在Hive中配置自定义的仓库目录(warehouse directory)? 2. HDFS的ACL(访问控制列表)如何增强权限管理? 3. 如何自动化清理Hive的临时目录? 4. Hive与Hadoop的用户身份映射机制是怎样的? </think> ### 解决Hive 1.2.2运行时HDFS /tmp/hive目录无写入权限问题 #### 问题分析 错误信息`The root scratch dir: /tmp/hive on HDFS should be writable. Current permissions are: rwxr-xr-x`表明: 1. **权限不足**:当前权限`rwxr-xr-x`(755)允许所有用户读取和执行目录,但**写入权限**仅限目录所有者[^1] 2. **用户身份**:Hive进程以root身份运行,但目录所有者是hadoop用户(或其它用户),导致root用户无法写入 3. **目录作用**:`/tmp/hive`是Hive的临时工作目录(scratch dir),需要完全读写权限 #### 解决方案 ```mermaid graph LR A[检查目录权限] --> B{root有写权限?} B ----> C[重启Hive] B ----> D[修改权限] D --> E[方案1: 添加写权限] D --> F[方案2: 修改所有者] D --> G[方案3: 自定义目录] ``` ##### 方案1: 为所有用户添加写权限(推荐测试环境) ```bash # 使用HDFS超级用户操作 sudo -u hdfs hdfs dfs -chmod 777 /tmp/hive # 验证权限 hdfs dfs -ls /tmp | grep hive # 应显示: drwxrwxrwx ``` ##### 方案2: 修改目录所有者(推荐生产环境) ```bash # 将目录所有者改为root sudo -u hdfs hdfs dfs -chown root:root /tmp/hive # 设置严格权限 sudo -u hdfs hdfs dfs -chmod 700 /tmp/hive ``` ##### 方案3: 自定义临时目录路径(永久解决方案) 1. **在HDFS创建新目录**: ```bash sudo -u hdfs hdfs dfs -mkdir -p /user/hive/tmp sudo -u hdfs hdfs dfs -chmod 777 /user/hive/tmp ``` 2. **修改`hive-site.xml`配置**: ```xml <property> <name>hive.exec.scratchdir</name> <value>/user/hive/tmp</value> </property> <property> <name>hive.scratch.dir.permission</name> <value>733</value> <!-- 自定义权限 --> </property> ``` 3. **重启Hive服务**: ```bash # 如果使用Hive Server hive --service metastore & hive --service hiveserver2 & ``` #### 验证修复 ```bash hive -e "CREATE TABLE test_perm (id int); DROP TABLE test_perm;" # 成功执行表示权限问题已解决 ``` #### 预防措施 1. **专用用户运行**: ```bash # 创建hive专用用户 sudo useradd hiveuser -G hadoop sudo -u hdfs hdfs dfs -mkdir /user/hiveuser sudo -u hdfs hdfs dfs -chown hiveuser:hadoop /user/hiveuser ``` 2. **定期清理临时目录**(添加至crontab): ```bash # 每天清理7天前的临时文件 0 2 * * * hdfs dfs -rm -r -skipTrash /tmp/hive/* >/dev/null 2>&1 ``` 3. **配置文件优化**: ```xml <!--hive-site.xml中 --> <property> <name>hive.start.cleanup.scratchdir</name> <value>true</value> <!-- 启动时自动清理 --> </property> ``` > **关键点**:生产环境应使用方案2或方案3,避免使用777权限。Hive对临时目录要求严格的写入权限,特别是MapReduce任务执行期间[^1][^4]。 ### 相关问题 1. **如何解决`/user/hive/warehouse`目录的WRITE权限拒绝问题?** 类似方案:使用`hdfs dfs -chmod g+w /user/hive/warehouse`添加组写入权限,或修改`hive.metastore.warehouse.dir`配置[^1] 2. **Hadoop代理用户配置有哪些安全风险?** 开放`hadoop.proxyuser.*`可能导致权限提升,应限制为必需的最小权限集合[^4] 3. **Kerberos环境下如何解决Hive权限问题?** 需确保:① Kerberos principal有HDFS访问权限 ② 使用`kinit`获取凭证 ③ 配置`hive.server2.enable.doAs=false` 4. **HDFS目录权限设置的最佳实践是什么?** - 遵循最小权限原则 - 临时目录用777,数据目录用750 - 定期审计权限(`hdfs dfs -ls -R / | grep '^d'`
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值