公众号后台比较多同学让我写面试相关的文章, 在之前的文章 从面试官的角度谈谈大数据面试 也聊了很多, 但是有同学吐槽说我没有把答案写上去, 当时我的心里是拒绝写的, 这有啥好写的, 又不难, Google 一大堆. 但是呢, 吐槽的人多了我也就妥协了, 这次我不仅把答案加上去了, 还会加很多的分析和建议.
之前也和大家说过, 由于市场所需, 行业红利, 金钱诱惑, 朋友下套... 等等原因(瞎说的瞎说的), 我的面试和被面试经验都还是比较丰富的, 可以帮助大家剖析下面试官的心理, 怎么能说出面试官比较喜欢的答案. 说实话, 面试的时候其实面试官可能会比你还希望你能进来这家公司, 只要你能戳到面试官的那个 "点", 那你就有戏.
以下
黑色字体是正经回答
引用是我小声 BB
hdfs 的数据读写过程 ?
这是一个很普通的问题, 我也很喜欢问这个问题, 但是我的目的也不仅仅是考察你懂不懂这个, 因为这个问题要答出来并不难, 很多人可能接触 hadoop 的第一天就知道了, 无非就是从 namenode 获取 block 元信息, pipline 写 datanode, 啪啦啪啦, 很平常的一顿操作, 很稳, 也没什么出彩的. 但是其实呢, 你也可以回答得 "装逼" 一点, 可能会让昏昏欲睡的面试官耳目一新, 对你稍微有点刮目相看, 印象也会稍微深刻一点,"这小子装逼装得还挺像样的...".
下面我要开始了.
" 读写的过程我稍微看过一下源码, 我先说下写的过程, 写会稍复杂些我可以讲得详细一点:
首先 client 创建一个 OutputStream 输出流, 在此过程中 client 通过 rpc 向 namenode 添加一个文件记录, 得到该文件的租约, 启动一个 DataStreamer 线程, 线程中会维护 dataQueue 和 ackQueue 队列.
FSDataOutputStream 输出流建好之后, 就可以调用 write 方法进行数据的写入. 在写入过程中先将数据写入 client 本地的缓存中, 此缓存默认是 9 个 chunk(512B)的大小, 当本地缓存写满之后 (如果要写入的数据长度大于本地缓存的长度, 则直接将缓存长度的数据写入 currentPacket 中) , 计算这些数据的 checksum, 并写入 currentPacket 中, currentPacket 写满之后放入 dataQueue 中排队并通知 DataStreamer 线程去 dataQueue 中消费数据.(数据先写入本地 buf, 然后写入 packet, 等 packet(64k)满之后才向 namenode 申请 blockId)
DataStreamer 线程从 dataQueue 中取出 packet, 如果 DataStreamer 的 stage 为 PIPELINE_SETUP_CREATE 时, 表示当前 block 的 pipeline 还没有建立, 向 namenode 申请 blockId 和 block 的 locations, 将申请到的 locations 组成一个 pipeline, 与第一个 dn 建立 socket 连接, 由 Sender 发送写请求.
新启动 ResponseProcessor 线程接收 dn 返回的 packet ack, 并更新 DataStreamer 的 stage, 由 PIPELINE_SETUP_CREATE 变为 DATA_STREAMING 将要发送的 packet 从 dataQueue 中移到 ackQueue 中, 然后向 pipeline 中发送 packet.
其实把 client 端的操作说完这个写过程基本就可以了, 当然如果你想更好一点可以看情况挑一些 datanode 端的内容来说, 或者你可以画个图, 边画边说显得更自然一点.
datanode 端在 client 创建 pipeline 时, 通过 DataXceiverServer 接收到 client 的 socket 请求, 创建一个 DataXceiver 线程, 由 DataXceiver 线程处理来自 client 的写请求;
DataXceiver 线程会实例化一个 BlockReceiver 对象, 并判断是否有 downstream, 如果有则创建一个 downstream 的 socket, 发送写请求;
与 downstream 建立连接之后, 在 blockReceiver.receiveBlock 循环调用 receivePacket 接收 packet, 向 downstream 发送 packet 之前将 packet 放入 ackQueue(当前 ackQueue 是 PacketResponder 线程维护的)中, 然后将 data 和 checksum 写入磁盘;
在 blockReceiver.receiveBlock 中还会启动一个 PacketResponder 线程, 此线程负责接收 downstream 发送的 packet ack, 校验成功之后从 ackQueue 中移除, 向 upstream 发送自己的 ack 和 downstream 的 ack;
最终所有的 ack 都汇集到 ResponseProcessor 线程中, 如果 ack 没有 error 则从 ackQueue 中移除; 如果有 error, 先将 ackQueue 中的 packet 移到 dataQueue 中, 然后将发生 error 的 dn 从 pipeline 中删除, 从 namenode 中重新申请 dn 与原有的没有发生 error 的 dn 组成新的 pipeline, 在 addDatanode2ExistingPipeline 中判断是否要 transfer 已经发送的 packet, 将已经发送成功的 packet 从之前正常的 dn 上 transfer 到新增加的 dn 上, 并更新 block 是 stamp, 这样发生故障的 DataNode 节点上的 block 数据会在节点恢复正常后被删除.
其实讲到这里已经是超额完成任务了, 真实面试的过程中不需要像我上面说得那么复杂和准确, 可以直接复述我上面的内容, 适当地说几个类名来, 读的过程就不需要再说得那么详细, 不然可能会适得其反, 让面试官听得有点不耐烦, 所以可以尽量简洁一些.
1, 跟 namenode 通信查询元数据, 找到文件块所在的 datanode 服务器
2, 挑选一台 datanode(就近原则, 然后随机)服务器, 请求建立 socket 流
3,datanode 开始发送数据(从磁盘里面读取数据放入流, 以 packet 为单位来做校验)
4, 客户端以 packet 为单位接收, 先在本地缓存, 然后写入目标文件
当然为了避免翻车, 还是希望大家可以真的去看看部分源码, 装 X 要适当, 稍微秀一下就可以, 不然被追问导致翻车的可能性还是有的.
hdfs 有哪些进程, 各自的作用是什么?
NameNode:Namenode 管理者文件系统的 Namespace. 它维护着文件的元数据, 包括文件名, 副本数, 文件的 BlockId, 以及 block 所在的服务器, 会接受来自 client 端的读写请求, 和 datanode 的 block 信息上报.
DataNode:hfds 的工作节点, 他们根据客户端或者是 namenode 的调度存储和检索数据, 并且定期向 namenode 发送他们所存储的块 (block) 的列表.
JournalNode: 负责两个 NameNode 高可用时的数据同步保证数据一致, 存放 NameNode 的 editlog 文件(元数据), 部署在任意节点, 奇数个.
DFSZKFailoverController(ZKFC): 负责监控 NameNode 的健康状态, 并及时把信息状态写入 Zookeeper, 如有异常会触发主从切换, 部署在有 NameNode 的节点.
另外你上百度搜这个问题的话, 很少会提到后面两个进程, SecondaryNameNode 却经常被提到, 这个东东其实可以不用说, 是 hadoop 比较旧而且已经基本没公司用的一种部署方式, NameNode 会有单点问题, 所以可以不用和其他的混合在一起说.
hdfs 如何保证可用性 ?
NameNode 的高可用由 JournalNode 和 DFSZKFailoverController 保证, JN 负责主从数据的一致, ZKFC 负责主从的 failover;
数据在 HDFS 中是默认存储三份的, 且在不同的 DataNode, 所以 DataNode 挂掉两台仍然能保证数据的完整性;(挂三台的概率理论上是很低的, 真挂了的话就算是重大事故了, 等着罚钱吧. 那有什么更好的解决办法呢? 其实是有的, 就是逢年过节记得要拜拜服务器, 多上几柱香)
JournalNode 也是分布式的, 因为有选举机制, 所以默认要大于 1 的奇数个服务器在线, 挂掉一两台问题也不太大, 但是要做好监控.
DFSZKFailoverController(ZKFC)这个进程貌似在设计上并没有去关注可用性的问题, 它是部署在两个 NameNode 节点上的独立的进程, 但是其实他的作用就是辅助 zookeeper 做 NameNode 的健康监控, 所以可以直接说 Zookeeper 的可用性.
Zookeeper 是一个独立的分布式系统, 用于管理和协调分布式系统的工作, 它本身也会通过 zab 协议来保证数据一致, 和主备节点的选举切换等等.
另外, 这个类型的文章我也准备来写一个系列, 每一篇会涉及几个大数据面试的问题和答案, 也会有我的一些想法和建议. 这是开篇, 就先写 HDFS 相关的, 另外我会尽量提高发文的频率, 大家还是多多支持啦, 好看就点个在看吧.
觉得有价值请关注 ▼
来源: https://www.cnblogs.com/uncledata/p/11427989.html