全栈工程师开发手册 (作者:栾鹏)
架构系列文章


HBase的RegionServer会将自己的hostname上报到zookeeper,客户端连接zookeeper时,获取的是regionserver的hostname,再由hostname获得regionserver的ip地址。基于hbase的这种名称上报机制,客户端连接hbase时,需要能够ping通hbase的hostname,但是如果把hbase的hostname分发到所有的服务器上,毕竟是不现实的。一种可选择的方法,就是以hbase的hostname作为域名配置到DNS,这样客户端服务器也能够通过ping hostname获取服务器的实际ip。是不是这样就够了?所有服务器的/etc/hosts都不用再做更改了吗?本文就是基于上面的背景介绍一个使用HBase过程中可能会遇到一个大深坑。而这也是hbase的一个bug。

我们创造这样一个场景:

在master节点的/etc/hosts中去掉regionserverA(假设其ip地址为10.0.0.1)的hostname,而在regionserverA本地的/etc/hosts中保留了它的hostname,然后重启该regionserver,随后可以发现在master的web页面上,该regionserver上报的名称为其ip地址,也就是10.0.0.1。而在zookeeper的rs路径下,我们看到zookeeper所登记的regionserver名字是regionserverA。这就是说该节点在zk和master的视角有不同的名字,在zookeeper上它是自己的hostname,而在master看来,它报过去的是自己的ip。

针对上述情况,集群有什么风险。我们继续试验,把10.0.0.1节点上的regionserver停掉。此时登录zookeeper可以看到对应的zookeeper节点已经被删掉,但是master认为这个zk节点所代表的regionserver不属于自己,master自己看到的是10.0.0.1而不是regionserverA,所以master不会去处理这台regionserver的shutdown。也就不会针对这台regionserver上的region做rebalance,造成该regionserver上的region实际不可用。

原因分析:

Regionserver的名字会在两处被加载到HMaster中,HMaster包含一个成员变量RegionServerTracker,这个Tracker继承了ZookeeperListener接口,用于当zookeeper上rs节点下的子节点发生变化时,通知master去处理这些子节点(包括删除/新增regionserver)。

RegionServer启动时,首先以自己的servername为名在zookeeper上创建一个临时节点。servername是由如下几个部分构成:

String hostName = shouldUseThisHostnameInstead()?useThisHostnameInstead : rpcServices.isa.getHostName();serverName = ServerName.valueOf(hostname, rpcServer.isa.getPort(), startcode);

Regionserver启动时通过InetSocketAddress获得了本地的hostanme,以hostname作为servername的一部分写到zookeeper上。

regionserver启动之后会向master汇报自身已经startup,通过调用reportForDuty(),将regionserver的名字和当前regionserver上的load汇报给master,master如何接收这些汇报信息的代码比较关键,我们把master上的处理代码列出在下面:

ServerName regionServerStartup(RegionServerStartupRequest request, InetAddress ia) throws IOException {final String hostname = request.hasUseThisHostnameInstead() ?request.getUseThisHostnameInstead() :ia.getHostName(); ServerName sn = ServerName.valueOf(hostname, request.getPort(), request.getServerStartCode());checkClockSkew(sn, request.getServerCurrentTime());checkIsDead(sn, "STARTUP");if (!checkAndRecordNewServer(sn, ServerLoad.EMPTY_SERVERLOAD)) {LOG.warn("THIS SHOULD NOT HAPPEN, RegionServerStartup" + " could not record the server: " + sn);}return sn;
}

Master调用本地的InetAddress去获取hostname,如果regionserver的hostname没有写到master的/etc/hosts,那么在master看来,regionserver的ServerName就是ip:port:startcode,而不是hostname:port:startcode。master节点上regionServerStartup函数将返回的servername直接写到zookeeper上。

如上造成master所看到的regionserver名字与其regionserver进程自身注册到zookeeper上的不一致。这带来的风险就是当regionserver挂掉时,regionserver写到zookeeper上rs路径下的临时节点会自动删掉,master是通过RegionserverTracker去监听rs路径下节点变化的

@Override
public void nodeDeleted(String path) {if (path.startsWith(watcher.rsZNode)) {String serverName = ZKUtil.getNodeName(path);LOG.info("RegionServer ephemeral node deleted, processing expiration [" + serverName + "]");ServerName sn = ServerName.parseServerName(serverName); if (!serverManager.isServerOnline(sn)) {LOG.warn(serverName.toString() + " is not online or isn't known to the master."+ "The latter could be caused by a DNS misconfiguration.");return; }remove(sn);this.serverManager.expireServer(sn); }
}

master处理regionserver临时节点消失的代码如上所示,其会调用serverManager的expireServer处理消失servername所对应的regionserver,在expireServer中会发起一个ServerCrashProcedure,Procedure是HBase中实现了2PC的分布式执行框架,有协调者和参与者两种角色,两种角色分别运行在HMaster和HRegionServer上,关于procedure的实现细节不是本文的重点,这里只需理解ServerCrashProcedure中master将dead regionserver上的region分配给其它的live regionserver,由这些live regionserver继续对外提供服务。

需要注意的的是serverManager.isServerOnline(sn)这句代码,如果zookeeper上获得的servername不在master所认为的onlineServers里面,那么根据这里的判断函数就会直接短路返回。也就不会执行到后续的expireServer,这台挂掉regionserver上的region也就不会被处理。

而当我们修改了hosts,并重启了regionserver之后,这台regionserver会以新的hostname注册上来,master看到一台新的regionserver,会开始region balance,这时master可能就会去那台旧的以ip注册的regionserver上去close region,但是实际上这台regionserver已经shutdown了,master已经连不上这台服务器,所以master试图去close这台机器上的region时会报failed close错误。

