将笔记中HDFS中部分学习总结记录于此,对HDFS进行粗浅的介绍。
提出问题:1.HDFS副本存放策略;2.大文件写入策略(切分blocks,三份备份);3.HDFS不适合存储小文件,为什么?(元数据存储在内存中,过多小文件带来大量元数据,导致namenode负载过大)
建议读GFS原版论文,多读读。
概述:
优点:
缺点:
只能把现有的追加后删除原有文件。真实环境中,此类应用场景占据80%,因此用途较广
架构和原理:
目前标准配置:3TB×12
考虑问题:文件备份,负载均衡,IO限制难以并行处理
HDFS:将大文件切片,分块存储。记录两张表:第一张记录文件构成的block;第二张记录每个block存在哪个节点
按顺序读取,把文件拼接。文件切分和组装对用户透明
容易做负载均衡,易于和上层框架结合。HDFS是Master&Slave架构,master主要工作存储上述两张表
master不能只有一个,ActiceNamenode、StandbyNamenode,前者挂掉接管
Datanode汇报心跳信息,Namenode确认存活,若挂机,Namenode寻找其他节点重构副本,保持副本个数
ActiveNamenode:管理HDFS名称空间,目录、文件等;管理数据块映射,副本放置策略(两个表);处理读写请求
StandbyNamenode:同步Namenode数据信息
Datanode:干活,存储数据块,执行读写任务
Client:客户端,进行文件切分;与Namenode交互获取文件位置信息;管理、访问HDFS。可以是Namenode或Datanode
特殊配置Federation
文件切分:hadoop2.0开始默认最大128MB一个block,一个block数据只能来自一个文件
HDFS写入流程:
client发起一个写入信息,Namenode检查元数据,若存在文件名则拒绝写入。写入前先与namenode通信,获取3个Datanode地址,(HDFS未采用多线程写入方案,有时对于频繁访问的数据,可能会增加部署副本个数,平摊压力。因此在线程特别大时,客户端的IO带宽成为瓶颈)HDFS首先往节点1写入,写入一个小package(如64kb),节点1写给节点2,节点2写给节点3,由此客户端出口带宽不会成为瓶颈,性能与多线程写入基本一致。
HDFS读取流程:
先发起通信给Namenode,获取第1个block的Datanode地址,从所有副本节点中找一个来读取,读取完毕再如此读取第2个block。客户端接受所有blocks后拼接返回给用户
HDFS副本放置策略:
读取数据尽量在本机架内读取,跨机架的读写性能低。假设客户端本身是Datanode,首先将写入本机,另外两个副本寻找另一个机架的两个副本。可以实现机架级别的容错,3个副本写在两个机架是可靠性和性能的折中。继续增加副本将随机在整个网络中其他机器加载
HDFS可靠性策略:
文件完整性CRC校验码;定期心跳信息;元数据信息拷贝,FSImage、Editlog、多分存储,主备Namenode切换
HDFS不适合存储小文件,一个block元信息消耗大约150byte内存,过多的小数据将占用Namenode大量内存
问题:如何判断不同机架?需要对HDFS拓扑结构配置文件进行配置指定
MR计算结果都很小,需要做合并
HDFS程序设计方法:
HDFS可以通过Thrift(Facebook开源的RPC框架)来实现多种语言编程API
Shell访问:fs -du -h /home;fs -put xx /tmp; fs -ls /tmp;管理命令 fs dfsadmin
fs fsck /tmp/*** -files -blocks -locations可以打印文件数据信息 (fsck有用)
负载均衡器bin/start-blancer.sh -threshold <20%> 最低和最高的差距,将搬运block直到满足阈值
给每个文件设置一个quota,最多使用磁盘空间 hadoop dfsadmin -setSpaceQuota 1t(或100个) /user/username
加入新的datanode,将打包拷贝到新datanode启动;删除datanode,加入datanode黑名单
Java访问HDFS:java包:org.apache.hadoop.fs;
通过Thrift来实现其他语言API,需要启动一个Thrift Server
HDFS优化小技巧:
文本文件不便于压缩,选择合适的压缩算法很重要;不建议将日志直接存储成文本文件
Squence File:二进制格式,便于压缩,压缩格式作为元信息,Flume默认格式
小文件优化:MR合并成大文件SequenceFile,key是文件名,value是文件内容;Hadoop Archives打包,把多个文件打包。
若多个独立小文件,如图片类型,不建议存储在HDFS建议存储在Hbase
引入纠删码,节省一半空间,达到同样容错效果。需要做一些计算。Hadoop3.0有
文件管理模块:
数据分区:年月日
原始日志存储格式选择SequenceFile,便于压缩
原始信息可用列式存储ORC或Parquet保存
原始日志→Hive表→ORC格式数据表
增加热点副本个数:API修改、配置参数修改、命令行
冷热数据:对半年没访问过的冷数据做高压缩、小文件合并等处理
异构存储可以指定存储介质类型
HDFS可以在本地IDE运行,将XML文件拷贝到resources中配置环境变量
答疑:distcp从一个集群拷贝到另一个集群;hadoop集群数据不存在单点,不需要做RAID;HDFS会始终保持副本3,如果挂掉的节点复活,会删除新节点
配置参数:hdfs-site.xml
Dfs.datanode.data.dir:配置多个物理盘,用,分格/mnt/disk1, /mnt/disk2
Dfs.datanode.failed.volumns.tolerated 容忍磁盘失败数目,0为False,如设置为3,达到3块磁盘坏时停止写入,只能读取,直到修复
Dfs.datanode.du.reserved 每块磁盘余留给非HDFS预留的空间,达到预留则停止写入本磁盘
Dfs.datanode.balance.bandwidthPerSec 平衡间隔带宽
Dfs.datanode.handler.count 非读写RPC线程数,默认10个,如果节点多,可以调大
Dfs.datanode.max.transfer.threads 读写线程数,默认4096,节点数小于200基本不用调整
Namenode配置参数:
Fs.trash.interval 配置垃圾桶存放时间 cross-site.xml
Fs.replication 副本数默认为3
Fs.block.size block大小 一般也在cross-site.xml
Fs.namenode.handler.count 线程数
JVMneicun canshu hadoop-env.sh配置
Namenode进程的JVM配置:内存较大机器,启用CMS垃圾回收机制,Datanode不用太大内存,2-4G