1.HDFS( 存储功能)特点:
- 大规模数据集(支持节点扩展)
- 简单一致性模型(一次写入多次读取)
- 流式数据访问(对数据进行批量处理,而不是用户交互处理)
- 硬件错误(有很强的容错能力)
- 权限问题(写入者就是拥有者)。
- 安全性,不是很高。
2.HDFS组成:
namenode datanode 以及secondarynamenode,edits,fsimage等
namenode(管理者)
:存储为数据的元数据(medadata描述数据
属性(
property)的
信息
,用来支持如指示存储位置、
历史
数据、
资源
查找、文件记录等功能。),namenode管理文件系统的命名空间。维护着整个文件系统树,以及真个树内的所有文件和目录,但是它并不存储真正的数据。但如果它被破环了,那么datanode上的数据也会变成垃圾数据。同时,它作为客户端与HDFS的入口。
datanode(工作者) :datanode则是存储真正的数据,并定期通过心跳机制向namenode汇报自己的状况。由于hadoop移动计算而不是移动数据的特点,所以它也是执行计算的地点。 datanode副本机制(如下图) :为保证很强的容错性datanode默认有三个副本(可在配置文件中修改),默认一个机架上两个副本(不在同一个机器上),这是因为同一机架数据流速度更快,另一副本放在另一机架(同一机架一般共享同一电源,防止整个机架宕机)。
详细可参考:
secondarynamenode: fsimage是为namenode元数据在磁盘中的存储形式,每次HDFS启动都是通过加载它来初始化文件系统。(安全模式,整个系统的初始化)。 edits为客户操作日志(对HDFS各种操作的记录),当edits文件的大小超过一定量,需要与fsimage进行合并,以保证磁盘中的源文件与内存中的文件的同步,而namenode面对高访问量的客户端请求,而操作日志和源文件的合并是一个极费时间和资源的过程,则由secondarynamenode来做这部分工作。 secondarynamenode可以是namenode一大部分数据的备份,但它的主要工作却不是备份。
3.HDFS配置文件简单介绍:
1.core-site.xml
<configuration>
<!--配置namenode的位置以及端口(或者说HDFS文件系统的入口)-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
<!--用来指定使用hadoop时产生文件的存放目录,默认在tmp目录下,计算机重启数据可能丢失,建议改默认配置
同时hadoop.tmp.dir这个目录非常重要。其他如namenode,datanode的工作目录是以该目录为基础目录-->
<property>
<name>hadoop.tmp.dir</name>
<value>file:///usr/hadoop/hadoop-2.6.0/tmp</value>
</property>
<!--用来设置检查点备份日志的最长时间-->
<name>fs.checkpoint.period</name>
<value>3600</value>
</configuration>
2.hdfs-site.xml
<configuration>
<!--指定hdfs保存数据的副本数量-->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!--指定hdfs中namenode的存储位置,建议修改默认配置-->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/hadoop/hadoop-2.6.0/tmp/dfs/name</value>
</property>
<!--指定hdfs中datanode的存储位置,建议修改默认配置-->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/hadoop/hadoop-2.6.0/tmp/dfs/data</value>
</property>
</configuration>
3.mapred-site.xml
<configuration>
<!--告诉hadoop以后MR(Map/Reduce)运行在YARN上-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuratio
4.yarn-site.xml
<configuration>
<!--nomenodeManager获取数据的方式是shuffle-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--指定Yarn的老大(ResourceManager)的地址-->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
<!--Yarn打印工作日志-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<configuration>
4.HDFS数据流介绍
读文件,首先上图:
1.首先调用FileSystem对象的open方法,其实是一个DistributedFileSystem的实例。
2.DistributedFileSystem通过RPC(二进制数据流交互)从namenode获得文件的block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面.
3.客户端调用read方法,FSDataInputStream最会找出离客户端最近的datanode并连接,通过反复的调用read方法,可以将数据从datanode传输到客户端(可在多个datanode并发)。
4.数据从datanode源源不断的流向客户端。
5.如果第一块的数据读完了,就会关闭指向第一块的datanode连接,接着读取下一块。这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流。
6.如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的块都读完,这时就会关闭掉所有的流。
如果在读数据的时候,DFSInputStream和datanode的通讯发生异常,就会尝试正在读的block的排第二近的datanode,并且会记录哪个datanode发生错误,剩余的blocks读的时候就会直接跳过该datanode。DFSInputStream也会检查block数据校验和,如果发现一个坏的block,就会先报告到namenode节点,然后DFSInputStream在其他的datanode上读该block的镜像
该设计的方向就是客户端直接连接datanode来检索数据并且namenode来负责为每一个block提供最优的datanode,namenode仅仅处理block location的请求,这些信息都加载在namenode的内存中,hdfs通过datanode集群可以承受大量客户端的并发访问。
写文件
1.客户端通过调用DistributedFileSystem的create方法创建新文件
2.DistributedFileSystem通过RPC调用namenode去创建一个没有blocks关联的新文件,创建前,namenode会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,namenode就会记录下新文件,否则就会抛出IO异常.
3.前两步结束后会返回FSDataOutputStream的对象,象读文件的时候相似,FSDataOutputStream被封装成DFSOutputStream.DFSOutputStream可以协调namenode和datanode。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列data quene。
4.DataStreamer会去处理接受data quene,他先问询namenode这个新的block最适合存储的在哪几个datanode里,比如重复数是3,那么就找到3个最适合的datanode,把他们排成一个pipeline.DataStreamer把packet按队列输出到管道的第一个datanode中,第一个datanode又把packet输出到第二个datanode中,以此类 推。
5.DFSOutputStream还有一个对列叫ack quene,也是有packet组成,等待datanode的收到响应,当pipeline中的所有datanode都表示已经收到的时候,这时akc quene才会把对应的packet包移除掉。
如果在写的过程中某个datanode发生错误,会采取以下几步:1) pipeline被关闭掉;2)为了防止防止丢包ack quene里的packet会同步到data quene里;3)把产生错误的datanode上当前在写但未完成的block删掉;4)block剩下的部分被写到剩下的两个正常的datanode中;5)namenode找到另外的datanode去创建这个块的复制。当然,这些操作对客户端来说是无感知的。
6.客户端完成写数据后调用close方法关闭写入流
7.DataStreamer把剩余得包都刷到pipeline里然后等待ack信息,收到最后一个ack后,通知datanode把文件标示为已完成。
另外要注意得一点,客户端执行write操作后,写完得block才是可见的,正在写的block对客户端是不可见的,只有调用sync方法,客户端才确保该文件被写操作已经全部完成,当客户端调用close方法时会默认调用sync方法。是否需要手动调用取决你根据程序需要在数据健壮性和吞吐率之间的权衡。
5.其他
hadoop1.0的缺陷:
NameNode 单点故障问题 压力过大
JobTracker 单点故障问题 压力过大
hadoop2.0改进:
NNFederation:支持水平拓展(多个namenode,每个NameNode分管一部分目录,但是所有的NameNode共享所有DataNode上的存储资源)工作可以独立,但共享所有的datanode 。通过多个namenode/namespace把元数据存储和管理分散到多个节点,使得namenode/namespace可以通过增加机器来实现水平扩展。能把单个namenode的负载分散到多个节点,在HDFS数据规模较大的时候也不会影响性能。可以通过多个namespace来隔离不同类型的应用,把不同类型应用的HDFS元数据的存储和管理分派到不同的namenode。
YARN(分布式资源管理系统):管理包过内存cpu等,是HDFS和计算框架之间的东西,可以理解为接口。由它进行各种资源的分配,所有的计算任务都向yarn去申请资源,提高了资源的利用率。
hadoop2.0新引进来的资源管理系统,是从MR1演化而来的;
- 核心思想:将MR1中的JobTracker的资源管理和任务调度两个功能分开,分别由ResourceManager和ApplicationMAster进程实现
- ResourceManager:负责整个集群的资源管理和调度
- ApplicationMaster:负责应用程序相关的事物,比如任务调度、任务检控和容错等
YARN的引入,使得多个计算框架可以运行在一个集群中
- 每个应用程序对应一个ApplicationMaster
- 目前多个计算框架可以运行在YARN上,比如MapRuce、Spark、Storm等。
着重讲下namenode的高可用HA机制:
如果namenode出现问题,整个HDFS集群将不能使用。是不是可以有两个或者多个namenode,一个为对外服务->active,其他处于待机->standby,他们存储datanode的元数据存放至另外一个集群,来保证它的安全性。
1.主 Active ,备Standbg(可以多个) datanode的心跳机制会将datanode情况向多个namenode汇报。
2.为了能让备份的NameNode能够在发生故障的时候成功的接管NameNode,它的元数据不在存储在NameNode的本地,而是存储在JournalNodes的集群中(通过多台机器来保证数据的安全)。
3.有两种方式提供HDFS的高可用:共享文件夹(NFS和zk ,为用户提供二次开发接口,关于ZooKeeper读者可查阅其他资料进行学习。在这里可简单理解为,多个namenode的状态和控制协调由zk完整。 首先请求ZK,ZK知道哪个namenode是活的。(心跳检测)failoverControllerActive(自动切换namenode) ZK必须使用奇数个,投票机制。
HA(高可用)配置简介:
(具体配置可参考官方文档 http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html )
配置hdfs.site.xml文件:
1.配置集群的命名服务(dfs.nameservices)
2.配置所有namenode的命名服务。
3.配置多个namenode节点的RPC协议和端口。
4.配置多个namenode节点的HTTP协议和端口。
5.配置JN的url地址。
6.配置客户端找到活动namenode的java类,这个一般是固定的。
7.配置ssh fence。
8.配置JN的工作目录。
9.配置自动切换
配置core.site.xml
1.配置namenode的入口。
2.配置zk的集群。
zoo.cfg(zk的配置文件)
不重启集群添加节点:
1。在新节点上安装hadoop,并且复制现有的hadoop集群的配置文件。
2。确保集群的主节点可以对新节点进行免密登陆(SSH)。
3。将新节点的IP或者DNS添加到slaves文件中去。
4。可以在从节点启动DataNode进程。
bin/hadoop-deamon.sh start datanode
当新增的节点比较多时也可以在主节点上执行start-start.sh
5.在新节点上启动(MapReduce)TaskTrecker
Hadoop-deamom.sh start tasktracker
6.HDFS再平衡,需要我们手动再平衡。
start-balancer.sh -threshold 15
DataNode下架:
需要向集群中添加一个排出文件(exclude.file),,并在hdfs-site.xml文件中配置<name>dfs.hosts.exclude</name>用来指向他。
将需要下架的节点的主机名添加到排出文件中。
运行命令重新加载配置文件
hadoopdfsadmin -refresh Nodes
重新添加回集群,可以从exclude中删除节点,执行:Hadoop dfsadmin -refreshNodes命令。