3.hadoop中的数据复制

HDFS通过将文件拆分成数据块并保持多个副本来确保数据可靠性。每个文件块通常有相同的大小,但支持变长块。复制因子可在创建时指定,NameNode根据心跳和块报告管理副本,使用机架感知策略优化复制位置,提升性能和可靠性。安全模式下,NameNode在达到一定比例的复制安全数据块后退出,然后复制未达最小副本数的数据块。

HDFS可以保证集群中文件存储的可靠性。它把文件分解成一个由数据块构成的序列,每个数据块有多个副本,这种数据冗余对容错非常关键。当一个数据块损坏时,不会造成数据丢失。数据块的大小和复制因子对每个文件都是可配的。

一般情况下,HDFS中一个文件的所有数据块,除最后一个块外,都有同样的大小。

但是,HDFS支持变长的数据块,就是说一个文件有可能包含两种大小的数据块。当用户重新配置了文件的块大小,然后向该文件中追加数据,这时HDFS不会填充文件的最后一个块,而是用新的尺寸创建新块存储追加的数据,这种情况下文件中就会同时存在两种大小的块。

应用可以指定一个文件的副本数,即复制因子。可以在文件创建时指定复制因子,这个复制因子的配置以后是可以改变的。除了追加和清除操作外,HDFS中的文件在任何时候都是严格地一次写入。

NameNode做出的所有操作,都会考虑数据块的复制。它周期性地接收集群中每个DataNode发出的心跳和块报告。接收到心跳说明DataNode工作正常。块报告包含该DataNode节点上所有数据块的列表。

HDFS使用所谓的“机架感知”策略放置数据块副本。这是一个需要进行大量实验并不断调整的特性,也是HDFS与其他分布式文件系统的主要区别。机架感知的目的是要提升数据可靠性、可用性和网络带宽的利用率。

在此简单说一下可靠性与可用性的区别

可靠性是指系统可以无故障地持续运行,而可用性指的是系统在任何给定的时刻都能工作。
例如,如果系统每月崩溃1分钟,那么它的可用性是99.998%,但是它还是非常不可靠的。与之相反,如果一个系统从来不崩溃,但是每年要停机两星期,那么它是高度可靠的,但是可用性只有96%。

在一个复制因子为3的普通场景中,这样只写了两个机架,节省了一个机架的写入流量,提升了写入性能。
该策略的前提是认可这样一种假设:机架失效的可能性比机器失效的可能性小得多。因此这种策略并不会影响数据的可靠性和可用性。
该策略提升了写的性能,同时没有损害数据可靠性或读的性能。

如果复制因子大于3,第4个及其后面的副本被随机放置,但每个机架的副本数量要低于上限值,上限值的计算公式是:((副本数 -1)/(机架数 + 2))取整。

当Hadoop的NameNode节点启动时,会进入一种称为安全模式的特殊状态。

NameNode处于安全模式时不会进行数据块的复制操作。此时NameNode会接收来自DataNode的心跳和块报告消息。块报告中包含该DataNode节点所保存的数据块列表,每个数据块有一个特定的最小副本数。

NameNode检测到一个数据块达到了最小副本数时,就认为该数据块是复制安全的。当检测到的复制安全的数据块达到一定比例(由dfs.safemode.threshold.pct参数指定)30秒后,NameNode退出安全模式。然后NameNode会确定一个没有达到最小副本条件的数据块列表,并将这些数据块复制到其他DataNode节点,直至达到最小副本数。
 

