Hdfs体系结构:三个进程(namenode,datanode, secondary namenode)
Hdfs(hadoopdistributed filesystem)是hadoop的核心子项目,是分布式存储,它是基于流数据模式的访问和处理超大文件。(分布式最大的好处就是其通透性,虽然分布存在不同的datanode上面,但是感觉在一台电脑的本地进行操作)。
Tips:
Hdfs的高可用性主要取决于namenode,间接取决于元数据的可靠性和namenode的服务回复时间。
磁盘元数据文件,所有的元数据文件是将存放在内存之中的,一旦断电,内存中的数据将会全部消失,所以需要将数据存放在磁盘上面 永久保存。
磁盘员数据文件包含:
fsimage 元数据镜像文件,存储的是某一时刻的namenode内存元数据信息。
edits:日志文件 包含了该时刻以后的元数据操作记录。
fstime:保存了最近的checkpoint的时间
VERSION:标志性文件,代表前面三个文件成功创建。
Namenode(进程):元数据节点,用来管理文件系统的命名空间,维护目录树,接管用户的请求。
(1) 将文件的元数据保存在一个文件目录树中
(2) 在磁盘上保存为:fsimage 和 edits
(3) 保存datanode的数据信息的文件,在系统启动的时候读入内存。
下面看下hdfs配置文件源码分析,里面的内容立即显现:
hdfs-default.xml:
首先这个文件不可以修改的,若是想修改某些属性,拷贝实体到hdfs-site.xml文件中进行配置,这也是开始安装hadoop的配置文件中的一些<configuration>
下面namenode存储的元数据信息的配置:
这个property中包含一个:
${hadoop.tmp.dir}是基于core-default.xml文件配置的:
${user.name}安装hadoop的用户名字。
基于在本地文件系统之上的分布式文件系统的name node 是存储 名字表的,保存为fsimage文件,为了冗余(备份,安全性)可以用逗号(,)分隔目录列表。
例如:
逗号之间什么都不允许添加,否则将会不识别。
当 cd ${hadoop.tmp.dir}(自己定义的目录)/dfs/name
ls 出现
其中有个in_use.lock 文件,表明已有进程执行(lock住了,即namenode进程)。
cd current/
ls 出现:
正好满足 fsimage(镜像文件namenode的核心数据文件),edits文件的存在。
如果namenode 失效 将无法恢复 datanode。
Edits
edits:transaction file (事物文件),为了保存数据的一致性,写入数据的过程需要先写入edits中,edits保存操作的过程,当过程结束时,edits是知道的,但fsimage不清楚,只有操作成功了,才会通知fsimage。此时,要将edits数据操作成功的报告告诉给fsimage,需要通过的进程就是 secondarynamenode,所以secondarynamenode的主要作用就是合并fsiamge和edits的,形成新的fsimage,在本地保存,在发送给namenode,同时重置namenode的edits。Namenode之所以不进行合并,而应用secondarynamenode来操作,主要就是namenode需要快速接管用户的请求,需要快速响应。所以fsimage文件保存了一份在secondarynamenode中,所以当namenode的数据丢失的情况,可以进行secondarynamenode恢复,但是可能会丢失一部分数据,就是没有来得及合并的fsimage和edits,即备份数据不是实时的,是冷备份。
Tips:
fsimage:是内存的元数据在硬盘上的checkpoint,更新fsimage文件需要有个checkpoin过程:
- 从元数据节点通知元数据节点生成新的日志文件,以后的日志都写到新的日志文件中。
- 从元数据节点用http get从元数据节点获得fsimage文件及旧的日志文件。
- 从元数据节点将fsimage文件加载到内存中,并执行日志文件中的操作,然后生成新的fsimage文件。
- 从元数据节点奖新的fsimage文件用http post传回元数据节点
- 元数据节点可以将旧的fsimage文件及旧的日志文件,换为新的fsimage文件和新的日志文件(第一步生成的),然后更新fstime文件,写入此次checkpoint的时间。
- 这样元数据节点中的fsimage文件保存了最新的checkpoint的元数据信息,日志文件也重新开始,不会变的很大了。
此外:
这个作用和上面的一致,多备份几个文件,需要用逗号分隔(,)。
DataNode的进程:主要就是存储真实数据。
需要存储(上传)数据时,需要先报告给namenode,namenode找到空闲的datanode,才可以进行操作。
Datanode存储数据的时候,是以block为单位进行,默认大小64MB.
在hdfs-default.xml文件中,如果用户根据自己的实际情况,需要修改默认的block的大小,如果修改为128MB,256MB的时候,需要注意的是(修改将在hdfs-site.xml文件中进行),同上。
流式数据,将待存储的数据划分为多个block,namenode将block放到不同的datanode中,但是不同于操作系统的切分单位(簇),若是文件大小小于默认大小,并不会按照默认大小来存储,而是按照实际的大小来存储,此外需要注意:
若是上亿(虚拟量)的数量是小文件来存储,此时可以进行,但是效率不高,造成namenode的压力过大,解决:可以将小文件合并处理,将会很有效果,所以也印证了hdfs对于海量小文件的存储,效果并不是很好。
源码中datanode的配置:
由名字可见,datanode进程是:dfs.data.dir 而namenode进程是:dfs.name.dir
解释是:datanode存储block的地方。
当 cd${hadoop.tmp.dir}(自己定义的目录)/dfs/data
ls 出现
在进入 cd current | ls 出现:
由图可知:block是成对出现的
由于上传数据的时候,会被分块,破坏,此时.meta文件主要类似是校验数据的作用,类似于(MD5)。
当上传文件的时候,在datanode的路径中去查看切分好的数据block。
例如:hadoop fs –put /
查询blocks:cd ${hadoop.data.dir}(自己定义)/dfs/data/current
ll:
但是发现,上传之后是在linux文件系统上面,是否可以通过手动拷贝传递?No,手动上传hdfs是不承认的(通过
hadoopfs –ls 是查看不到的),原因是namenode并不清楚是否上传。