HDFS
hdfs读流程
-
客户端向NameNode发起RPC请求,请求文件block位置
-
NameNode检查是否有访问权限,如果有权限则继续检查是不是有这个文件,如果有这个文件则返回部分或全部的block列表,对于每个block,NameNode会返回含有该副本的DataNode地址
-
客户端根据就近原则挑选一台DataNode,请求读取数据
-
DataNode开始传数据给客户端
-
当读完列表的block后,若文件读取没有结束,向NameNode获取下一批block列表
-
读取完一个block会进行checksum验证,如果读取DataNode时出现错误,客户端会通知NameNode,然后从下一个拥有该block的DataNode继续读取
-
客户端以packet为单位接收数据,先存入缓存
-
最终读取的所有block合并成一个完整的文件
可以这样理解:
我很喜欢玩拼图游戏也爱好收藏拼图,手里有很多个拼图,而且每个拼图有多个相同的副本(因为我怕有一天丢失了找不到就不能玩了,多备几份以防丢失
- 你要在我的房间里找一个完整拼图,只不过这个东西被我分为了几个部分,而且这个拼图有三份被我放在不同的位置,你要找到所有的模块才能拼成一个完整的拼图
- 我是不是想让你玩这个拼图游戏,如果我也想让你玩也得看看我有没有这个拼图,如果有我给你提供这张拼图的所有块都在哪个地方写在本本上分页提供给你
- 你非常聪明人格也高尚,为了给国家省粮食在我给你的地点里挑最近的地方去取所有的地图块
- 把地图块一块一块收集起来
- 如果在我给你的一页上没有找到所有的块,你再来找我要剩下的地图块对应的信息
- 拿到地图块之后先看看这个地图块是不是又破损,如果有破损则去另外一个地方去拿相同的一块
- 拿到地图块后先把地图块放在随身的背包里
- 最终开心的将每个地图块拼成一张完整的地图
hdfs写流程
1. client发起上传文件请求,通过rpc与NameNode建立通信,NameNode检查目标文件是否存在,父目录是否存在,返回是否可以上传
-
client请求第一个block该传输到哪些DataNode服务器上
-
NameNode根据配置文件中指定的备份数量及机架感知原理进行文件分配,返回可用的DataNode地址:比如A,B,C三台机器
-
client请求3台DataNode中的其中一台A上传数据,A收到请求后会调用B,B再调用C,建立整个pipeline
-
client开始向A上传block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(默认64K)上传,A收到一个packet就会传给B,B再传给C,A每传一个packet会放入一个应答队列等待应答
-
数据被分割成一个个packet数据包在pipeline上一次传输,在pipeline反方向逐个发送ACK(命令正确应答),最终由pipeline中第一个节点A将pipeline ack发送给客户端
-
当一个block传输成功后,client再同理请求NameNode上传第二个block,第三个block。。。。直至上传完毕
可以这样理解:
有一天你爸妈给你买了一副拼图,你怕你的小弟弟给你弄丢了你决定把拼图保存在我这里
- 你想存在我这里肯定要跟我打招呼,然后我看看我这里有没有这个拼图,如果有了就不需要存了,随你的小弟弟去玩,丢了你打不了以后来我这里借;如果没有我也图个新鲜就让你存在我这里偷玩
- 为了保险和我这里空间的问题我们将地图分块存储,我给你能够存放的地方
- 因为我太爱拼图了,也因为你是我的好朋友怕丢了对你不好交代,所以我用我家的3D打印机复制出两份,分别把3份地图放在不同的地方
- 我比较聪明,在第一个存放的地方做了一个记号存储第二个存放的地方,又在第二个地方做了一个记号记录存放的第三个地方
- 你开始在第一个地方放地图的第一块,然后放到第二块,接着第三块
- 放完之后你跟我说三块都准确无误的放完了
- 我们再这样放地图的第二块,第三块。。。。。。直至都存放完毕