Exception in thread "main" java.lang.NullPointerException at java.lang.ProcessBuilder.start(ProcessBuilder.java:1012) at org.apache.hadoop.util.Shell.runCommand(Shell.java:483) at org.apache.hadoop.util.Shell.run(Shell.java:456) at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:722) at org.apache.hadoop.util.Shell.execCommand(Shell.java:815) at org.apache.hadoop.util.Shell.execCommand(Shell.java:798) at org.apache.hadoop.fs.RawLocalFileSystem.setPermission(RawLocalFileSystem.java:731) at org.apache.hadoop.fs.RawLocalFileSystem.mkOneDirWithMode(RawLocalFileSystem.java:489) at org.apache.hadoop.fs.RawLocalFileSystem.mkdirsWithOptionalPermission(RawLocalFileSystem.java:530) at org.apache.hadoop.fs.RawLocalFileSystem.mkdirs(RawLocalFileSystem.java:507) at org.apache.hadoop.fs.FilterFileSystem.mkdirs(FilterFileSystem.java:305) at org.apache.hadoop.mapreduce.JobSubmissionFiles.getStagingDir(JobSubmissionFiles.java:133) at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:144) at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1290) at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1287) 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:1657) at org.apache.hadoop.mapreduce.Job.submit(Job.java:1287) at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1308) at com.kegc.Phoneflow.PhoneFlowDriver.main(PhoneFlowDriver.java:39)帮我解决一下这个问题
最新发布
05-25
### Hadoop运行时出现`java.lang.NullPointerException`异常的原因分析 在Hadoop环境中,`java.lang.NullPointerException`通常是由某些对象未被正确初始化或配置不当引起的。以下是可能导致此问题的具体原因及其解决方案: #### 1. **ProcessBuilder.start()方法引发的空指针异常** 当调用`ProcessBuilder.start()`方法时发生空指针异常,可能是因为环境变量或路径设置不正确[^1]。具体来说,在Windows环境下运行Hadoop时,如果系统的PATH环境变量中缺少必要的工具(如SSH客户端),可能会导致此类错误。 #### 2. **HDFS操作中的空指针异常** 在执行HDFS文件复制操作(如`copyToLocalFile`)时,可能出现`NullPointerException`。这通常是由于目标路径不存在或者权限不足造成的[^2]。例如,代码中尝试将文件从HDFS复制到本地磁盘时,指定的目标路径可能并未创建成功。 #### 3. **Eclipse集成开发环境下的空指针异常** 对于通过Eclipse连接至远程Hadoop集群并运行WordCount程序的情况,空指针异常可能是由以下几个方面引起: - 配置文件加载失败:Hadoop的核心配置文件(如core-site.xml、hdfs-site.xml)未能正确加载。 - 文件系统实例化失败:`FileSystem.get(conf)`返回的对象为空,表明配置参数有误。 - 权限问题:HDFS上的数据访问权限不足,无法完成读写操作[^3]。 --- ### 解决方案 #### (一) 检查环境变量与依赖项 确保操作系统已正确配置Java和Hadoop所需的环境变量。特别是以下几点需注意: - `JAVA_HOME`指向有效的JDK安装目录; - 将Hadoop二进制包内的bin目录加入到全局PATH中; - 如果涉及分布式计算,则还需验证网络连通性和SSH免密登录功能是否正常工作。 #### (二) 修改代码逻辑以增强健壮性 针对提供的测试类`TestHDFS`,建议增加对输入参数的有效性校验以及捕获潜在异常的能力。改进后的版本如下所示: ```java import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.LocatedFileStatus; import org.apache.hadoop.fs.RemoteIterator; public class TestHDFS { public static void main(String[] args) { try { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://myServer1:9000"); FileSystem fs = FileSystem.get(conf); if (!fs.exists(new Path("/"))) { throw new RuntimeException("Root directory does not exist!"); } RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("/"), true); while (files.hasNext()) { LocatedFileStatus status = files.next(); System.out.println(status.getPath().getName()); } boolean success = fs.copyToLocalFile(false, new Path("/hello.txt"), new Path("F:/"), true); if (!success) { System.err.println("Failed to copy file from HDFS."); } fs.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` #### (三) 调整安全策略与权限管理 确认当前用户的账户具备足够的权限来操控所涉及到的所有资源。可以通过命令行手动更改相应目录的属性作为临时措施,比如使用`chmod`指令赋予额外许可给特定用户组成员。 另外需要注意的是,默认情况下RawLocalFileSystem会尝试修改本地存储位置的ACLs,而这一过程也可能触发NPE。因此有必要重新审视这些默认行为,并视情况调整它们的行为模式。 --- ### 总结 综上所述,要彻底消除因`java.lang.NullPointerException`而导致的功能障碍,就需要从业务流程设计层面入手进行全面排查——既包括外部条件准备工作的落实到位程度评估,也涵盖了内部算法实现细节方面的优化完善两个维度的工作推进方向探讨[^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值