Hadoop HDFS 常见问题

docker安装hadoop 添加镜像源

为了加速在 CentOS 7 镜像中安装软件包的速度,可以使用阿里云的镜像源。以下是修改后的 Dockerfile,它包括了将 yum 源更改为阿里云的步骤,并确保安装过程更快。
为了加速在 CentOS 7 镜像中安装软件包的速度,可以使用阿里云的镜像源。以下是修改后的 Dockerfile,它包括了将 yum 源更改为阿里云的步骤,并确保安装过程更快。

# 使用官方的 CentOS 7 镜像作为基础镜像
FROM centos:7

# 添加元数据
LABEL author="hjq" date="2022/03/05"

# 更改yum源为阿里云镜像源
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup && \
    curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum clean all && \
    yum makecache

# 安装openssh-server和sudo软件包,并且将sshd的UsePAM参数设置成no
RUN yum install -y openssh-server sudo && \
    sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config

# 安装openssh-clients
RUN yum install -y openssh-clients

# 安装which
RUN yum install -y which

# 添加测试用户root,密码root,并且将此用户添加到sudoers里
RUN echo "root:root" | chpasswd && \
    echo "root ALL=(ALL) ALL" >> /etc/sudoers && \
    ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N '' && \
    ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''

# 启动sshd服务并且暴露22端口
RUN mkdir /var/run/sshd
EXPOSE 22

# 拷贝并解压jdk,根据自己的版本修改
ADD jdk-8u321-linux-x64.tar.gz /usr/local/
RUN mv /usr/local/jdk1.8.0_321 /usr/local/jdk1.8
ENV JAVA_HOME /usr/local/jdk1.8
ENV PATH $JAVA_HOME/bin:$PATH

# 拷贝并解压hadoop,根据自己的版本修改
ADD hadoop-3.3.2.tar.gz /usr/local
RUN mv /usr/local/hadoop-3.3.2 /usr/local/hadoop
ENV HADOOP_HOME /usr/local/hadoop
ENV PATH $HADOOP_HOME/bin:$PATH

# 设置容器启动命令
CMD ["/usr/sbin/sshd", "-D"]

关键点说明:

  1. 更改 Yum 源

    • 将默认的 CentOS 基础仓库文件备份。
    • 使用 curl 下载阿里云的 CentOS 7 仓库文件。
    • 清理现有的 Yum 缓存并重新生成缓存。
  2. 安装 SSH 和相关工具

    • 安装 openssh-serversudoopenssh-clients
    • 修改 SSH 配置文件以禁用 PAM。
    • 生成 SSH 主机密钥。
  3. 配置用户和权限

    • 设置 root 用户的密码。
    • 将 root 用户添加到 sudoers 文件中。
  4. 安装 JDK 和 Hadoop

    • 拷贝并解压 JDK 和 Hadoop 的压缩包。
    • 设置环境变量 JAVA_HOMEHADOOP_HOME,并将它们添加到 PATH 中。
  5. 启动 SSH 服务

    • 创建 /var/run/sshd 目录。
    • 在容器启动时运行 SSH 服务。

通过这种方式,不仅可以加快软件包的安装速度,还能确保的 Docker 容器能够快速地提供 SSH 服务。

ERROR: failed to solve: unexpected EOF

=> [ 5/11] RUN yum install -y which                                                                                                                                                                          1.3s 
 => [ 6/11] RUN echo "root:root" | chpasswd &&     echo "root ALL=(ALL) ALL" >> /etc/sudoers &&     ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N '' &&     ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_k  0.3s 
 => [ 7/11] RUN mkdir /var/run/sshd                                                                                                                                                                           0.2s 
 => ERROR [ 8/11] ADD jdk-8u321-linux-x64.tar.gz /usr/local/                                                                                                                                                  0.1s 
------                                                                                                                                                                                                             
 > [ 8/11] ADD jdk-8u321-linux-x64.tar.gz /usr/local/:                                                                                                                                                             
------                                                                                                                                                                                                             
Dockerfile:34                                                                                                                                                                                                      
--------------------
  32 |     
  33 |     # 拷贝并解压jdk,根据自己的版本修改
  34 | >>> ADD jdk-8u321-linux-x64.tar.gz /usr/local/
  35 |     RUN mv /usr/local/jdk1.8.0_321 /usr/local/jdk1.8
  36 |     ENV JAVA_HOME /usr/local/jdk1.8
