在最近的一个项目中有这样一个需求,咱们的业务数据是存放在hbase中,一天大概新增五到六百万的,而后我这边须要作一件事是按小时把新增数据加载到impala中,而且数据须要按年月日三个字段分区。
java
起初想到的是直接在hive中创建一个表,而后在表上创建一个mapping映射到hbase中的表。可是考虑到分区,业务表中没法提供这些字段,因此另想它法。数据库
后来想到的是用hbase中提供的TableMapper按时间截扫描(这里不用rowkey缘由能够本身思考,时间截会出现的问题,业务那边已经处理),mapreduce任务定时每隔一小时执行一次,每次记录下扫描到的数据的最大和最小时间截。下次依据这个扫描最新数据,而后经过reduce把数据写到hdfs上,最后load到impala上。服务器
按照上面的思路敲完代码测试的时候,在log中发现一个error,以下图app
经过源码找到报错的地方dom
InetAddress regionAddress = isa.getAddress(); String regionLocation; try { regionLocation = reverseDNS(regionAddress); } catch (NamingException e) { LOG.warn("Cannot resolve the host name for " + regionAddress + " because of " + e); regionLocation = location.getHostname(); }
抛出异常的方法reverseDNS测试
private String reverseDNS(InetAddress ipAddress) throws NamingException { String hostName = this.reverseDNSCacheMap.get(ipAddress); if (hostName == null) { hostName = Strings.domainNamePointerToHostName(DNS.reverseDns(ipAddress, this.nameServer)); this.reverseDNSCacheMap.put(ipAddress, hostName); } return hostName; }
可见hostName的获取是与nameServer有关this
this.nameServer = context.getConfiguration().get("hbase.nameserver.address", null);
而nameServer是从配置(hbase-site.xml)中读取的,hbase.nameserver.address从字面上看是名字服务器的地址,也就是域名服务器。spa
try { regionLocation = reverseDNS(regionAddress); } catch (NamingException e) { LOG.warn("Cannot resolve the host name for " + regionAddress + " because of " + e); regionLocation = location.getHostname(); }
在分析这里,首先根据region所在的regionserver的ip地址去域名服务器中找这个regionserver的主机名,而咱们搭建本地集群通常不会去弄个域名服务器什么的,这里固然会找不到,而后才会去hosts文件获取regionserver的主机名。总之这里仍是获取到了regionserver的主机名,没有获取到想要的主机域名,不影响mapreduce的执行。code
只有在线上集群,咱们可能会申请一个域名,而后为每一个节点 的ip映射一个二级域名,而后在hbase-site.xml中配置上hbase.nameserver.address的值为一个域名服务器的ip(好比114.114.114.114)。server
因此不想看到这个error:一、能够本身在一个节点上搭建一个域名服务器,而后再域名服务器的数据库中按hosts的配置添加映射;二、修改源码注释这行代码,覆盖到集群中