大数据处理架构 Hadoop
## Hadoop 简介
- 两大核心
- HDFS
- MapReduce
- 优点
- 高可靠
- 高效性
- 高扩展
- 成本低
- Lunix
- 多语言、跨平台
-
框架
- Hadoop 不同版本
- Hadoop 1.0 到 Hadoop 2.0 对
- 将1.0负责资源处理的模块抽出,在2.0版本
YARN
(资源调度框架) MapReduce
只做资源处理
工作,不在做资源调度
工作,并架构在YARN
上(第一个架构在YARN上的计算框架,其他的有Spark
、Storm
)HDFS
- 1.0 扩展性差,只有一个
NameNode
- 2.0引入
NN Federration
HA
- 利用
Secondary NameNode
分担NameNode工作量 - 利用高可用
HA
:High availability
- 利用
- 1.0 扩展性差,只有一个
- 将1.0负责资源处理的模块抽出,在2.0版本
- Hadoop 1.0 到 Hadoop 2.0 对
## Hadoop 项目结构
## Hadoop 安装部署
- 单机模式:本地模式,访问本地磁盘
- 伪分布式:Hadoop 可以在单节点以伪分布式的方式运行,Hadoop 进程以分离的Java进程来运行,节点即作为
NameNode
也作为DataNode
,同时读取都是HDFS
的文件 - 分布式模式:多个机器部署
伪分布式模式部署
- 1、创建hadoop用户
useradd -m hadoop -s /bin/bash passwd hadoop
- 2、关闭防火墙、
SELinux
,配置hosts
文件映射systemctl stop firewalld systemctl status firewalld
- 3、
SSH
免密登录ssh-keygen -t rsa ssh-copy-id localhost
- 4、
jdk
安装,配置环境变量 - 5、解压Hadoop,并修改权限为hadoop用户,在环境变量中添加Hadoop环境变量
- 6、修改配置文件
-
$HADOOP_HOME/etc/hadoop/hadoop-env.xml
export JAVA_HOME=/usr/local/big_data/jdk1.8.0_201
- $HADOOP_HOME/etc/hadoop/core-site.xml
<property> <name>hadoop.tmp.dir</name> <value>file:/usr/local/hadoop/tmp</value> </property> <!-- 当然,你也可以不在core-site.xml文件中配置fs.default.name参数,这样当你读写一个文件或目录时,需要使用全URI地址,即在前面添加“hdfs://host0001:9000” --> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <!-- 设置 web UI 为静态用户--> <property> <name>hadoop.http.staticuser.user</name> <value>root</value> </property>
- $HADOOP_HOME/etc/hadoop/hdfs-site.xml
<!-- 表示副本数量,伪分布式要设置1 --> <property> <name>dfs.replcation</name> <value>1</value> </property> <!-- 表示本地磁盘目录,是存储fsimage文件的地方 --> <property> <name>dfs.namenode.name.dir</name> <value>file:/usr/local/hadoop/tmp/name</value> </property> <!-- 表示本地磁盘目录,HDSF数据存放block的的地方 --> <property> <name>dfs.namenode.data.dir</name> <value>file:/usr/local/hadoop/tmp/data</value> </property>
- $HADOOP_HOME/etc/hadoop/mapred-site.xml
<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
- $HADOOP_HOME/etc/hadoop/yarn-site.xml
<property> <name>yarn.resourcemanager.hostname</name> <value>localhost</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>
- $HADOOP_HOME/etc/hadoop/slave
# 填入数据节点的hostname localhost
-
- 7、初始化文件系统
hadoop namenode star-format
- 8、启动所有进程
start-all.sh start-dfs.sh start-yarn.sh
- 9、通过Web页面、jps观察进程是否正常
- 50070:hadoop web UI
- 8088:yarn web UI
分布式模式部署
- 删除
docs 网页文档
加快传输过程 - 注意slave,yarn的启动机器配置
scp -rq # 不显示传输过程
高可用分布式模式部署
介绍
-
双
NameNode
-
也就是一个
NameNode
处于Active
(活跃) 状态另一个
NameNode
处于Standby
(备用)状态,通过这种机制实现
NameNode
的双机热备高可用功能。
-
-
双
NameNode
的运行原理 -
只有
Active
状态的NameNode
是正常工作的,Standby
状态的NameNode
处于随时待命状态,它时刻去同步Active
状态NameNode
的元数据。一旦
Active
状态的NameNode
不能工作,可以通过手工
或者自动
切换方式将Standby
状态的NameNode
转变为Active
状态,保持
NameNode
持续工作。这就是两个高可靠的NameNode
的实现机制。 -
可自动切换
-
Zookeeper
集群进行仲裁选举-
能够为集群协作数据提供监控 并将数据的更改随时反馈给客户端
HDFS
的热备功能依赖ZK
提供的两个特性:错误监测
、活动节点选举
-
高可用机制:每个
NameNode
都会在ZK
中注册并且持久化-一个session
标识 一旦NameNode
失效了,那么session
也将过期 而ZK也会通知其他的NameNode
发起一个失败切换 -
独占锁:如果当前的活动
NameNode
失效了 那么另一个NameNode
将获取ZK中的独占锁,表明自己是活动的节点 -
ZKFailoverController
(ZKFC) :ZK集群的客户端 用来监控NN的状态信息,每个运行NameNode
的节点必须要运行一一个ZKFC提供
健康检查
、session管理
、基础选举
-
-
HDFS
集群中的两个NameNode
都在ZooKeeper
中注册 当Active
状态的NameNode
出故障时ZooKeeper
能马.上检测到这种情况 它会自动把Standby
状态切换为Active
状态
-
-
可手动切换
- 如果不配置zookeeper,可以手工切换Active NN/Standby NN;如果要配置zookeeper自动切换,还需要提供切换方法,也就是要配置
dfs.ha.fencing.methods
参数。
- 如果不配置zookeeper,可以手工切换Active NN/Standby NN;如果要配置zookeeper自动切换,还需要提供切换方法,也就是要配置
-
双
NameNode
架构中的元数据一致性如何保证-
通过
Quorum Journal Node (JournalNode)
集群(2 * n + 1
台)或者network File System (NFS)
进行数据共享 -
NFS
是操作系统的 -
JournalNode
是Hadoop
层面的,成熟可靠、使用简单方便。 -
当
Active
状态的NameNode
元数据有任何修改时 会告知大部分的JournalNodes
进程,如果2 / n + 1
的节点写入成功,则算成功。 -
Standby
状态的NameNode
也会读取JNs
中的变更信息 并且一直监控EditLog
(事务日志)的变化 并把变化应用于自己的命名空间,Standby
可以确保在集群出错时元数据状态已经完全同步了
-
-
总体架构图
部署
- 配置
- core-site.xml ```XML
fs.defaultFS hdfs://ns1 hadoop.tmp.dir 你的路径/tmp ha.zookeeper.quorum sa3:2181,sa1:2181,sa2:2181 ipc.client.connect.max.retries 30 * hdfs-site.xml ```xml <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.nameservices</name> <value>ns1</value> </property> <property> <name>dfs.ha.namenodes.ns1</name> <value>nn1,nn2</value> </property> <!-- nn1的RPC通信地址,nn1所在地址 --> <property> <name>dfs.namenode.rpc-address.ns1.nn1</name> <value>master:8020</value> </property> <!-- nn1的http通信地址,外部访问地址 --> <property> <name>dfs.namenode.http-address.ns1.nn1</name> <value>master:50070</value> </property> <!-- nn2的RPC通信地址,nn2所在地址 --> <property> <name>dfs.namenode.rpc-address.ns1.nn2</name> <value>master2:8020</value> </property> <!-- nn2的http通信地址,外部访问地址 --> <property> <name>dfs.namenode.http-address.ns1.nn2</name> <value>master2:50070</value> </property> <!-- 指定NameNode的元数据在JournalNode日志上的存放位置(一般和zookeeper部署在一起) --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://sa1:8485;sa2:8485;sa3:8485/ns1</value> </property> <!-- 指定JournalNode在本地磁盘存放数据的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/home/hadoop/opt/software/hadoop-2.6.0/data/journal</value> </property> <!--客户端通过代理访问namenode,访问文件系统,HDFS 客户端与Active 节点通信的Java 类,使用其确定Active 节点是否活跃 --> <property> <name>dfs.client.failover.proxy.provider.ns1</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <!--这是配置自动切换的方法,有多种使用方法,具体可以看官网,在文末会给地址,这里是远程登录杀死的方法 --> <property> <name>dfs.ha.fencing.methods</name> <value>sshfence shell(/bin/true) </value> </property> <!-- 这个是使用sshfence隔离机制时才需要配置ssh免登陆 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/home/hadoop/.ssh/id_rsa</value> </property> <!-- 配置sshfence隔离机制超时时间,这个属性同上,如果你是用脚本的方法切换,这个应该是可以不配置的 --> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> <!-- 这个是开启自动故障转移,如果你没有自动故障转移,这个可以先不配 如果不用zk,想自己改变节点状态,需要注释--> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>
- yarn-site.xml ```xml
yarn.nodemanager.aux-services mapreduce_shuffle yarn.resourcemanager.ha.enabled true yarn.resourcemanager.cluster-id rmcluster yarn.resourcemanager.ha.rm-ids rm1,rm2 yarn.resourcemanager.hostname.rm1 master yarn.resourcemanager.hostname.rm2 master2 yarn.resourcemanager.zk-address sa1:2181,sa2:2181,sa3:2181 yarn.resourcemanager.recovery.enabled true * mapred-site.xml ```xml <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
- slave
Slave1 Slave2 Slave3
- 启动流程
- 在每个slave节点上面启动zk命令:zkServer.sh start,启动完成后查看状态,命令:zkServer.sh status
- 在每台子节点启动JournalNode进程,命令:hadoop-daemon.sh start journalnode
- 在其中一台主节点格式化,命令:hdfs namenode -format
- 在这个节点上启动namenode进程,命令:hadoop-daemon.sh start namenode
- 在另一个主节点上同步namenode元数据,命令:hdfs namenode -bootstrapStanby
- 在这台机子上启动namenode,此时两台机子的webUI(hostname:50070)显示两台机子都是standy状态,接下来手动强制其中 一个为active,命令:hdfs haadmin -transitionToActive nn1 –forcemanual,此时再去查看webUI可以发现其中一台为active状态
- 接下来是自动故障转移,先把整个集群关闭zk不关
- 执行:hdfs zkfc -formatZK;验证:slave节点登录,输入命令:zkCli.sh,输入命令ls / 看到 hadoop-ha表示这个配置ok
- 在所有的NN启动zkfc,命令:hadoop-daemom.sh start zkfc在启动集群:start-dfs.sh,观察webUI发现其中一台机子会是工作状态,那么配置完成。现在手动把工作状态的那台机器的namenode进程给结束,在观察webUI会发现另一台机器变为工作状态(会有点慢)
### 集群部署和使用
- HDFS
- NameNode 总管家
- 是一个目录服务器,数据存储的具体地址的信息。当应用来取数据的时候会先访问
NameNode
,然后获取数据存储的地址信息,然后再去访问相应的DataNode
- 管理各种元数据并提供服务
- NameNode里面有很多元数据直接保存在内存当中
- 机器配置最高的
- 是一个目录服务器,数据存储的具体地址的信息。当应用来取数据的时候会先访问
- DataNode 数据节点
- 存储元数据
- 机器配置硬盘要大
- SecondaryNameNode
- hdfs组件,冷备份数据
- 机器配置要和NameNode相当,如果集群不是很大可以运行在同一台机器上
- NameNode 总管家
- MapReduce两大核心组件
- JobTracker 作业管家
- 负责对用户的作业进行处理,他会将用户的一整个作业拆分为小作业,分发到不同的机器上面去执行,JobTracker去协调不同的机器去执行
- TaskTracker
- 负责跟踪和执行分配给自己的那一小部分作业
- 通常都和DataNode运行在同一节点
- JobTracker 作业管家
分布式文件系统HDFS
#### 分布式文件系统HDFS简介
- 分布式存储
- 分布式处理
- 解决海量数据的存储问题
-
强一致性
- HDFS 实现目标
- 兼容廉价设备
- 支持大数据集
- 实现流数据读写
- 支持简单的文件模型
- 强大的跨平台兼容性
- HDFS 自身的局限性
- 不适合低延迟数据访问
- 无法高效存储大量小文件
- 不支持多用户写入及任意修改文件
### HDFS 相关概念
- 块 (核心概念)
- 为了分摊磁盘读写开销,寻址开销;降低分布式节点寻址开销
- HDFS 的块比普通文件大得多
- 默认64M(如果块过大会导致MapReduce就一两个任务在执行安全牺牲了MapReduce的并行度,发挥不了分布式并行处理的效果)
- 支持面向大规模数据存储
- 缺点
- 如果块过大会导致MapReduce就一两个任务在执行安全牺牲了MapReduce的并行度,发挥不了分布式并行处理的效果
- 优点
- 支持大规模文件存储
- 简化系统设计(方便元数据管理,很容易算出一个文件需要多少块,以及他的存储需求)
- 适合数据备份(冗余)
-
NameNode
-
整个HDFS集群的管家
-
接收用户操作请求
-
记录信息
-
数据目录
- 文件目录树维护和文件对应的
block
列表的维护 - 管理
block
和DataNode
之间的关系
- 文件目录树维护和文件对应的
-
管理文件系统命名空间、集群配置信息及存储块的复制
-
在分布式文件系统中,文件是以块的形式分散存储在不同的节点 这些分散在不同节点中的数据块可能属于同一个文件 为了组织众多的文件 可以把文件放到不同的文件夹中 文件夹一级一级的包含,这种组织形式就称为命名空间
-
元数据(
metadata
)- 文件是什么
- 文件分成多少块
- 块和文件是怎么映射的
- 每个块存储在那个服务器(
DataNode
)上面- 存储信息是通过数据节点
DataNode
向名称节点汇报得来的,最后在内存中维护 - 实时维护
- 存储信息是通过数据节点
- 内存
- 关键数据结构
-
FsImage
:相当于当前系统的快照,只读- 保存系统文件树
- 记录文件复制等级
- 修改和访问时间
- 访问权限
- 块大小以及组成的文件的块
- 数据块到文件的映射
- 里面记录了自最后一次
检查点
之前HDFS文件系统中所有目录和文件的信息
- 保存系统文件树
-
EditLog
:在系统启动过后进行记录新的操作,达到阈值之后会通过第二名称节点
进行合并。- 记录对数据进行的诸如创建、删除、重命名等操作
- 也就是自最后一次
检查点
之后所有针对HDFS文件系统的操作 都会记录在Edit Log文件中 - 主
NameNode
会有非常多的EditLog
文件,HA的备份节点中,只有一个edits_inputprogress_xxx
-
-
其他:对元数据进行持久化存储的,名为
fsImage
,内存中也要放一些元数据信息 虽然很容易丢失,但可以提供查询服务,实际上就是读写分离,由读写分离就有了数据一致性的问题实际上是记录在edits.log中,这个文件不提供修改,只提供追加,以日志的形式记录;当一个文件上传时,会将空间分配信息记录在
EditLog
,然后在一个文件副本写入成功后,将EditLog
数据更新至内存。元数据会在编辑日志有所改动后进行更新。内存中的元数据用来提供读数据请求服务。 - 启动过程 * 把`FsImage`文件从底层磁盘加载到内存 * `FsImage`是记录的历史的相关数据结构信息,需要通过`EditLog`和合并(回放)才能得到最新的元数据 * 将新的`FsImage`保存到从内存保存到本地 * 同时删除旧的`EditLog` * 最后在创建一个空的`EditLog` * 这样合并的过程就是一个`检查点(checkpoint)` - 检查点:如果`EditLog`过大,`SecondaryNameNode`会将其拉走,并将与`FsImage`进行合并,最后发送回 `NameNode`,如果是在`HA`集群,`fsImage、EditLog`合并会通过 `StandByNameNode`完成。 * 它的出现是为了解决Edit Log文件会不断变大的问题 在`NameNode`运行期间 HDFS的所有更新操作都是直接写到Edit Log文件中. 一段时间之后,Edit Log文件会变得很大 当Edit Log文件非常大的时候,就会导致`NameNode`启动过程非常慢 * 两次`checkpoint`的时间间隔达到阈值 此属性由`dfs.namenode.checkpoint.period`控制 默认是3600s,也就是一小时触发一次 * 新生成的`Edit Log`中积累的事务数量达到阈值 此属性由`dfs.namenode.checkpoint.txns`控制 默认1000000,也就是HDFS经过100万次操作后就要进行`checkpoint`了 * 由于资源消耗过大,不会再`NameNode`节点上发生 * Hadoop 1.0 2.0 单命名空间:由`SecondaryNameNode`来完成 * Hadoop 2.0 HA:由Standby状态的`NameNode`来实现
-
可以通过 配置文件来修改元数据副本数
-
dfs.namenode.name.dir
可添加多个目录参数进行副本的配置,建议不再统一磁盘
-
-
存储在硬盘的格式
- 有大量以 edits_ 开头的文件,这些就是 Edit Log 文件。记录在 Edit Log 之中的每一个操作又称为一个事务,每个事务都有一个整数形式的事务 id 作为编号。这些 edits_ 开头的文件名类似
edits_${start_txid}-${end_txid}
,并且多个 Edit Log 之间通过 txid 首尾相连。 ${start_txid}
表示 edits 的起始事务 id,而${end_txid}
表示 edits 的结束事务 id。正在写入的 edits 文件处于inprogress
(真正写入) 状态,其文件名为edits_inprogress_${start_txid}
,已经写入完成的 edits 处于 finalized 状态,名字就变成了edits_${start_txid}-${end_txid}
。- 还有两个
Fsimage
文件,该文件的名称类似fsimage_${end_txid}
,此文件在NameNode
上保存的数目由dfs.namenode.num.checkpoints.retained
参数控制,超出的会被删除,默认保存 2 个。历史Fsimage
文件通常只会在元数据损坏的时候用来做恢复用,适当保留几份就够了,太多了不仅没用,反而浪费磁盘空间。 - 还有两个文件,一个是 VERSION 文件,此文件是一个 Java 格式文件,保存了 HDFS 的版本号信息;另一个是
seen_txid
文件,此文件非常重要,它记录了最后一次 checkpoint 或者 edit 回滚(将edits_inprogress_xxx
文件回滚成一个新的Edit Log
文件)之后的 transaction ID,它主要用来检查NameNode
启动过程中 Edit Log 文件是否有丢失的情况。
-
当客户端对 HDFS 中的文件进行新增或者修改操作,操作记录首先被记入 edits 日志文件中,当客户端操作成功后,相应的元数据会更新到内存元数据中,然后定时持久化到内存当中。因为
fsimage
文件一般都很大(GB 级别的很常见),如果所有的更新操作都往fsimage
文件中添加,这样会导致系统运行的十分缓慢。 -
HDFS 这种设计实现着手于:一是内存中数据更新、查询快,极大缩短了操作响应时间;二是内存中元数据丢失风险颇高(断电等),因此辅佐元数据镜像文件(
fsimage
)+编辑日志文件(edits
)的备份机制进行确保元数据的安全。- 在HA模式下,客户端请求只能和主
NameNode
进行通信 而主NameNode
会将写操作信息,分别写入本地的Edit Log文件中和JournalNode中的Edit Log文件
StandbyNameNode
只会周期性的去JournalNode
中读取Edit Log文件进行同步,并将生成的新Fsimage
文件传送给主NameNode
- 在HA模式下,客户端请求只能和主
-
第二名称节点:
SecondaryNameNode
- 名称节点的冷备份
- 对
EditLog
的处理 - 运行机制(实现了不断增大的
EditLog
和FsImage
的合并,并实现了冷备份)- 提供节点的服务
FsImage
和EditLog
- 第二名称节点会定期地和名称节点进行通信
- 当
EditLog
文件过大时会请求NameNode
停止使用EditLog
文件 NameNode
收到请求过后会停止写入EditLog
,并创建新的edits.new
文件,并在之后把所有新的操作写入新的edits.new
- 第二名称节点此时会通过
HTTPGet
的方式从NameNode
上把FsImage
、EditLog
都下载到本地 - 第二名称节点做合并操作,然后在发送到
NameNode
- 最后将
edits.new
文件重命名为edits
- 提供节点的服务
- 通过
SecondaryNameNode
不能完整的恢复元数据信息,可能会丢失一部分数据,所以在Hadoop 2.0 中加入了StandbyNameNode
。
-
- 数据节点(
DataNode
)- 负责存储实际数据
- 存取
- 文件保存到各自节点的磁盘
- 块的格式
-
StandbyNameNode
NameNode
的备用模式- 处于
Standby
模式,不能接受用户请求 - 他会通过
JournalNode
时刻NameNode
同步元数据 - 当
NameNode
发生故障后,Zookeeper会及时发现问题,进行主备切换 - 完全意义的热备份
StandbyNameNode
之所以会周期地让主NameNode
对Edit Log文件进行回滚 间隔周期由dfs.ha.log-roll.period
指定,默认是120s 是因为StandbyNameNode
不会读取inprogress
的Edit Log文件 它只会周期性(dfs.ha.tail-edits.period,
默认是60s)的去检测已经完成的Edit Log文件 然后将该Edit Log文件通过JournalNode
读取到内存 进而更新Fsimage
在内存中的状态- 检查点
- 在达到checkpoint触发条件后
新的
Fsimage
文件会在StandbyNameNode
上生成StandbyNameNode
会删除自己磁盘上保留的陈旧Fsimage
文件 然后将新的Fsimage
文件上传给主NameNode
- 在达到checkpoint触发条件后
新的
- 主
NameNode
元数据目录下会有非常多的EditLog
文件 而在StandbyNameNode
元数据目录下只有一个edits_ inprogress_XXX 文件 这是因为StandbyNameNode
并不会从JournalNode
.上拉取Edit Log文件保存到磁盘 而主NameNode
下Edit Log文件 每两分钟(由dfs.ha.log-roll.period
控制)生成一个 所以我们需要定期清理陈旧的Edit Log文件
-
JournalNode
:防止脑裂- 只会在HA模式下出现,其作为一个守护进程,实现了元数据在主、备节点的共享
- 指定元数据处存储目录:
hdfs-site.xml
->dfs. journalnode.edits.dir
- 包含一个VERSION文件
多个
edits_xx
文件和一个edits_inprogress_XXX
文件 还包含一-些与HA实现相关的文件 这些文件主要是为了防止脑裂(两个NameNode
节点同时运行) 但JournalNode
中并不包含fsimage
和seen_txid
文件
#### HDFS 体系结构
- 采用主从架构
- 主节点
- 数据节点 N 个
- HDFS 命名空间
- 目录
- 文件
- 块
-
通信协议
- 局限性
- 命名空间限制:名称节点是保存在内存中的,因此,名称节点能够容纳的对象(文件、块)的个数会受到空间大小限制
- 性能瓶颈:整个分布式文件的吞吐量,受限于单个名称节点的吞吐量
- 隔离问题:隔离问题:由于集群中只有一个名称节点,只有一个命名空间,因此无法对不同应用程序进行隔离
- 集群的可用性:一旦这个唯一的名称节点发生故障,会导致整个集群变得不可用(
SecondnaryNameNode
是冷备份,不能及时工作,需要一定时间才会恢复NameNode
),在2.0中会有高可用
#### HDFS 存储原理
- 冗余数据保存问题
- 默认冗余因子是3
- 加快数据传输速度(3个备份的数据可以同时被3个应用访问)
- 很容易检查数据错误(因为有备份,可以通过比对副本,效验数据)
- 保证数据可靠性(会自动复制到冗余因子数)
- 负载不均衡时候也会自动调整
- 数据节点发生故障时候也会自动调整
- 数据保存策略问题
- 数据会就近保存一份到本机,第二备份放在不同的机架,第三个副本放在与第一个副本相同的机架上,往后随机
- 数据读取
- 就近原则
- HDFS提供了一个API可以确定一个数据节点所属的机架ID,客户端也可以调用API获取自己所属的机架ID
- 当客户端读取数据时,从名称节点获得数据块不同副本的存放位置列表,列表中包含了副本所在的数据节点,可以调用API来确定客户端和这些数据节点所属的机架ID ,当发现某个数据块副本对应的机架ID和客户端对应的机架ID相同时就优先选择该副本读取数据,如果没有发现,就随机选择-个副本读取数据
- 数据恢复问题
- 名称节点出错
- 会暂停服务一段时间,然后在第二名称节点取回
FsImage
、EditLog
,最后恢复服务
- 会暂停服务一段时间,然后在第二名称节点取回
- 数据节点出错
- 数据节点定期通过远程调用发送心跳至名称节点,
- 如果隔一个周期收不到心跳信息,则故障,并标记为宕机
- 最后在重新复制数据至冗余因子的数量
- 数据本身出错
- 采用效验码校对数据
- 在数据生成时候就会生成校验码,并存储同一个文件目录,然后在应用读取文件时候会自动进行校验码计算并和本地的校验码数据进行核对
- 名称节点出错
#### HDFS 数据读写过程
- 注意
- 一次写入,多次读取(不可修改,只可追加)
- 文件由数据块(Block) 组成 数据块大小默认128MB,若文件不足128M,则也会单独存成一个块 一个块只能存一个文件的数据 即使一个文件不足128M,也会占用一个块 块是一个逻辑空间,并不会占磁盘空间
- 默认情况下每个块都有三个副本
三个副本会存储到不同的节点上,副本越多,磁盘利用率越低
但数据的安全性越高
可以通过修改
hdfs-site.xml -> dfs.replication
属性设置副本的个数 - 文件
- 按大小被切分成若干个块 存储到不同的节点上,块大小可通过配置文件进行配置或修改
-
读取
- 客户端向
NameNode
请求读取一个文件,NameNode
通过查询元数据,找到请求文件对应的数据块所在的位置,也就是块文件对应的DataNode
节点地址; NameNode
返回自己查询到的元数据信息给客户端;- 客户端挑选一台
DataNode
(根据就近原则,然后随机原则)服务器,开始请求读取数据; DataNode
开始传输数据给客户端(从磁盘里面读取数据放入流,以 packet 为单位来做校验);- 客户端以 packet 为单位接收,先在本地缓存,然后写入目标文件。
- 客户端向
-
写入
-
首先,客户端对
NameNode
发起上传文件的请求。NameNode
接到请求后,马上检查请求文件是否已存在,上级目录是否存在。 -
NameNode
检查发现,请求的文件如果不存在,就响应客户端请求,可以上传文件。 -
Client 会首先对文件进行切分。假定 HDFS 的一个
block
大小是 128M,如果写入的文件大小有 300M,那么此文件就会被切分成 3 个块,分别是两个 128M 和一个 44M。接着,客户端向NameNode
发起请求第一个 block 该传输到哪些DataNode
服务器上。 -
NameNode
返回信息给 Client,告知可以上传到哪些DataNode
服务节点上。这里假定有三个副本,所以一个块需要上传到三个节点上,这里设定上传到 A、B、C 三个DataNode
节点。 -
Client 开始和
DataNode
建立传输通道,首先请求DataNode
A 节点上传数据(本质上是一个 RPC 调用,建立 pipeline),DataNode
A 收到请求后,会继续调用DataNode
B;然后DataNode
B 再去调用第三个DataNode
C,将整个 pipeline 建立完成,逐级返回 Client。 -
Client 开始往 A 上传第一个 block(先从磁盘读取数据放到一个本地内存缓存),以 packet 为单位(一个 packet 为 64KB),
DataNode
A 收到一个 packet 就会传给DataNode
B,DataNode
B 接着传给DataNode C
;DataNode A
每传一个 packet 会放入一个应答队列,等待应答。 -
当一个 block 传输完成之后,Client 再次请求
NameNode
开始上传第二个 block,上传过程重复上面 4~6 步骤。
-
HDFS Shell
hadoop fs
: 适用于任何不同的文件系统,比如本地的文件系统和HDFS文件系统hadoop dfs
: 只能适用于HDFS文件系统-
hdfs dfs
: 与hadoop dfs
一样只能用于HDFS文件系统 -
查看
[root@yarnserver ~]# hadoop fs -ls / [root@yarnserver ~]# hadoop fs -ls /user [root@yarnserver ~]# hadoop fs -cat /logs/demo10.txt [root@yarnserver ~]# hadoop fs -text /logs/demo10.tar.gz #通过 -text 可查看压缩文件的内容,支持场景的 zip、gzip、bzip2 等压缩格式 [root@yarnserver ~]# hadoop fs -du -s /tez #查看/ tez 目录所占空间大小
-
增加
[root@yarnserver ~]# hadoop fs -touch /logs/demo101.txt [root@yarnserver ~]# hadoop fs -mkdir /logs/demo [root@yarnserver ~]# hadoop fs -put /local/demo10.tar.gz /logs/demo #这里的 /local/demo10.tar.gz 是本地路径 [root@yarnserver ~]# hadoop fs -copyFromLocal /localdemo10.tar.gz /logs/demo #这个实现功能同 put 参数,都是上传本地文件到 HDFS [root@yarnserver ~]# hadoop fs -get /logs/demo/demo10.tar.gz /home/hadoop #这里的 /home/hadoop 是本地路径 [root@yarnserver ~]# hadoop fs -copyToLocal /logs/demo/demo10.tar.gz /home/hadoop #这个实现功能同 get 参数,都是下载 HDFS 文件到本地系统磁盘 hadoop fs -cp /logs/demo/demo10.tar.gz /tmp #这个命令中两个路径均为 HDFS 上路径
-
移动
[root@yarnserver ~]# hadoop fs -mv /logs/demo/demo10.tar.gz /tmp #这个命令中两个路径均为 HDFS 上路径 [root@yarnserver ~]# hadoop fs -moveFromLocal /tmp/spark-2.4.5-bin-hadoop2.7.tgz /logs/demo/ #这个命令中 /tmp/spark-2.4.5-bin-hadoop2.7.tgz 路径为本地路径
-
删除文件
- core-site.xml 文件中增加
fs.trash.interval
参数,表示进入回收站中的文件多少分钟后会被系统永久删除,可以根据情况设置一个合适的时间周期。
# 无论是文件或者目录,都可以通过如下命令进行删除: [root@yarnserver ~]# hadoop fs -rm -r /logs/demo/demo10.tar.gz # 你确定某个文件可以删除,不需要进入回收站的话,可以执行如下命令 [root@yarnserver ~]# hadoop fs -rm -r -skipTrash /tmp/hive_test # 清空回收站 [root@yarnserver ~]# hadoop fs -expunge
- core-site.xml 文件中增加
-
追加文件
[root@yarnserver ~]# hadoop fs -appendToFile aa1.log /logs/aa.log
-
对文件进行授权
[root@yarnserver ~]# hadoop fs -chown -R hadoop:hadoop /logs/aa.log [root@yarnserver ~]# hadoop fs -chmod 744 /logs/aa.log