Hadoop异常:n must be positive

文章详细介绍了在使用HDFS处理5000万个文件时遇到的Datanode异常问题,通过分析发现是由于数据块扫描周期设置过大导致Integer溢出,提出解决方案将随机数生成改为取绝对值,避免了异常发生,并链接到已存在的Apache JIRA问题跟踪。
测试HDFS 5000万个文件场景时,看到Datanode的log上不断的报如下异常

11/11/10 00:00:00 ERROR datanode.DataNode: DatanodeRegistration(172.17.1.23:50010, storageID=DS-857985192-202.106.199.37-50010-1320820941090, infoPort=8083, ipcPort=50020):DataXceiver java.lang.IllegalArgumentException: n must be positive at java.util.Random.nextInt(Random.java:250) at org.apache.hadoop.hdfs.server.datanode.DataBlockScanner.getNewBlockScanTime(DataBlockScanner.java:284) at org.apache.hadoop.hdfs.server.datanode.DataBlockScanner.addBlock(DataBlockScanner.java:301) at org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:372) at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:103) at java.lang.Thread.run(Thread.java:662)


经过跟踪,发现问题是出在DataBlockScanner内:
    long period = Math.min(scanPeriod, 
Math.max(blockMap.size(),1) * 600 * 1000L);
return System.currentTimeMillis() - scanPeriod +
random.nextInt((int)period);

当BlockMap特别大的时候,比如我这里上传了5000万个文件,每个文件4KB,该数值会大于Integer.MAX 小于Long.MAX,强制转换成int会负数,导致nextInt抛出异常。
该处修改,只需要把
random.nextInt((int)period)
,替换成
random.nextInt(Math.abs((int)period))
即可。

后来又发现Hadoop已经有人提这个bug了,[url]https://issues.apache.org/jira/browse/HDFS-2541[/url]
### 设置 HADOOP_HOME 或 HADOOP_PREFIX 环境变量 Hadoop 的安装路径未正确设置会导致类似 `Cannot find hadoop installation: $HADOOP_HOME or $HADOOP_PREFIX must be set or hadoop must be in the path` 的错误。以下是解决此问题的详细方法。 #### 1. 检查 Hadoop 是否已正确安装 首先需要确认 Hadoop 是否已经正确安装,并确定其安装路径。可以通过以下命令检查: ```bash which hadoop ``` 如果输出类似于 `/usr/bin/hadoop`,则说明 Hadoop 已安装。进一步查看符号链接指向的实际路径: ```bash ls -l /usr/bin/hadoop ``` 这将显示 Hadoop 的实际安装路径[^5]。 #### 2. 设置 HADOOP_HOME 环境变量 编辑系统的环境变量配置文件(如 `.bashrc` 或 `.bash_profile`),添加以下内容: ```bash export HADOOP_HOME=/path/to/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin ``` 将 `/path/to/hadoop` 替换为实际的 Hadoop 安装路径。例如,如果 Hadoop 安装在 `/home/admin/softwares/hadoop-2.7.2`,则应写为: ```bash export HADOOP_HOME=/home/admin/softwares/hadoop-2.7.2 export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin ``` 执行以下命令使更改生效: ```bash source ~/.bashrc ``` #### 3. 设置 HADOOP_PREFIX 环境变量 某些情况下,可能需要同时设置 `HADOOP_PREFIX`。可以按照以下方式设置: ```bash export HADOOP_PREFIX=$HADOOP_HOME ``` 将其添加到 `.bashrc` 文件中以确保每次登录时自动加载。 #### 4. 配置 Hive 的环境变量 如果使用的是 Hive,还需要在 Hive 的配置文件中指定 Hadoop 的路径。编辑 `hive-env.sh` 文件: ```bash vi $HIVE_HOME/conf/hive-env.sh ``` 添加或修改以下行: ```bash export HADOOP_HOME=/path/to/hadoop ``` 确保路径与上述设置一致[^4]。 #### 5. 验证设置是否成功 完成上述步骤后,重新启动 Hive 并验证问题是否解决: ```bash hive ``` 如果没有再次出现 `Cannot find hadoop installation` 错误,则说明设置成功[^1]。 ### 注意事项 - 如果 Hadoop 是通过包管理工具(如 Yum 或 Apt)安装的,可能需要调整符号链接以确保路径正确。 - 确保 Hadoop 的二进制文件(如 `hadoop` 和 `hdfs`)在 `$PATH` 中可用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值