公众号后台比较多同学让我写面试相关的文章,在《从面试官的角度谈谈大数据面试》也聊了很多,但是有同学吐槽说我没有把答案写上去,当时我的心里是拒绝写的,这有啥好写的,又不难,Google一大堆。但是呢,吐槽的人多了我也就妥协了,这次我不仅把答案加上去了,还会加很多的分析和建议。

之前也和大家说过,由于市场所需,行业红利,金钱诱惑,朋友下套...等等原因(瞎说的瞎说的),我的面试和被面试经验都还是比较丰富的,可以帮助大家剖析下面试官的心理,怎么能说出面试官比较喜欢的答案。说实话,面试的时候其实面试官可能会比你还希望你能进来这家公司,只要你能戳到面试官的那个“点”,那你就有戏。

以下
黑色字体是正经回答
引用是我小声BB

hdfs 的数据读写过程 ?

这是一个很普通的问题,我也很喜欢问这个问题,但是我的目的也不仅仅是考察你懂不懂这个,因为这个问题要答出来并不难,很多人可能接触hadoop的第一天就知道了,无非就是从namenode获取block元信息,pipline写datanode,啪啦啪啦,很平常的一顿操作,很稳,也没什么出彩的。但是其实呢,你也可以回答得“装逼”一点,可能会让昏昏欲睡的面试官耳目一新,对你稍微有点刮目相看,印象也会稍微深刻一点,“这小子装逼装得还挺像样的...”。

下面我要开始了。

“读写的过程我稍微看过一下源码,我先说下写的过程,写会稍复杂些我可以讲得详细一点:

  1. 首先client创建一个OutputStream输出流,在此过程中client通过rpc向namenode添加一个文件记录,得到该文件的租约,启动一个 DataStreamer 线程,线程中会维护 dataQueue和ackQueue队列。

  2. FSDataOutputStream 输出流建好之后,就可以调用 write 方法进行数据的写入。在写入过程中先将数据写入client本地的缓存中,此缓存默认是9个chunk(512B)的大小,当本地缓存写满之后 (如果要写入的数据长度大于本地缓存的长度,则直接将缓存长度的数据写入currentPacket中) ,计算这些数据的checksum,并写入currentPacket中,currentPacket写满之后放入dataQueue中排队并通知DataStreamer线程去dataQueue中消费数据。(数据先写入本地buf,然后写入packet,等packet(64k)满之后才向namenode申请blockId)

  3. DataStreamer线程从dataQueue中取出packet,如果DataStreamer的stage为PIPELINE_SETUP_CREATE时,表示当前block的pipeline还没有建立,向namenode申请blockId和block的locations,将申请到的locations组成一个pipeline,与第一个dn建立socket连接,由Sender发送写请求。

  4. 新启动ResponseProcessor线程接收dn返回的packet ack,并更新DataStreamer的stage,由PIPELINE_SETUP_CREATE变为DATA_STREAMING 将要发送的packet从dataQueue中移到ackQueue中,然后向pipeline中发送packet。

其实把client端的操作说完这个写过程基本就可以了,当然如果你想更好一点可以看情况挑一些datanode端的内容来说,或者你可以画个图,边画边说显得更自然一点。

  1. datanode端在client创建pipeline时,通过DataXceiverServer接收到client的socket请求,创建一个DataXceiver线程,由DataXceiver线程处理来自client的写请求;

  2. DataXceiver线程会实例化一个BlockReceiver对象,并判断是否有downstream,如果有则创建一个downstream的socket,发送写请求;

  3. 与downstream建立连接之后,在blockReceiver.receiveBlock循环调用receivePacket接收packet,向downstream发送packet之前将packet放入ackQueue(当前ackQueue是PacketResponder线程维护的)中,然后将data和checksum写入磁盘;

  4. 在blockReceiver.receiveBlock中还会启动一个PacketResponder线程,此线程负责接收downstream发送的packet ack,校验成功之后从ackQueue中移除,向upstream发送自己的ack和downstream的ack;

  5. 最终所有的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相关的,另外我会尽量提高发文的频率,大家还是多多支持啦,好看就点个在看吧。

觉得有价值请关注 ▼

如何比较装X地回答问题 | 面试系列.1的更多相关文章

  1. 面试系列-面试官:你能给我解释一下javascript中的this吗?

    一.前言 关于javascript中的this对象,可能已经被大家说烂了. 即使是这样,我依然决定将这篇文章给水出来.毕竟全国在新型肺炎的影响下,公司没法正常复工. 除了刷刷手机,还是要适当的学习一下 ...

  2. java程序猿面试系列之jvm专题

    前言 因为疫情的影响,现在都变成金五银六了.为了方便大家,在此开一个程序猿面试系列.总结各大公司所问的问题,希望能够帮助到大家,适合初中级java程序猿阅读. 1. Java类实例化时,JVM执行顺序 ...

  3. 【Java进阶面试系列之一】哥们,你们的系统架构中为什么要引入消息中间件?

    转: [Java进阶面试系列之一]哥们,你们的系统架构中为什么要引入消息中间件? **这篇文章开始,我们把消息中间件这块高频的面试题给大家说一下,也会涵盖一些MQ中间件常见的技术问题. 这里大家可以关 ...

  4. 【阿里面试系列】Java线程的应用及挑战

    文章简介 上一篇文章[「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景]我们了解了进程和线程的发展历史.线程的生命周期.线程的优势和使用场景,这一篇,我们从Java层面更进一步了解线程的使用.关 ...

  5. JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载

    我写的程序员面试系列文章 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Jav ...

  6. 程序员面试系列之Java单例模式的攻击与防御

    我写的程序员面试系列 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Java ...

  7. 2019前端面试系列——JS面试题

    判断 js 类型的方式 1. typeof 可以判断出'string','number','boolean','undefined','symbol' 但判断 typeof(null) 时值为 'ob ...

  8. 2019前端面试系列——Vue面试题

    Vue 双向绑定原理        mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter.getter,在数 ...

  9. 2019前端面试系列——JS高频手写代码题

    实现 new 方法 /* * 1.创建一个空对象 * 2.链接到原型 * 3.绑定this值 * 4.返回新对象 */ // 第一种实现 function createNew() { let obj ...

随机推荐

  1. c语言进阶9-值传递与地址传递

    一.  函数的值传递 函数的值传递是指参数为基本类型时,如整型.浮点型.字符型(特指单字符型)时,参数传递时是从实参拷贝一份值传给形参,形参的变化不会影响实参的值. 1.        基本类型做参数 ...

  2. C#7.1 新增功能

    连载目录    [已更新最新开发文章,点击查看详细] C# 7.1 是 C# 语言的第一个点版本(更新版本). 它标志着该语言发布节奏的加速. 理想情况下,可以在每个新功能准备就绪时更快推出新功能.  ...

  3. 6.2.初识Flutter应用之路由管理

    路由管理 路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewC ...

  4. ES6 symbol 以及symbol的简单应用

    前置 1.ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值. 2.Symbol 值通过Symbol函数生成. 3.Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实 ...

  5. Python -----函数(基础部分)

    函数: 1.定义: 函数是对功能的封装 2.语法: def 函数名 函数体 函数名 函数名的命名规则和变量一样 3.函数的返回值: return,函数执行完毕,不会执行后面的 1.如果函数中不写ret ...

  6. python调用WebService遇到的问题'Document' object has no attribute 'set'

    代码: from suds import WebFault from suds.client import Client url = 'http://******/bns/PtDataSvc.asmx ...

  7. Java IO部分面试题

    1.什么是比特(Bit),什么是字节(Byte),什么是字符(Char),它们长度是多少,各有什么区别 1. Bit最小的二进制单位 ,是计算机的操作部分 取值0或者1 2. Byte是计算机操作数据 ...

  8. Vue模板语法与常用指令

    Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据.在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数,结合相应系统,在应用状态改变时 ...

  9. [P2216] [HAOI2007]理想的正方形 「单调队列」

    思路:用单调队列分别维护行与列. 具体实现方法:是先用单调队列对每一行的值维护,并将a[][]每个区间的最大值,最小值分别存在X[][]和x[][]中. 那么X[][]与x[][]所存储的分别是1×n ...

  10. Selenium浏览器自动化测试框架

    selenium简介 介绍 Selenium [1]  是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 1 ...