--------------------
ERROR: failed to solve: unexpected EOF

主要问题

  1. 内部文件和外部文件不一致, 将RUN mv /usr/local/jdk1.8.0_321 改为文件的内部文件名

hdfs dfs -put test.txt / 遇到的问题

[root@master /]# hdfs dfs -put test.txt /
2024-10-01 02:48:53,048 WARN hdfs.DataStreamer: DataStreamer Exception
org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /test.txt._COPYING_ could only be written to 0 of the 1 minReplication nodes. There are 0 datanode(s) running and 0 node(s) are excluded in this operation.
	at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:2338)
	at org.apache.hadoop.hdfs.server.namenode.FSDirWriteFileOp.chooseTargetForNewBlock(FSDirWriteFileOp.java:294)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:2989)
	at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:911)
	at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:595)
	at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine2.java:621)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine2.java:589)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine2.java:573)
	at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1213)
	at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:1089)
	at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:1012)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1899)
	at org.apache.hadoop.ipc.Server$Handler.run(Server.java:3026)

	at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1584)
	at org.apache.hadoop.ipc.Client.call(Client.java:1530)
	at org.apache.hadoop.ipc.Client.call(Client.java:1427)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Invoker.invoke(ProtobufRpcEngine2.java:258)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Invoker.invoke(ProtobufRpcEngine2.java:139)
	at com.sun.proxy.$Proxy9.addBlock(Unknown Source)
	at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.addBlock(ClientNamenodeProtocolTranslatorPB.java:531)
	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:498)
	at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:433)
	at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeMethod(RetryInvocationHandler.java:166)
	at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invoke(RetryInvocationHandler.java:158)
	at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeOnce(RetryInvocationHandler.java:96)
	at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:362)
	at com.sun.proxy.$Proxy10.addBlock(Unknown Source)
	at org.apache.hadoop.hdfs.DFSOutputStream.addBlock(DFSOutputStream.java:1088)
	at org.apache.hadoop.hdfs.DataStreamer.locateFollowingBlock(DataStreamer.java:1915)
	at org.apache.hadoop.hdfs.DataStreamer.nextBlockOutputStream(DataStreamer.java:1717)
	at org.apache.hadoop.hdfs.DataStreamer.run(DataStreamer.java:713)
put: File /test.txt._COPYING_ could only be written to 0 of the 1 minReplication nodes. There are 0 datanode(s) running and 0 node(s) are excluded in this operation.

HDFS 无法将文件 test.txt 写入集群,因为没有可用的 DataNode。具体错误是:


File /test.txt._COPYING_ could only be written to 0 of the 1 minReplication nodes. There are 0 datanode(s) running and 0 node(s) are excluded in this operation.

这表明 Hadoop 集群中没有运行的 DataNode,因此 NameNode 无法找到足够的 DataNode 来存储数据块。

解决方法

  1. 检查 DataNode 是否启动
    • 确保所有 DataNode 服务已经启动。可以通过以下命令检查 DataNode 的状态:
      hdfs dfsadmin -report
      
    • 这个命令会显示集群的状态报告,包括每个 DataNode 的信息。如果没有任何 DataNode 显示,则表示 DataNode 没有启动。
  2. 启动 DataNode
    • 如果 DataNode 没有启动,需要手动启动它们。假设在单节点或多节点集群上,可以使用以下命令启动 DataNode:
      hdfs --daemon start datanode
      
    • 如果在多节点集群上,确保在所有 DataNode 节点上都执行这个命令。
  3. 检查配置文件
    • 确保 Hadoop 配置文件(如 hdfs-site.xmlcore-site.xml)正确配置了 DataNode 的位置和端口。
    • 确认 dfs.datanode.addressdfs.datanode.http.addresshdfs-site.xml 中正确设置。
  4. 检查日志文件
    • 查看 DataNode 的日志文件以获取更多详细信息。日志文件通常位于 /var/log/hadoop/ 目录下,具体路径可能因配置而异。
    • 日志文件名通常是 hadoop-hadoop-datanode-<hostname>.log 或类似的命名方式。
  5. 检查防火墙和网络
    • 确保防火墙没有阻止 DataNode 与 NameNode 之间的通信。
    • 确保所有节点之间的网络连接正常。
  6. 格式化 NameNode(仅在必要时):
    • 如果是第一次设置集群或者遇到其他问题,可能需要格式化 NameNode:
      hdfs namenode -format
      
    • 注意:这将清除所有现有的 HDFS 数据,请谨慎操作。
  7. 重启 Hadoop 服务
    • 有时,重启整个 Hadoop 服务可以解决问题。可以使用以下命令停止并重新启动 Hadoop 服务:
      stop-dfs.sh
      start-dfs.sh
      

