0 引子:
提出两个问题,是对上面 ma-大数据mapreduce思想和数据切割 的深入提问以及hdfs的引入:
1、对每一次的MapReduce作业来说,JobTracker可能会启动个数不同的mapper,且可能调度它们运行于不同的TaskTracker上,那么,这些个mapper如何获取要处理的数据(split),以及如何高效获取所需的数据? 2、如果存储了数据的设备发生了故障,MapReduce是否还能继续运行?如果能,如何进行?
1 hadoop的mapreduce和hdfs关系:
MapReduce并非依赖于分布式文件系统,只不过运行在非分布式文件系统的MapReduce的诸多高级特性将无用武之地.
2 hdfs设计理念:
和传统文件系统相同处:
文件数据存储于“数据块(block)”中、通过“元数据”将文件名与数据块建立映射关系、文件系统基于目录实现树状组织结构、通过元数据保存文件权限及时间戳等。
和传统文件不同处:
1 HDFS是用户空间的文件系统, 2 传统文件系统的“块大小(block size)”通过为1KB、2KB或4KB等,而HDFS的块大小为64MB,且在生产环境中使用时,此块大小通常还会被调整为128MB、256MB甚至是512MB等。 因为HDFS专为存储大文件而设计,较大的块可以减少磁盘的寻道次数,进而提升I/O性能 3 HDFS将所有文件的元数据存储于名称节点(NameNode)的内存中,对于有着海量小文件的应用场景则会给名称节点的内存空间带去巨大压力并使得其很可能成为系统性能瓶颈。 4 HDFS为MapReduce的计算框架而设计,存储下来数据主要用于后续的处理分析,其访问模型为“一次写入、多次读取”;因此,数据在HDFS中存储完成后,仅能在文件尾部附加新数据,而不能对文件进行修改。 5 HDFS专为了高效地传输大文件进行了优化,其为了完成此目标,在“低延迟”特性上做出了很大让步,因此,其不适用于较小访问延迟的应用
3 hdfs节点:
namenode(名称节点):
名称节点负责管理HDFS的名称空间,即以树状结构组织的目录及文件的元数据信息,
这些信息持久存储于名称节点本地磁盘上并保存为名称“空间镜像(namespace image)”和“编辑日志(edit log)”两个文件。
并不存储数据块,仅需要知道每个文件对应数据块的存储位置(存储在数据节点的位置)
但是名称节点并不会持久存储数据块所与其存储位置的对应信息,
这个对应信息是HDFS集群启动时由名称节点根据各数据节点发来的信息进行重建而来,这个重建过程叫做hdfs的安全模式。
datanode(数据节点):
根据名称节点或客户的要求完成存储或读取数据块,并周期性地将其保存的数据块相关信息报告给名称节点
关于存储节点的分配:
默认情况下,HDFS会在集群中为每个数据块存储三个副本以确保数据的可靠性、可用性及性能表现。
在一个大规模集群中,这三个副本一般会保存至不同机架中的数据节点上以应付两种常见的故障:
单数据节点故障和导致某机架上的所有主机离线的网络故障。另外,如前面MapReduce运行模型中所述,
为数据块保存多个副本也有利于MapReduce在作业执行过程中透明地处理节点故障等,
并为MapReduce中作业协同处理以提升性能提供了现实支撑。名称节点会根据数据节点的周期性报告来检查每个数据块的副本数是否符合要求,
低于配置个数要求的将会对其进行补足,而多出的将会被丢弃。
4 hdfs特点:
5 解答问题:
job的多个task(eg: map task或者mapper) 如何知道要处理的 split的数据:
回答:这其实就是客户端如何读取hdfs文件的流程:
HDFS提供了POSIX网络的访问接口,所有的数据操作对客户端程序都是透明的,
以先存后取的流程介绍如下:
当需要存储文件并写数据到hdfs时,客户端程序首先会向名称节点发起名称空间更新请求, 名称节点检查用户的访问权限及文件是否已经存在,如果没有问题,名称空间会挑选一个合适的数据节点分配一个空闲数据块给客户端程序, 此时名称节点内存中会增加维护这段数据在datanode节点的blockid和存储在datanode的节点信息 客户端程序直接将要存储的数据发往对应的数据节点,在完成存储后,数据节点将根据名称节点的指示将数据块复制多个副本至其它节点。 当客户端程序需要访问HDFS中的数据时(即mapper要处理对应split时),它首先基于TCP/IP协议与名称节点(namenode)监听的TCP端口建立连接, 接着通过客户端协议(Client Protocol)发起读取文件的请求,而后名称节点根据用户请求返回相关文件的块标识符(blockid)及存储了此数据块的数据节点。 接下来客户端向对应的数据节点监听的端口发起请求并取回所需要数据块。
6 hdfs 读写数据具体介绍:
6.1 写数据:
(1) 向HDFS集群中保存数据之前,HDFS客户端需要事先知悉目标文件系统使用的“块大小”以及“复制因子(Replication Factor,即每一个块需要保存的副本数目)”。在提交数据至HDFS之前,HDFS客户端需要将要保存的文件按块大小进行分割,并将其逐个向名称节点发起块存储请求,此时,根据复制因子,客户端会要求名称节点给出与复制因子相同个数的空闲块,这里假设为3个; (2) 名称节点需要从找出至少3个具有可用空闲块的数据节点(同复制因子),并将这3个节点的地址以距客户端的距离由近及远的次序响应给客户端; (3) 客户端仅向最近的数据节点(假设为DN1)发起数据存储请求;当此最近的数据节点存储完成后,其会将数据块复制到剩余的数据节点中的一个(假设为DN2),传输完成后,由DN2负责将数据块再同步至最后一个数据节点(假设为DN3);这个也称为“复制管道(replication pipeline); (4) 当三个数据节点均存储完成后,它们会将“存储完成(DONE)”的信息分别通知给名称节点;而后,名称节点会通知客户端存储完成; (5) 客户端以此种方式存储剩余的所有数据块,并在全部数据块存储完成后通知名称节点关闭此文件,名称节点接着会将此文件的元数据信息存储至持久存储中;
6.2 读操作: