如何比较装X地回答问题 | 面试系列.1

公众号后台比较多同学让我写面试相关的文章,在《从面试官的角度谈谈大数据面试》也聊了很多,但是有同学吐槽说我没有把答案写上去,当时我的心里是拒绝写的,这有啥好写的,又不难,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数据会在节点恢复正常后被删除。

其实讲到这里已经是超额完成任务了,真实面试的过程中不需要像我上面说得那么复杂和准确,可以直接复述我上面的内容,适当地说几个类名来,读的过程就不需要再说得那么详细,不然可能会适得其反,让面试官听得有点不耐烦,所以可以尽量简洁一些。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywypz.html