示例命令

假设有一个简单的单节点集群,以下是启动 DataNode 并检查其状态的示例命令:

# 启动 DataNode
hdfs --daemon start datanode

# 检查 DataNode 状态
hdfs dfsadmin -report

如果在一个多节点集群上,确保在所有 DataNode 节点上执行这些命令。

其他注意事项

  • 确保 Hadoop 版本与集群配置兼容。
  • 确保所有节点上的 Hadoop 配置文件是一致的。
  • 如果使用的是分布式环境,确保所有节点的时间同步。

Couldn’t find datanode to write file. Forbidden (hadoop上传不了文件)

当遇到 Couldn't find datanode to write file. Forbidden 错误时,这通常意味着 Hadoop NameNode 无法找到可用的 DataNode 来写入数据。以下是一些可能的原因和解决方法:

可能的原因

  1. DataNode 未启动
    • 确保所有 DataNode 服务已经启动。
  2. 防火墙或网络问题
    • 确保 DataNode 和 NameNode 之间的网络通信没有被防火墙阻止。
    • 检查网络连接是否正常。
  3. 配置错误
    • 确认 hdfs-site.xmlcore-site.xml 配置文件中的设置正确无误。
    • 确认 dfs.replication 设置合理(默认值通常是 3)。
  4. 权限问题
    • 确保有权限在 HDFS 上创建文件。检查 HDFS 的权限设置。
  5. NameNode 和 DataNode 版本不匹配
    • 确保所有节点上的 Hadoop 版本一致。
  6. DataNode 日志中的错误
    • 查看 DataNode 的日志文件以获取更多详细信息。

解决方法

  1. 检查 DataNode 是否启动

    • 使用以下命令检查 DataNode 的状态:
      hdfs dfsadmin -report
      
    • 如果没有任何 DataNode 显示,则表示 DataNode 没有启动。
  2. 启动 DataNode

    • 在每个 DataNode 节点上执行以下命令来启动 DataNode 服务:
      hdfs --daemon start datanode
      
  3. 检查防火墙和网络

    • 确保防火墙没有阻止 DataNode 与 NameNode 之间的通信。
    • 确保所有节点之间的网络连接正常。
    • 可以使用 ping 命令测试节点之间的连通性:
      ping <datanode-hostname>
      
  4. 检查配置文件

    • 确认 hdfs-site.xmlcore-site.xml 配置文件中的设置正确无误。
    • 确认 dfs.replication 设置合理。例如:
      <property>
        <name>dfs.replication</name>
        <value>3</value>
      </property>
      
    • 如果集群只有一个 DataNode,可以将 dfs.replication 设置为 1:
      <property>
        <name>dfs.replication</name>
        <value>1</value>
      </property>
      
  5. 检查权限

    • 确保有权限在 HDFS 上创建文件。可以使用以下命令检查当前用户的权限:
      hdfs dfs -ls /
      
    • 如果需要,可以更改目录权限:
      hdfs dfs -chmod 777 /
      
  6. 查看 DataNode 日志

    • 查看 DataNode 的日志文件以获取更多详细信息。日志文件通常位于 /var/log/hadoop/ 目录下,具体路径可能因的配置而异。
    • 日志文件名通常是 hadoop-hadoop-datanode-<hostname>.log 或类似的命名方式。
  7. 重启 Hadoop 服务

    • 有时,重启整个 Hadoop 服务可以解决问题。可以使用以下命令停止并重新启动 Hadoop 服务:
      stop-dfs.sh
      start-dfs.sh
      

示例命令

假设有一个简单的单节点集群,以下是启动 DataNode 并检查其状态的示例命令:

# 启动 DataNode
hdfs --daemon start datanode
# 检查 DataNode 状态
hdfs dfsadmin -report