处理措施:

重启master节点,由备master接管之后,问题消失。

切换master之后,所有regionserver重新汇报自己的region,这时master会发现哪些region不在线,进而去分配这些region,重新让它们上线。

总结与反思:

RIT问题可以分两大类,一类是由于hdfs上的文件错误导致,比如写入了格式不准确的文件、文件的.regioninfo丢失或者瞬间大量小文件造成compact阻塞,一般此类问题深层次原因是由于硬盘故障或者服务器的突然断电造成。解决方式需要删除引起错误的文件。

还有一类是由于master上的信息与zookeeper或者hdfs上持久化的不一致,导致master出现错误的行为,比如去close已经不在线regionserver上的region,此类问题的解决需要切换master,此时regionserver会重新上报自己的信息,master可以在这时更新自己的roadmap,修正错误。

HBase因hostname可能引起的RIT问题。HBASE的ip和hostname坑相关推荐

  1. hbase 0.96 java api_HBase(九) HBase JAVA API - 运维API

    运维API 监控集群状态 Configuration conf = HBaseConfiguration.create(); HBaseAdmin admin = new HBaseAdmin(con ...

  2. 云HBase小组成功抢救某公司自建HBase集群,挽救30+T数据

    摘要: 使用过开源HBase的人都知道,运维HBase是多么复杂的事情,集群大的时候,读写压力大,配置稍微不合理一点,就可能会出现集群状态不一致的情况,糟糕一点的直接导致入库.查询某个业务表不可用, ...

  3. 转载:云HBase小组成功抢救某公司自建HBase集群,挽救30+T数据

    概述 使用过开源HBase的人都知道,运维HBase是多么复杂的事情,集群大的时候,读写压力大,配置稍微不合理一点,就可能会出现集群状态不一致的情况,糟糕一点的直接导致入库.查询某个业务表不可用, 甚 ...

  4. find ip from hostname or find hostname from ip

    1. find ip from hostname ping <hostname> 2.fin hostname from ip nslookup <ip>

  5. /opt/hbase/conf 中不能启动hbase_浅谈Hbase在用户画像上的应用

    背景 公司要做C端的用户画像,方便运营人员根据标签做用户圈选,然后对这部分人群做精准广告投放,所以需要线上接口实时调用库中数据,并快速返回结果,并将结果反馈到推送平台进行推送. 目前公司的方案是全部走 ...

  6. HBase出现java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/HBaseConfiguration问题

    问题:Hbase在集群上运行报错:NoClassDefFoundError:org/apache/hadoop/hbase/HBaseConfiguration 需求:HBase使用Java创建表,打 ...

  7. java导出hbase表数据_通用MapReduce程序复制HBase表数据

    编写MR程序,让其可以适合大部分的HBase表数据导入到HBase表数据.其中包括可以设置版本数.可以设置输入表的列导入设置(选取其中某几列).可以设置输出表的列导出设置(选取其中某几列). 原始表t ...

  8. hostname -I(大写i)显示主机IP

    hostname -I (大写i)显示主机IP

  9. sqoop将hbase数据导入mysql_Sqoop将mysql数据导入hbase的血与泪

    Sqoop将mysql数据导入hbase的血与泪(整整搞了大半天) 版权声明:本文为yunshuxueyuan原创文章. 如需转载请标明出处: https://my.oschina.net/yunsh ...

  10. HBase详解(对hbase集群搭建、读写流程、hbase的javaApi等细致入微的讲解与保姆级的图解)

    学HBase的意义是什么 我本想用MySQL来与HBase作比较,但发现他们两者毫无可比性,因为两者运用领域不同,各自有各自的优点,就好比爬山穿登山鞋,潜水穿脚蹼一般. 一门技术的兴起,一个优秀的开源 ...

最新文章

  1. Ubuntu虚拟机JeOS安装-2016.08.28
  2. oracle字段求和_oracle大纲
  3. Extension project - Component.js of standard application could not be loaded
  4. linux7安装EMC的多路径,Oracle Linux 7.8 多路径(Multipath)+Udev绑定磁盘
  5. 关于HTML的面试题-html5/css3篇
  6. APP时间界面设计模板,可临摹学习的好素材
  7. RabbitMQ实现中AMQP与MQTT消息收发异同
  8. 领域驱动设计的个人理解
  9. 小米球外网映射本地tomcat
  10. SPSS方差分析应该如何进行
  11. 窗体 dialog 弹出时动画效果
  12. 网络——局域网和广域网
  13. 解决invalid operands of types ‘float‘ and ‘int‘ to binary ‘operator %
  14. 浅谈solrCloud的分布式设计
  15. 为什么自建 UI 框架?
  16. 新思科技网络安全研究中心分析手机中的生物识别数据泄露漏洞
  17. 如何画Flot折线图
  18. excel表格怎么筛选出空白的单元格
  19. 数人云|PaaS Innovation 2017开幕在即,共襄技术演进与商业碰撞盛宴
  20. STM32WB55无限固件库升级文档说明和脚本文件升级程序免输入命令

热门文章

  1. python编程是啥-Python编程
  2. 离线语音识别技术品鉴——功能不同各有千秋
  3. 解决浏览器中点击input输入框时,placeholder的值不消失的方法
  4. JavaScript-面向对象(构造函数,实例成员,静态成员)
  5. 蓝桥c++2013真题:逆波兰表达式(代码填空题)
  6. 【数据结构和算法笔记】KMP算法介绍
  7. SDL2源代码分析2:窗口(SDL_Window)
  8. ES Filebeat 使用 Pipeline 处理日志中的 @timestamp
  9. jpg灰度化 python_python开发之HighGUI上位机开发(一)
  10. 四年级学生计算机学情分析报告,四年级学情分析