HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程
在《HDFS源码分析心跳汇报之数据结构初始化》一文中,我们了解到HDFS心跳相关的BlockPoolManager、BPOfferService、BPServiceActor三者之间的关系,并且知道最终HDFS的心跳是通过BPServiceActor线程实现的。那么,这个BPServiceActor线程到底是如何工作的呢?本文,我们将继续HDFS心跳分析之BPServiceActor工作线程运行流程。
首先,我们先看下
那么,BPServiceActor线程是通过什么样的流程来实现心跳的呢?我们来看下它正常工作的run()方法,代码如下:
- /**
- * No matter what kind of exception we get, keep retrying to offerService().
- * That's the loop that connects to the NameNode and provides basic DataNode
- * functionality.
- *
- * Only stop when "shouldRun" or "shouldServiceRun" is turned off, which can
- * happen either at shutdown or due to refreshNamenodes.
- */
- @Override
- public void run() {
- // 记录日志信息:starting to offer service
- LOG.info(this + " starting to offer service");
- try {
- // 在一个while循环内,完成连接NameNode并握手操作,即初始化
- while (true) {
- // init stuff
- try {
- // setup storage
- // 连接NameNode并握手
- connectToNNAndHandshake();
- break;
- } catch (IOException ioe) {
- // 如果存在异常
- // Initial handshake, storage recovery or registration failed
- // 现将运行状态runningState设置为初始化失败INIT_FAILED
- runningState = RunningState.INIT_FAILED;
- // 调用shouldRetryInit()方法判断初始化失败时是否可以重试
- if (shouldRetryInit()) {
- // Retry until all namenode's of BPOS failed initialization
- // 记录error日志信息
- LOG.error("Initialization failed for " + this + " "
- + ioe.getLocalizedMessage());
- // 线程休眠5s,并记录info日志信息,之后再进入循环重复执行之前的操作
- sleepAndLogInterrupts(5000, "initializing");
- } else {
- // 不允许重试的情况下,将运行状态runningState设置为失败FAILED,退出循环,并返回
- runningState = RunningState.FAILED;
- LOG.fatal("Initialization failed for " + this + ". Exiting. ", ioe);
- return;
- }
- }
- }
- // 设置运行状态runningState为正在运行RUNNING
- runningState = RunningState.RUNNING;
- // 进入另一个while循环,不停的调用offerService()方法,
- // 发送心跳给NameNode并接收来自NameNode,然后根据命令交给不同的组件去处理
- // 循环的条件就是该线程的标志位shouldServiceRun为true,且dataNode的shouldRun()返回true
- while (shouldRun()) {
- try {
- offerService();
- } catch (Exception ex) {
- // 存在异常的话,记录error日志,并休眠5s
- LOG.error("Exception in BPOfferService for " + this, ex);
- sleepAndLogInterrupts(5000, "offering service");
- }
- }
- // 设置运行状态runningState为已退出EXITED
- runningState = RunningState.EXITED;
- } catch (Throwable ex) {
- LOG.warn("Unexpected exception in block pool " + this, ex);
- runningState = RunningState.FAILED;
- } finally {
- LOG.warn("Ending block pool service for: " + this);
- // 清空,释放占用的资源
- cleanUp();
- }
- }
在run()方法的开始,也就是BPServiceActor线程刚启动时,会在一个while循环内,完成连接NameNode并握手操作,即初始化。这里,是通过调用connectToNNAndHandshake()方法完成与NameNode的连接并进行两次握手的。值得一提的是,如果出现了IOException异常,会先将运行状态runningState设置为初始化失败INIT_FAILED,然后调用shouldRetryInit()方法判断初始化失败时是否可以重试:
1、如果可以重试的话,记录error日志信息,线程休眠5s,并记录info日志信息,之后再进入循环重复执行之前的操作;
2、不允许重试的情况下,将运行状态runningState设置为失败FAILED,退出循环,并返回。
接下来,设置运行状态runningState为正在运行RUNNING,进入另一个while循环,不停的调用offerService()方法,发送心跳给NameNode并接收来自NameNode的命令,然后根据命令交给不同的组件去处理,循环的条件就是该线程的标志位shouldServiceRun为true,且dataNode的shouldRun()返回true;
而当循环过程中存在异常Exception的话,记录error日志,并休眠5s,然后继续循环,只有当shouldRun()方法返回false,才退出循环,设置运行状态runningState为已退出EXITED,最终调用cleanUp()方法释放占用的资源等。
上述就是BPServiceActor线程正常工作进行周期性心跳的主流程。下面,我们针对其中的某些细节进行详细描述。
首先,完成与NameNode的连接并进行两次握手的connectToNNAndHandshake()方法,实现如下:
- /**
- * 连接NameNode并握手
- */
- private void connectToNNAndHandshake() throws IOException {
- // get NN proxy
- // 利用DataNode实例dn的connectToNN()方法和NameNode地址nnAddr获得NameNode的代理bpNamenode
- bpNamenode = dn.connectToNN(nnAddr);
- // First phase of the handshake with NN - get the namespace
- // info.
- // 与NameNode握手第一阶段:获取命名空间信息
- NamespaceInfo nsInfo = retrieveNamespaceInfo();
- // Verify that this matches the other NN in this HA pair.
- // This also initializes our block pool in the DN if we are
- // the first NN connection for this BP.
- // 验证,并设置命名空间信息()
- bpos.verifyAndSetNamespaceInfo(nsInfo);
- // Second phase of the handshake with the NN.
- // 与NameNode握手第二阶段,注册
- register();
- }
它的主要处理流程如下:
1、利用DataNode实例dn的connectToNN()方法和NameNode地址nnAddr获得NameNode的代理bpNamenode
2、与NameNode握手第一阶段:调用retrieveNamespaceInfo()方法获取命名空间信息nsInfo;
3、通过bpos的verifyAndSetNamespaceInfo()方法进行验证,并设置命名空间信息nsInfo;
4、与NameNode握手第二阶段,调用register()方法进行注册。
接着,我们再看下实现周期性心跳的offerService()方法,代码如下:
HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程的更多相关文章
- HDFS源码分析心跳汇报之数据块增量汇报
在<HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程>一文中,我们详细了解了数据节点DataNode周期性发送心跳给名字节点NameNode的BPServiceAct ...
- HDFS源码分析心跳汇报之数据块汇报
在<HDFS源码分析心跳汇报之数据块增量汇报>一文中,我们详细介绍了数据块增量汇报的内容,了解到它是时间间隔更长的正常数据块汇报周期内一个smaller的数据块汇报,它负责将DataNod ...
- HDFS源码分析心跳汇报之数据结构初始化
在<HDFS源码分析心跳汇报之整体结构>一文中,我们详细了解了HDFS中关于心跳的整体结构,知道了BlockPoolManager.BPOfferService和BPServiceActo ...
- HDFS源码分析心跳汇报之周期性心跳
HDFS源码分析心跳汇报之周期性心跳,近期推出!
- HDFS源码分析心跳汇报之DataNode注册
HDFS源码分析心跳汇报之DataNode注册,近期推出!
- HDFS源码分析心跳汇报之整体结构
我们知道,HDFS全称是Hadoop Distribute FileSystem,即Hadoop分布式文件系统.既然它是一个分布式文件系统,那么肯定存在很多物理节点,而这其中,就会有主从节点之分.在H ...
- HDFS源码分析数据块汇报之损坏数据块检测checkReplicaCorrupt()
无论是第一次,还是之后的每次数据块汇报,名字名字节点都会对汇报上来的数据块进行检测,看看其是否为损坏的数据块.那么,损坏数据块是如何被检测的呢?本文,我们将研究下损坏数据块检测的checkReplic ...
- HDFS源码分析数据块校验之DataBlockScanner
DataBlockScanner是运行在数据节点DataNode上的一个后台线程.它为所有的块池管理块扫描.针对每个块池,一个BlockPoolSliceScanner对象将会被创建,其运行在一个单独 ...
- HDFS源码分析数据块复制监控线程ReplicationMonitor(一)
ReplicationMonitor是HDFS中关于数据块复制的监控线程,它的主要作用就是计算DataNode工作,并将复制请求超时的块重新加入到待调度队列.其定义及作为线程核心的run()方法如下: ...
随机推荐
- 添加一种emit的应用,反射发出,较直接调用稍慢,但好过反射与表达式树。
System.Reflection.MethodInfo mInfo = typeof(TypeParse).GetMethod("Add", System.Reflection. ...
- 补不manjaro系统
昨天无意间看到:使用不同的主题时,使用midna图标时,关机的按钮和其他的不同,经过摸索,只需要更改替换3个图标即可: (1)进入目录/usr/share/icons/breeze/actions/t ...
- python 锁 多进程
参考: http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html http://linhs.blog.51cto.com/370259/1 ...
- window golang1.12.4 安装配置&IDE vscode
step 1:下载golang golang官网地址是 https://golang.org/dl/ 如果没有墙的话,可以用这个地址 https://golang.google.cn/dl/ 如图: ...
- [Python Debug] How to install external python package? MAC系统下的xgboost安装
从昨天晚上开始安装xgboost,经历了各种稀奇古怪的错误,终于现在程序可以跑起来了.整个过程对python编译环境,路径设置,package安装方法有了一定了解,当然还有一些疑惑,所以姑且做个记录. ...
- Cygwin下vi和vim方向键和Backspace不好用的问题(转)
执行p4 client时vi打开文本,编辑起来恼火,于是找到了这个: 默认的vi(vim)没有配置文件,因此导致了方向键出现ABCD,以及Backspace只会移动光标,字符不消失的问题.cygwin ...
- weblogic的集群与配置图文方法
一.Weblogic的集群 还记得我们在第五天教程中讲到的关于Tomcat的集群吗? 两个tomcat做node即tomcat1, tomcat2,使用Apache HttpServer做请求派发 ...
- iOS 在Xcode中使用OpenSSL库
最近要做一个密码键盘,想内置一些加密算法,所以就想到了添加OpenSSL库,现在mac也自带了OpenSSL库,但是每次都从终端是生成是很麻烦的.网上找了很多文档.博客去介绍如何编译可以在Xcode中 ...
- mac 查看文件编码及转换文件编码
方法是用vim , vim 打开相应文件, :set fileencoding即可显示文件编码格式 将文件编码转换为utf-8 :set fileencoding=utf-8
- Linux学习之十六-Linux用户管理
Linux用户管理 Linux系统跟Windows系统一样,可以创建不同的用户,不同的用户组.在不同用户下使用系统具有相应的权限 创建一个普通用户时,会修改几个文件,拷贝一些初始文件到用户家目录中 修 ...