hdfs
概念
1.适合一次写入,多次读出。
2.优点:高容错(多副本);适合大数据;可用廉价服务器
3.缺点:不适合低延时访问数据;无法高效对大量小文件进行存储;不支持并发写入;不能随机修改(只能append)
特点
高容错 : 由于 HDFS 采用数据的多副本方案,所以部分硬件的损坏不会导致全部数据的丢失
高吞吐量 : HDFS 设计的重点是支持高吞吐量的数据访问,而不是低延迟的数据访问。
大文件支持 : HDFS 适合于大文件的存储,文档的大小应该是是 GB 到 TB 级别的。
简单一致性模型 : HDFS 更适合于一次写入多次读取 (write-once-read-many) 的访问模型。支持将内容追加到文件末尾,但不支持数据的随机访问,不能从文件任意位置新增数据
跨平台移植性 : HDFS 具有良好的跨平台移植性,这使得其他大数据计算框架都将其作为数据持久化存储的首选方案
Block
1.2.x/3.x默认128M;1.x默认64M;本地模式32M
2.寻址时间为传输时间1%最好
3.Block太大,在磁盘上的传输时间过长,Map太少
4.Block太小,寻址时间过长
5.磁盘传输速度决定Block大小
window操作HDFS API只需要hadoop/bin和hadoop.client。依靠jar调用bin里的命令操作。
读写流程
三个单位
1.block是最大的一个单位,它是最终存储在DataNode上的数据粒度。由dfs.block.size参数决定。默认是128M。
2.packet是中等单位,它是dfsClient流向DataNode的粒度,以dfs.write.packet.size参数决定,默认是64kb。注:这个参数是参考值,是指真正传输时,会以这个参数为基准进行调整。调整的原因是packet特定的结构,调整的目标是这个packet的大小刚好包含结构中所有的元素,同时也保证写入DataNode后当前packet的大小不会超过设定值。
3.chunk是最小的粒度,是dfsClient流向DataNode进行数据校验的粒度。默认512b
注:事实上一个chunk还包含4b的校验值,因而写入packet时是516b。数据与校验值比例是128:1,所以128M的block会有1M的校验文件与之对应。
HDFS文件块目录结构
${dfs.datanode.data.dir}/
├── current
│ ├── BP-526805057-127.0.0.1-1411980876842
│ │ └── current
│ │ ├── VERSION
│ │ ├── finalized
│ │ │ ├── blk_1073741825
│ │ │ ├── blk_1073741825_1001.meta
│ │ │ ├── blk_1073741826
│ │ │ └── blk_1073741826_1002.meta
│ │ └── rbw
│ └── VERSION
└── in_use.lock
in_use.lock表示DataNode正在对文件夹进行操作
rbw是“replica being written”的意思,该目录用于存储用户当前正在写入的数据。
Block元数据文件(*.meta)由一个包含版本、类型信息的头文件和一系列校验值组成。校验和也正是存在其中。
写流程
Client向NameNode发起RPC请求。
Namenode会检查文件是否存才,是否有权限进行操作,成功会为文件创建一个记录,否则让客户端抛出异常。
当客户端开始写文件,数据流入dfsOutputStream,dfsOutputStream内会有一个chunk大小的buff,当数据写满buff(或强制flush)时,会计算checkSum值,然后填塞进packet。
当一个chunk填塞进packet后,仍不会立即发送,而是积累到一个packet填满后,将这个packet放入dataqueue队列。进入dataqueue队列的packet会被另一个线程按顺序取出发送到datanode。
client还会向NameNode申请blocks,获取用来存储replicas的合适datanode列表,列表大小根据Namenode中relication的设定而定。
开始以pipline的形式将packet写入所有replicas中。开发库把packet以流的方式写入第一个datanode,该datanode把该packet存储之后,再传递给pipline的下一个datanode,直到最后一个datanode,最后一个datanode成功存储返回ack packet(确认消息),在pipline里传递至客户端,客户端开发库内部维护着ack queue,成功收到datanode返回的ack packet后,会从 ack queue移除相应的packet。
如果传输过程中,有某个datanode出现故障,开发库关闭pipline,出现故障的datanode会被移除,剩余的block会继续在剩下的datanode中以pipline的方式传输,同时namenode会分配一个新的datanode,保证replicas的设定数量。
客户端完成数据写入后,close掉数据流。
注1:生产者消费者模型,阻塞生产者的条件是dataqueue与ackqueue之和超过了一个block的packet上限
注2:只要写入达到dfs.replication.min的副本数(默认1),写操作就成功,并且这个块可以在集群中异步复制,直到达到目标副本数。
注3:namenode在addblock动作后不知道block副本元信息,知识返回给客户端一个LocatedBlock对象,包含了存放Block的位置。只有接收存储block成功的消息后才正式记录block位置。
图片.png 图片.png
读操作:
1.Client向NameNode发起RPC请求
2.Namenode视情况返回全部或部分Block列表,对于每个block,Namenode都会返回该block拷贝的DataNode地址。
3.客户端选取离它最近的Datanode读取block,如果客户端本身就是DataNode,就直接本地读取。
4.读完当前block,关闭与当前DataNode链接。并选择下一个block的最佳DataNode
5.当读取完列表Block,如果还没读完,继续向NameNode申请Block列表。
注:读取完一个block都会进行checksum验证,如果读取datanode时出现错误,客户端会通知namenode,然后从下一个拥有该block的datanode继续读。
图片.png
网络拓扑
求路径和
机架感知
BlockPlacementPolicyDefault(chooseTargetInOrder)
第一个副本在Client所处节点上。如果客户端在集群外,随机选一个
第二个副本在另一个机架随机一个节点
第三个副本在第二个副本的机架的另一个随机节点
NN和2NN工作机制
seen_txid:保存一个数字,就是最好一个edits_的数字
NN
fsImage:HDFS文件系统元数据的一个永久性检查点,包含HDFS文件系统的所有目录和文件inode的序列化信息
1.第一次启动生成/之后加载Edits和fsImage镜像
2.客户端请求cud
3.cud操作先记录在Edits.inprogress上
4.cud
2NN
5.2NN定期发送CheckPoint给NN,如果需要CheckPoint(edits写满或定时)
6.执行CheckPoint,滚动edits.inprogress,得到edits,拷贝fsImage,合成FsImage.ckpt
7.fsImage.ckpt返还给NN,重命名为新的fsImage
DN工作机制
图片.png1.DN:1个block分为两块数据:数据本身和元信息(校验和,长度,时间戳)
2.启动去NN注册
3.返回注册成功
4.周期性上报块信息
5.提交心跳(心跳返回结果带有NameNode给DataNode的命令,如复制数据块到另一个DataNode或删除数据块),心跳默认3秒一次,如果10分钟没有收到某个DataNode的心跳,则认为该节点不可用。
心跳机制
NameNode 不会将任何新的 IO 请求转发给标记为死亡的 DataNode, 也不会再使用这些 DataNode 上的数据
由于 DataNode 不再可用, 可能会导致某些块的副本数小于指定值, NameNode 会跟踪这些块, 再必要的时候进行重新复制
数据完整性CheckSum
1.当DataNode读取Block的时候,它会计算CheckSum
2.如果计算后的CheckSum与Block创建时值不一样,说明Block已经损坏。
3.Client读取其他DataNode上的Block
4.常见校验算法crc(32),md5(128),sha1(160)
5.DataNode在其他文件创建后周期验证CheckSum
6.https://blog.csdn.net/qq_27087973/article/details/80401206