如果在一个多节点集群上,确保在所有 DataNode 节点上执行这些命令。

其他注意事项

  • 确保 Hadoop 版本与的集群配置兼容。
  • 确保所有节点上的 Hadoop 配置文件是一致的。
  • 如果使用的是分布式环境,确保所有节点的时间同步。

通过上述步骤,能够解决 Couldn't find datanode to write file. Forbidden 问题,并成功将文件上传到 HDFS。

RemoteException Object { exception: “AccessControlException”, javaClassName: "org.apache.hadoop.security.AccessControlException

RemoteException	Object { exception: "AccessControlException", javaClassName: "org.apache.hadoop.security.AccessControlException", message: 'Permission denied: user=dr.who, access=WRITE, inode="/":root:supergroup:drwxr-xr-x\n\tat org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:506)\n\tat org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:346)\n\tat org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:242)\n\tat org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:1943)\n\tat org…Invoker.call(ProtobufRpcEngine2.java:573)\n\tat org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1213)\n\tat org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:1089)\n\tat org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:1012)\n\tat java.security.AccessController.doPrivileged(Native Method)\n\tat javax.security.auth.Subject.doAs(Subject.java:422)\n\tat org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1899)\n\tat org.apache.hadoop.ipc.Server$Handler.run(Server.java:3026)\n' }

遇到的 AccessControlException 是 Hadoop 中常见的权限问题。具体错误信息是:

Permission denied: user=dr.who, access=WRITE, inode="/":root:supergroup:drwxr-xr-x

这表明用户 dr.who 尝试对根目录 / 进行写操作,但没有足够的权限。

解决方法

  1. 检查 HDFS 权限
    使用 hdfs dfs -ls / 命令来查看根目录的权限设置。

    hdfs dfs -ls /
    

    应该会看到类似以下的输出:

    drwxr-xr-x - root supergroup          0 2023-10-01 11:05 /
    

    在这个例子中,根目录的权限是 drwxr-xr-x,这意味着只有 root 用户和 supergroup 组有写权限。

  2. 更改 HDFS 权限
    如果需要允许 dr.who 用户进行写操作,可以更改目录的权限或将其添加到具有写权限的组。

    • 更改目录权限
      可以使用 hdfs dfs -chmod 命令来更改目录的权限。

      hdfs dfs -chmod 777 /
      

      注意:将权限设置为 777 会使任何人都可以读、写和执行该目录,这在生产环境中通常是不安全的。建议仅在测试环境中这样做,并确保在生产环境中使用更严格的权限设置。

    • 将用户添加到具有写权限的组
      可以将 dr.who 用户添加到 supergroup 组(假设 supergroup 有写权限)。

      sudo usermod -a -G supergroup dr.who
      

      然后重新登录以使组更改生效。

  3. 使用 Hadoop 的 hadoop 命令行工具
    可以使用 hadoop fshdfs dfs 命令来管理 HDFS 文件系统。

  4. 检查 Hadoop 配置
    确保 Hadoop 配置文件中的 hdfs-site.xmlcore-site.xml 没有配置错误。特别是检查 hdfs-site.xml 中的 dfs.permissions.enabled 属性是否设置为 true

    <property>
        <name>dfs.permissions.enabled</name>
        <value>true</value>
    </property>
    

    如果不希望启用权限检查,可以将其设置为 false(不推荐在生产环境中这样做)。

  5. 使用正确的用户运行 Hadoop 命令
    确保使用的是具有适当权限的用户来运行 Hadoop 命令。可以使用 sudo -u <user> 来切换用户并运行命令。

    sudo -u hdfs hdfs dfs -mkdir /mydirectory
    

示例

假设想让 dr.who 用户能够写入 /mydirectory 目录,可以按以下步骤操作:

  1. 创建目录并设置适当的权限:

    hdfs dfs -mkdir /mydirectory
    hdfs dfs -chown dr.who:supergroup /mydirectory
    hdfs dfs -chmod 775 /mydirectory
    
  2. 验证权限:

    hdfs dfs -ls /mydirectory
    
  3. 使用 dr.who 用户尝试写入文件:

    sudo -u dr.who hdfs dfs -put localfile.txt /mydirectory/
    

通过这些步骤,应该能够解决 AccessControlException 并允许 dr.who 用户进行写操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java我跟你拼了

您的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值