分布式文件系统HDFS
- 简介
- 什么是HDFS
- 设计目标
- 优缺点
- 优点
- 缺点
- HDFS原理
- 系统架构
- 设计思想
- 角色分工
- Active NameNode(AN)
- Standby NameNode(SN)
- DataNode(DN)
- Client
- 文件存储
- Block数据块
- 放置策略
- Block文件
- 元数据
- 内存元数据
- 文件元数据
- 读写操作
- 写操作
- 读操作
- 安全模式
- 触发安全模式
- 离开安全模式
- HDFS高可用
- HDFS文件管理
- Shell命令
- REST API
- HDFS系统管理
- 系统配置
- 核心配置文件
- 环境变量文件
- Shell命令
- NameNode(格式化或恢复)
- Report(报告文件系统信息)
- Fsck(检查文件系统健康状况)
- Safemode(安全模式)
- NameNode HA(主备切换)
- Decommission or Recommission(DataNode退役和服役)
- Balancer(数据重分布)
- Balancer(数据重分布)
- BalancerBandwidth
- Distcp(分布式拷贝)
- 参考
Hadoop变成熟的一个原因正是HDFS高可用的出现。
简介
什么是HDFS
HDFS(Hadoop Distributed File System):Hadoop分布式文件系统,目前是Apache Hadoop的核心子项目。在开源大数据技术体系中,它的地位无可替代。
设计目标
- 需要运行在大量廉价商用机器上(需要容错机制)
- 简单一致性模型(不能并发不能随机):一次写入多次读取,支持追加写,但不允许并发写和随机修改,通过对写操作的严格限制来保证数据的一致性
- 流式数据访问:批量读而非随机读,关注吞吐量而非时间
- 存储大规模数据集:典型文件大小GB~TB(大文件),关注横向线性扩展
HDFS设计之初是为了数据仓库或数据湖这种一次写入以后只读的,因此要这种简单一致性模型。
优缺点
优点
- “三高”:高容错、高可用、高扩展:
① 数据冗余,多Block多副本,副本丢失后自动恢复
② NameNode HA(主节点高可用)、安全模式
③ 10K节点规模(线性扩展) - 海量数据存储:典型文件大小GB~TB,百万以上文件数量, PB以上数据规模
- 构建成本低、安全可靠
- 适合大规模离线批处理
缺点
- 不适合低延迟数据访问(不能做在线,存储大文件的传输速度也慢)
- 不适合存储小文件(磁盘寻道时间超过读取时间;元数据占用NameNode大量内存空间,每个文件或目录的元数据要占用150Byte。也就是说不管存储大文件还是小文件,NameNode占得内存都一样)
- 不支持并发写入(一个文件同时只能有一个写入者)
- 不支持随机修改(只能追加)
HDFS原理
系统架构
设计思想
采用了两种模式:Master/Slave(主从) + Active/Standby(主备)
主节点上的NameNode是一个账本的角色,账本没了就全无了,因此要设计几个standby的备用节点。Active账本是实时更新的,Standby里面的是稍微滞后的。
下面的一排是Slave节点,节点里面一个块是128MB,一个颜色代表相同的数据,例如紫色的有三块,来保证数据冗余。
一般而言,主节点个数是个位数的,Slave节点可以是几千个数目很大的。他们采用心跳(Heartbeats)来进行联系(每三秒一次)。当新机上线或者机器宕机,会采用Balance信号来进行数据交流,将数据重新迁移和分布。
例如一个文件大小有10GB,首先会将它切成128MB每块的Block,然后将它存储在NameNode上,并安排具体某个Block放在哪。
角色分工
Active NameNode(AN)
- 活动管理节点(Master / 集群中唯一)
- 管理命名空间:文件系统的目录层次空间
- 管理元数据:目录/文件的基本属性、Block相关信息、DataNode相关信息等
- 管理Block副本策略:副本数(默认3副本)、副本放置策略(放在哪几个DataNode上)等
- 管理DataNode:节点上下线动态监测、文件系统健康状况监测(DataNode心跳中汇报的数据)、 Block恢复和重分布等
- 处理客户端读写请求:审核权限,编制计划,并为DataNode分配任务
Standby NameNode(SN)
- 也叫热备管理节点(Hadoop3.0起允许多个)
- 主备切换:AN宕机后,经过Master选举和元数据恢复,SN升级为AN
- 元数据同步:正常运行期间的周期性同步(60秒一次)、AN宕机后的最新同步(最差情况下需要同步最近一分钟的数据)
DataNode(DN)
数据节点(Slave / 高扩展)
- 存储Block数据块和数据校验和
- 向AN和SN汇报情况:
正常运行下,通过心跳机制(默认3秒),定期汇报运行状况和Block信息(包括物理存储位置);集群启动时,进入安全模式(只读状态),集中上报Block信息 - 执行客户端发送的读写命令
Client
文件管理:将文件切分为128MB一个的Block,或将Block组装为文件;与NameNode交互,获取读写计划和相关元数据;与DataNode交互,读取或写入Block。
也负责发送HDFS管理命令。
文件存储
Block数据块
HDFS的最小存储单元(落盘的最小单元)。
多Block多副本:
- 文件被切分为若干个Block,每个Block有多个副本(默认3副本);
- Block以DataNode为存储单元,即一个DataNode上只能存放Block的一个副本
- 机架感知:尽量将副本存储到不同的机架上,以提升数据的容错能力
- 副本均匀分布:DataNode的Block副本数和访问负荷要比较接近,以实现负载均衡
默认大小是128MB,可设置(若Block中数据的实际大小小于设定值,例如最后一个Block没那么大 ,则Block大小 = 实际数据大小)
不推荐调整Block大小,如果调整需要满足:最小化寻址开销,降到1%以下;任务并发度和集群负载比较适中,作业运行速度较快。
如果块太小,寻址时间占比过高,而且任务太多,并发度太高,会导致集群负载过高,作业变慢;如果块太大,任务太少,导致并发度太低,导致集群负载过低,作业变慢。
因此如果要调整Block大小,需要实际去测试。
放置策略
副本1:放在Client所在节点上
副本2:放在与副本1不同的机架上
副本3:放在与副本2同一机架的不同节点上
副本N:在遵循相关原则的前提下,随机选择
Block文件
实际落盘如上图:
Block数据文件:DataNode本地磁盘中名为“blk_blockId”的Linux文件
Block元数据文件:DataNode本地磁盘中名为“blk_blockId_*.meta”的Linux文件,由一个包含版本、类型信息的头文件和一系列校验值组成
Block文件目录:DataNode启动时自动创建,无需格式化
元数据
包括:目录/文件的基本属性(如名称、所有者)、Block相关信息(如文件包含哪些Block、Block放在哪些节点上)、DataNode相关信息。
有内存元数据、文件元数据两种:
内存元数据
Active NameNode:最新的元数据(= fsimage + edits)
Standby NameNode:通过QJM定期(默认60s)同步AN的元数据
文件元数据
内存元数据持久化后生成的文件,包括edits(编辑日志文件)和fsimage(检查点镜像文件)
edits文件:编辑日志文件。记录文件系统的每一个变更操作,并定期瘦身。写元数据时要先写edits,再写内存。edits文件名通过“txid前后缀”标记所包含变更操作的范围。如下图,edits_0001-00019代表数据的范围。
fsimage文件:元数据检查点镜像文件。检查点为:时间间隔(默认1小时)或变更操作次数到了之后(默认100万),因此速度较慢。fsimage文件名标记出最后一个变更操作的txid,例如上图中:只要在内存中载入fsimage_19,然后执行edits_inprogress_20,即可还原出最新的元数据。瘦身时,会保存最近100万条的数据。
edits与fsimage持久化方法自Hadoop 2.x:
这里引入一个系统,QJM(Quorum Journal Manager)共享存储系统:仲裁方式,最好部署奇数(2n+1)个节点,最多容忍n个节点宕机;过半(大于n+1)节点写入成功,即代表写操作完成。
那么,基于QJM的edits持久化的步骤如上图所示:
① AN将变更操作同步写入本地和QJM edits;
② AN将该操作写入内存,并将结果反馈给Client
基于QJM的fsimage持久化:
① 在检查点,SN通过对内存中的NameSpace上锁,先将QJM edits定期同步(默认60s)暂停下来,再生成fsimage
② SN将fsimage上传到AN,同时恢复QJM定期同步
③ AN删除本地和QJM中的edits旧文件,完成瘦身
读写操作
写操作
- 首先发起一个写请求(hadoop fs -put word.txt /input),包括要上传的文件信息,要上传的路径是什么(/input)
- NameNode检查一下目录是不是占用,空间还够不够大
- 如果检查满足就返回允许上传给客户端
- 客户端将文件切块(Block),
- 客户端将文件切块的信息发送给NameNode(注意只发信息不发数据)
- NameNode检查DataNode的信息,进行计划
- 将可以使用的DataNode返回给客户端(相当于拿到一张许可证了)
- 客户端与DataNode建立传输通道,DataNode再与另外的DataNode建立管道传输block,这里先写Block再写元数据
- DataNode返回成功给客户端
读操作
读操作比较简单,客户端向NameNode查询需要的文件,NameNode查询文件所在位置,按照与客户端的举例返回给客户端,客户端按照距离由近到远逐个发给客户端。
安全模式
安全模式是HDFS的一种特殊状态(只读)。它是HDFS确保Block数据安全的一种保护机制。
大型集群是非常忌讳硬关机的
当Active NameNode启动时,HDFS会自动进入安全模式,DataNode主动向NameNode上报可用Block信息,在达到安全标准前,HDFS一直处于“只读”状态。
触发安全模式
- NameNode重启
- NameNode磁盘空间不足
- DataNode无法正常启动
- Block上报率低于阈值
- 日志中出现严重异常
- 用户操作不当,如强制关机(特别注意)
离开安全模式
当Block上报率 >= 阈值时,HDFS才能离开安全模式(默认阈值为0.999)(Block上报率:DataNode上报的可用Block个数 ÷ NameNode元数据记录的Block个数)
另外,不建议手动强制退出安全模式。
HDFS高可用
基于ZK实现Master选举:
(1)AN或AN-ZKFC宕机,其创建的临时Znode被删除,但永久Znode(存储AN地址)被保留
-若AN宕机,ZKFC失去与AN的心跳连接,从而监测到故障,然后主动删除临时Znode
-若AN-ZKFC宕机,ZK失去与ZKFC的心跳连接,会话超时后,临时Znode被自动删除
(2)Watcher触发,通知所有SN-ZKFC去竞争创建临时Znode,SN1-ZKFC创建成功,SN1被选举为New AN
(3)其他SN-ZKFC在临时Znode上注册监听器,等待下一次选举
通过AN-Fencing防止脑裂
(4)若New-AN-ZKFC发现永久Znode,则通过RPC调用AN-ZKFC的服务,将AN从Active切换为Standby
(5)若步骤④失败,则New-AN-ZKFC直接调用SSL命令(或者执行自定义Shell脚本),Kill AN进程
(6)若步骤④⑤均失败,则需要人工干预
(7)AN-Fencing成功后,New-AN-ZKFC将New AN从Standby切为Active,并正式对外服务(HDFS只读)
基于QJM实现元数据恢复
(8)New AN从QJM edits中下载最新的(≤60s)变更操作,并在内存中执行一遍,即可恢复
HDFS文件管理
Shell命令
# 使用面最广,可以操作任何文件系统
hadoop fs <args>
# 只能操作HDFS文件系统
hdfs dfs <args>
REST API
HDFS的所有接口都支持REST API:
hdfs://:<RPC_PORT>/
HDFS系统管理
系统配置
核心配置文件
core-site.xml:Hadoop全局配置
hdfs-site.xml:HDFS局部配置
环境变量文件
Hadoop-env.sh:设置了HDFS运行所需的环境变量
Shell命令
NameNode(格式化或恢复)
选项 | 含义 |
format | 格式化指定的NameNode。它启动NameNode,格式化它,然后关闭它。 |
force | 如果名称目录存在则格式化 |
nonInteractive | 如果名称目录存在,则中止,除非指定了-force选项 |
hdfs namenode [-format [-clustered cid] [-force] [-nonInteractive] ] | [-recover [-force] ]
Report(报告文件系统信息)
报告基本的文件系统信息和统计信息。
可选标志可用于筛选显示的数据节点列表。
hdfs dfsadmin [generic_options] [-report [-live] [-dead] [-decommissioning] ]
Fsck(检查文件系统健康状况)
hdfs fsck <path> [-move | -delete] | [-files [-blocks [-locations | -racks] ] ]
选项 | 含义 |
-path | 从此路径开始检查 |
-dalete | 删除损坏的文件 |
-files | 输出正在检查的文件 |
-files -blocks | 输出块状态 |
-files -blocks -locations | 输出块位置 |
-files -blocks -racks | 输出DataNode网络拓扑 |
-move | 移动损坏文件到 /lost+found |
Safemode(安全模式)
NameNode启动会自动进入安全模式(也支持手动进入),该模式下只支持读操作
检测Block上报率超过阈值,才会离开安全模式
在TDH中,为避免用户错误退出安全模式,增加了检查变量,只有设置变量后,命令才可以正确执行
慎用hdfs dfsadmin -safemode leave
hdfs dfsadmin [generic_options] [-safemode enter | leave | get | wait]
NameNode HA(主备切换)
hdfs haadmin -failover [--forcefence] [--forceactive] <serviceId> <serviceId>
hdfs haadmin -getServiceState <serviceId>
hdfs haadmin -transitionToActive <serviceId> [--forceactive]
hdfs haadmin -transitionToStandby <serviceId>
选项 | 含义 |
-failover | 在两个NameNode之间启动故障切换 |
-getServiceState | 确定给定的NameNode是活动的还是备用的 |
-transitionToActive | 将给定名称节点的状态转换为活动状态 |
-transitionToStandby | 将给定NameNode的状态转换为待机状态 |
Decommission or Recommission(DataNode退役和服役)
hdfs dfsadmin [generic_options] -refreshNodes
选项 | 含义 |
dfs.hosts | 命名包含允许连接到namenode的主机列表的文件。必须指定文件的完整路径名。如果该值为空,则允许所有主机 |
dfs.hosts.exclude | 命名包含不允许连接到namenode的主机列表的文件。必须指定文件的完整路径名。如果该值为空,则不排除任何主机 |
Balancer(数据重分布)
hdfs balancer [-threshold <threshold>]
[-exclude [-f <hosts-file> | <comma-separated list of hosts>] ]
[-include [-f <hosts-file> | <comma-separated list of hosts>] ]
Balancer(数据重分布)
集群平衡的标准:每个DataNode的存储使用率和集群总存储使用率的差值均小于阀值
默认阈值为10,设置值为0~100
BalancerBandwidth
hdfs dfsadmin [generic_options] [-setBalancerBandwidth <bandwidth in bytes per second>]
默认带宽为1M/s,主要为了Balance的同时不影响HDFS操作
建议Balance的时候,带宽设为10M/s,并且停止操作HDFS(流量较小时操作)
Distcp(分布式拷贝)
大规模集群内部和集群之间拷贝的工具
hadoop distcp options [source_path...] <target_path>