之前的一篇博客说到,公司请的大数据培训师那简直一个差啊,就差直接说自己是骗子。忍无可忍之下,搭建了个环境,简单跑了一下,然后把HDFS的主要代码翻了一遍。不得不说,设计的真不错。不过据说当年的初期的版本代码啥的也很烂。
写了两份关于HDFS的培训文档,给研发部门培训了下。后面原准备接着来两次mapreduce和spark的培训,因为种种原因,一直耽搁下来。HDFS培训完针对同学提出的问题结合源码给出答疑,培训文档附件给出,这里把同学们提的问题以及我给出的解答贴出来。
1. 如果在一个数据节点写的过程中出现问题,那么容错处理是怎样的
对比从HDFS读文件,写文件过程比较复杂,有三个地方会影响写的过程,也就是说需要有容错的设计。在这次sharing,我们知道,写数据需要首先建立一个管道(pipeline),如果忘记了,可以看下面的图回忆一下,管道里是要写入当前块(block)的三个数据节点(DataNode). 具体点的话,可以分成下面两个部分:
写请求(write packet)
1) 客户端并不是一开始就把数据(block)直接写入管道,而是先测试管道是否能正确建立。如果在建立管道的过程中,有某个数据节点不能正常工作,客户端将终止这个管道,然后跟名字节点通信,获取另外三个数据节点,尝试建立一个新的管道,这样的尝试有3次(可以配置),如果均失败,则此次写文件失败。如果成功,则管道成功建立,留给后续写数据用
2) 如果管道建立成功,客户端开始写数据。客户端首先把数据传送给管道里的第一个数据节点,这个节点拿到数据后,首先将数据写往下一个数据节点,然后开始往本地写。这里有两个可能出错的地方:
a. 往下个数据节点写的时候可能出错这种情况的容错处理,和建立管道的错误处理是一样的,因为都是返回的TCP管道的错误码。而且,都会告诉客户端是那个数据节点出的错误。很重要的一点是,处理错误响应的是另外一个线程(PacketResponder)。注意,这种情况往本地写数据有可能是成功的。一旦成功,数据节点会和名字节点直接通信来声明本地写成功。
b. 往本地写数据的过程中,可能出错这种情况下当前,数据节点会直接kill掉上面提到的响应处理的线程(PacketResponder),这样造成的结果就是当前数据节点前面的那个节点收不到任何的响应,那么前一个节点就知道,当前这个节点出了问题,就把它标识成bad,然后返回给客户端。
返回响应(ack packet)
1) 建立管道的时候,响应需要顺着管道逆向返回给客户端,如果其中任何一个节点有问题了,则错误会被它前面的节点捕获,错误代码会返回给客户端。
2) 写数据的时候,响应是在另外的线程里处理,处理的策略和1)类似。
2. map和reduce函数的值是怎么获取的
大多数情况是不用去实现自己的FileInputFormat(比如WordCount的例子,map和reduce函数里的值(每行的文本)就是Hadoop给自动分析和设置进去),因为Hadoop已经有一些默认的实现,当既有的那些满足不了你的需求的时候,可以通过继承FileInputFormat来实现自己的。
3. 是否可以用HDFS的API来直接获取文件的某一行记录
首先,通过API直接获取某一个行的记录,肯定是不行的,注意我说的是通过API直接获取。那么如果我想要某一个行的值,是否是可以?这个肯定是可以的。因为我们能通过Hadoop的API来获取这个文件的输出流,那么在这个基础上,可以得到我们想要的那一行,但是需要我们自己写代码。看下面的代码实现
try {
fs = FileSystem.get(conf);
in = fs.open(path);
reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while((line = reader.readLine()) != null) {
System.out.println("Record: " + line);
}
} catch (IOException e) {}
4. 比如我们有1 -> 2 -> 3 -> 4的写入过程,
a. 它是多线程的吗?比如2 往3 写,同时也在另一个线程里往2的本地写?
b. 如果往3写到一半的时候,3挂掉了,3这时候存在了一个坏的数据块,它挂掉以前写正确的部分,它怎么处理的?全部放弃吗?这个时候2怎么处理它已经成功写到本地的部分?
1)是多线程的。针对每一个写入packet的请求,数据节点都会开启一个线程去响应。但是有个线程总数的限制,默认是256,可以在配置文件指定。2往3里写和本地写是在同一个线程里。
2) 如果3写到一半挂掉的话,3确实存在一个没有写完的数据块。按照我的第一封mail里解释的,当前管道会中断,返回错误信息给HDFS客户端,并且包含出错的节点。需要注意的是,这个时候,各个数据节点不做任何处理,目前是简化复杂性。客户端收到错误信息以后,按照前面所说的,它知道第3个节点出错了,所以,就把这个节点去掉,选取剩下3个节点中的一个数据节点作为主节点,然后重新生成一个管道。进行数据恢复。一旦数据恢复成功,有效的数据节点上的块的版本号会更新。对于挂掉的节点3,当它向名字节点周期汇报(heartbeat)的时候,名字节点会命令它删除出错的块,因为版本信息不一样了
对于2或者其它正常的节点,本地写入的进度可能是有差异的,那么HDFS客户端会发出请求到各个正常的节点,来得到目前每个节点写入到什么程度,这里有两种策略:完整恢复和以最小写入的那个点为基础来恢复
数据正常写入的时候用的是流式接口,实现是用的TCP的socket,而出错时候的恢复,则使用的IPC接口,你可以理解是RPC
稍微贴点代码帮助理解我上面第二点解释的:
a.删除出错的节点,取出剩下的节点
System.arraycopy(nodes, 0, newnodes, 0, errorIndex);
System.arraycopy(nodes, errorIndex+1, newnodes, errorIndex, newnodes.length-errorIndex);
b. 选取一个好的节点作为主节点,并发起IPC(RPC)连接
primaryNode = Collections.min(Arrays.asList(newnodes));
primary = createClientDatanodeProtocolProxy(primaryNode, conf, block, accessToken, recoveryTimeout, connectToDnViaHostname);
5. block和meta文件名的数字代表什么意思
blk是前缀, 数字是随机产生的。看下面的源代码
private Block allocateBlock(String src, INode[] inodes) throws IOException {
Block b = new Block(FSNamesystem.randBlockId.nextLong(), 0, 0);
while(isValidBlock(b)) {
b.setBlockId(FSNamesystem.randBlockId.nextLong());
}
b.setGenerationStamp(getGenerationStamp());
b = dir.addBlock(src, inodes, b);
NameNode.stateChangeLog.info("BLOCK* allocateBlock: "
+src+ ". "+b);
return b;
}
对meta文件来说,文件名的组成是block id + number.
public static final String METADATA_EXTENSION = ".meta";
static String getMetaFileName(String blockFileName, long genStamp) {
return blockFileName + "_" + genStamp + METADATA_EXTENSION;
}
相关推荐
HDFS支持基本的文件系统命名空间操作,如创建、删除、移动和重命名文件及目录,但目前不包含用户配额、访问权限控制以及硬链接和软链接功能。用户可以设置文件的复制因子,即每个文件在HDFS中的副本数量,以实现冗余...
赠送原API文档:hadoop-hdfs-2.9.1-javadoc.jar 赠送源代码:hadoop-hdfs-2.9.1-sources.jar 包含翻译后的API文档:hadoop-hdfs-2.9.1-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache....
包含翻译后的API文档:hadoop-hdfs-client-2.9.1-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.apache.hadoop:hadoop-hdfs-client:2.9.1; 标签:apache、hadoop、hdfs、client、中英对照文档、jar...
大数据与云计算培训学习资料 Hadoop之HDFS介绍 共28页.ppt
包含翻译后的API文档:hadoop-hdfs-2.7.3-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.hadoop:hadoop-hdfs:2.7.3; 标签:apache、hdfs、hadoop、jar包、java、中文文档; 使用方法:解压翻译后的API...
包含翻译后的API文档:hadoop-hdfs-2.7.3-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.apache.hadoop:hadoop-hdfs:2.7.3; 标签:apache、hdfs、hadoop、jar包、java、API文档、中英对照版; 使用...
### HDFS基础知识与分布式存储概念 #### HDFS简介与特点 - **定义**: HDFS(Hadoop Distributed File System)是一种分布式文件系统,旨在提供高效、可靠的数据存储解决方案,尤其适用于处理大规模数据集。 - **...
最新版的hdfs安装文档,详细的描述安装步骤,命令只需要copy执行即可,此安装的namenode是单体的
Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错...
好东西,hdfs官方设计文档(翻译),Hadoop 分布式文件系统 (HDFS)是一个设计为用在普通硬件设备上的分布式文件系统。它与现有的分布式文件系统有很多近似的地方,但又和这些文件系统有很明显的不同。HDFS是高容错的,...
**大数据存储基石:HDFS(Hadoop Distributed File System)理论篇** HDFS是Apache Hadoop项目的核心组件之一,是为处理大规模数据集而设计的一种分布式文件系统。它以高容错性和高可用性为目标,旨在运行在廉价的...
包含翻译后的API文档:hadoop-hdfs-2.6.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.hadoop:hadoop-hdfs:2.6.5; 标签:apache、hdfs、hadoop、jar包、java、中文文档; 使用方法:解压翻译后的API...
大数据与云计算培训学习资料 Hadoop之HDFS基础入门知识介绍 共42页.ppt
Hadoop 分布式文件系统 (HDFS)是一个设计为用在普通硬件设备上的分布式文件系统。它与现有的分布式文件系统有很多近似的地方,但又和这些文件系统有很明显的不同。HDFS是高容错的,设计为部署在廉价硬件上的。HDFS对...
HDFS能 够提供对数据的可扩展访问,通过简单地往集群里添加节点就可以解决大量客户端同时访问的问题。HDFS支持传统的层次文件组织结构,同现 有的一些文件系 统类似,如可以对文件进行创建、删除、重命名等操作。
Hadoop 培训课程(2)HDFS 分布式文件系统与HDFS HDFS体系结构与基本概念*** HDFS的shell操作*** java接口及常用api*** ---------------------------加深拓展---------------------- RPC调用** HDFS的分布式存储架构的...
【标题】"hdfs-over-ftp安装包及说明"涉及的核心技术是将FTP(File Transfer Protocol)服务与HDFS(Hadoop Distributed File System)相结合,允许用户通过FTP协议访问和操作HDFS上的数据。这个标题暗示了我们将在...
在大数据领域,分布式系统设计是核心之一,而Hadoop分布式文件系统(HDFS)作为其中的重要组成部分,扮演着存储和处理海量数据的角色。本文将详细探讨HDFS的相关知识点,包括其设计需求、扩展性、块的概念、中心节点...