diff --git a/hbase-common/src/main/resources/hbase-default.xml b/hbase-common/src/main/resources/hbase-default.xml
index e412b8f..fa8700d 100644
--- a/hbase-common/src/main/resources/hbase-default.xml
+++ b/hbase-common/src/main/resources/hbase-default.xml
@@ -906,6 +906,13 @@ possible configurations would overwhelm and obscure the important.
optional string use_this_hostname_instead = 4;
+ *
+ *
+ ** hostname for region server, optional + *+ */ + boolean hasUseThisHostnameInstead(); + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + java.lang.String getUseThisHostnameInstead(); + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + com.google.protobuf.ByteString + getUseThisHostnameInsteadBytes(); } /** * Protobuf type {@code RegionServerStartupRequest} @@ -131,6 +158,11 @@ public final class RegionServerStatusProtos { serverCurrentTime_ = input.readUInt64(); break; } + case 34: { + bitField0_ |= 0x00000008; + useThisHostnameInstead_ = input.readBytes(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -243,10 +275,66 @@ public final class RegionServerStatusProtos { return serverCurrentTime_; } + // optional string use_this_hostname_instead = 4; + public static final int USE_THIS_HOSTNAME_INSTEAD_FIELD_NUMBER = 4; + private java.lang.Object useThisHostnameInstead_; + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public boolean hasUseThisHostnameInstead() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public java.lang.String getUseThisHostnameInstead() { + java.lang.Object ref = useThisHostnameInstead_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + useThisHostnameInstead_ = s; + } + return s; + } + } + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public com.google.protobuf.ByteString + getUseThisHostnameInsteadBytes() { + java.lang.Object ref = useThisHostnameInstead_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + useThisHostnameInstead_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + private void initFields() { port_ = 0; serverStartCode_ = 0L; serverCurrentTime_ = 0L; + useThisHostnameInstead_ = ""; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -281,6 +369,9 @@ public final class RegionServerStatusProtos { if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeUInt64(3, serverCurrentTime_); } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, getUseThisHostnameInsteadBytes()); + } getUnknownFields().writeTo(output); } @@ -302,6 +393,10 @@ public final class RegionServerStatusProtos { size += com.google.protobuf.CodedOutputStream .computeUInt64Size(3, serverCurrentTime_); } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getUseThisHostnameInsteadBytes()); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -340,6 +435,11 @@ public final class RegionServerStatusProtos { result = result && (getServerCurrentTime() == other.getServerCurrentTime()); } + result = result && (hasUseThisHostnameInstead() == other.hasUseThisHostnameInstead()); + if (hasUseThisHostnameInstead()) { + result = result && getUseThisHostnameInstead() + .equals(other.getUseThisHostnameInstead()); + } result = result && getUnknownFields().equals(other.getUnknownFields()); return result; @@ -365,6 +465,10 @@ public final class RegionServerStatusProtos { hash = (37 * hash) + SERVER_CURRENT_TIME_FIELD_NUMBER; hash = (53 * hash) + hashLong(getServerCurrentTime()); } + if (hasUseThisHostnameInstead()) { + hash = (37 * hash) + USE_THIS_HOSTNAME_INSTEAD_FIELD_NUMBER; + hash = (53 * hash) + getUseThisHostnameInstead().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -480,6 +584,8 @@ public final class RegionServerStatusProtos { bitField0_ = (bitField0_ & ~0x00000002); serverCurrentTime_ = 0L; bitField0_ = (bitField0_ & ~0x00000004); + useThisHostnameInstead_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); return this; } @@ -520,6 +626,10 @@ public final class RegionServerStatusProtos { to_bitField0_ |= 0x00000004; } result.serverCurrentTime_ = serverCurrentTime_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.useThisHostnameInstead_ = useThisHostnameInstead_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -545,6 +655,11 @@ public final class RegionServerStatusProtos { if (other.hasServerCurrentTime()) { setServerCurrentTime(other.getServerCurrentTime()); } + if (other.hasUseThisHostnameInstead()) { + bitField0_ |= 0x00000008; + useThisHostnameInstead_ = other.useThisHostnameInstead_; + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -731,6 +846,104 @@ public final class RegionServerStatusProtos { return this; } + // optional string use_this_hostname_instead = 4; + private java.lang.Object useThisHostnameInstead_ = ""; + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public boolean hasUseThisHostnameInstead() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public java.lang.String getUseThisHostnameInstead() { + java.lang.Object ref = useThisHostnameInstead_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + useThisHostnameInstead_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public com.google.protobuf.ByteString + getUseThisHostnameInsteadBytes() { + java.lang.Object ref = useThisHostnameInstead_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + useThisHostnameInstead_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public Builder setUseThisHostnameInstead( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + useThisHostnameInstead_ = value; + onChanged(); + return this; + } + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public Builder clearUseThisHostnameInstead() { + bitField0_ = (bitField0_ & ~0x00000008); + useThisHostnameInstead_ = getDefaultInstance().getUseThisHostnameInstead(); + onChanged(); + return this; + } + /** + *
optional string use_this_hostname_instead = 4;
+ *
+ * + ** hostname for region server, optional + *+ */ + public Builder setUseThisHostnameInsteadBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + useThisHostnameInstead_ = value; + onChanged(); + return this; + } + // @@protoc_insertion_point(builder_scope:RegionServerStartupRequest) } @@ -8399,47 +8612,48 @@ public final class RegionServerStatusProtos { static { java.lang.String[] descriptorData = { "\n\030RegionServerStatus.proto\032\013HBase.proto\032" + - "\023ClusterStatus.proto\"b\n\032RegionServerStar" + - "tupRequest\022\014\n\004port\030\001 \002(\r\022\031\n\021server_start" + - "_code\030\002 \002(\004\022\033\n\023server_current_time\030\003 \002(\004" + - "\"C\n\033RegionServerStartupResponse\022$\n\013map_e" + - "ntries\030\001 \003(\0132\017.NameStringPair\"S\n\031RegionS" + - "erverReportRequest\022\033\n\006server\030\001 \002(\0132\013.Ser" + - "verName\022\031\n\004load\030\002 \001(\0132\013.ServerLoad\"\034\n\032Re" + - "gionServerReportResponse\"O\n\031ReportRSFata" + - "lErrorRequest\022\033\n\006server\030\001 \002(\0132\013.ServerNa", - "me\022\025\n\rerror_message\030\002 \002(\t\"\034\n\032ReportRSFat" + - "alErrorResponse\"6\n\037GetLastFlushedSequenc" + - "eIdRequest\022\023\n\013region_name\030\001 \002(\014\"D\n GetLa" + - "stFlushedSequenceIdResponse\022 \n\030last_flus" + - "hed_sequence_id\030\001 \002(\004\"\322\002\n\025RegionStateTra" + - "nsition\022>\n\017transition_code\030\001 \002(\0162%.Regio" + - "nStateTransition.TransitionCode\022 \n\013regio" + - "n_info\030\002 \003(\0132\013.RegionInfo\022\024\n\014open_seq_nu" + - "m\030\003 \001(\004\"\300\001\n\016TransitionCode\022\n\n\006OPENED\020\000\022\017" + - "\n\013FAILED_OPEN\020\001\022\n\n\006CLOSED\020\002\022\022\n\016READY_TO_", - "SPLIT\020\003\022\022\n\016READY_TO_MERGE\020\004\022\016\n\nSPLIT_PON" + - "R\020\005\022\016\n\nMERGE_PONR\020\006\022\t\n\005SPLIT\020\007\022\n\n\006MERGED" + - "\020\010\022\022\n\016SPLIT_REVERTED\020\t\022\022\n\016MERGE_REVERTED" + - "\020\n\"m\n\"ReportRegionStateTransitionRequest" + - "\022\033\n\006server\030\001 \002(\0132\013.ServerName\022*\n\ntransit" + - "ion\030\002 \003(\0132\026.RegionStateTransition\"<\n#Rep" + - "ortRegionStateTransitionResponse\022\025\n\rerro" + - "r_message\030\001 \001(\t2\326\003\n\031RegionServerStatusSe" + - "rvice\022P\n\023RegionServerStartup\022\033.RegionSer" + - "verStartupRequest\032\034.RegionServerStartupR", - "esponse\022M\n\022RegionServerReport\022\032.RegionSe" + - "rverReportRequest\032\033.RegionServerReportRe" + - "sponse\022M\n\022ReportRSFatalError\022\032.ReportRSF" + - "atalErrorRequest\032\033.ReportRSFatalErrorRes" + - "ponse\022_\n\030GetLastFlushedSequenceId\022 .GetL" + - "astFlushedSequenceIdRequest\032!.GetLastFlu" + - "shedSequenceIdResponse\022h\n\033ReportRegionSt" + - "ateTransition\022#.ReportRegionStateTransit" + - "ionRequest\032$.ReportRegionStateTransition" + - "ResponseBN\n*org.apache.hadoop.hbase.prot", - "obuf.generatedB\030RegionServerStatusProtos" + - "H\001\210\001\001\240\001\001" + "\023ClusterStatus.proto\"\205\001\n\032RegionServerSta" + + "rtupRequest\022\014\n\004port\030\001 \002(\r\022\031\n\021server_star" + + "t_code\030\002 \002(\004\022\033\n\023server_current_time\030\003 \002(" + + "\004\022!\n\031use_this_hostname_instead\030\004 \001(\t\"C\n\033" + + "RegionServerStartupResponse\022$\n\013map_entri" + + "es\030\001 \003(\0132\017.NameStringPair\"S\n\031RegionServe" + + "rReportRequest\022\033\n\006server\030\001 \002(\0132\013.ServerN" + + "ame\022\031\n\004load\030\002 \001(\0132\013.ServerLoad\"\034\n\032Region" + + "ServerReportResponse\"O\n\031ReportRSFatalErr", + "orRequest\022\033\n\006server\030\001 \002(\0132\013.ServerName\022\025" + + "\n\rerror_message\030\002 \002(\t\"\034\n\032ReportRSFatalEr" + + "rorResponse\"6\n\037GetLastFlushedSequenceIdR" + + "equest\022\023\n\013region_name\030\001 \002(\014\"D\n GetLastFl" + + "ushedSequenceIdResponse\022 \n\030last_flushed_" + + "sequence_id\030\001 \002(\004\"\322\002\n\025RegionStateTransit" + + "ion\022>\n\017transition_code\030\001 \002(\0162%.RegionSta" + + "teTransition.TransitionCode\022 \n\013region_in" + + "fo\030\002 \003(\0132\013.RegionInfo\022\024\n\014open_seq_num\030\003 " + + "\001(\004\"\300\001\n\016TransitionCode\022\n\n\006OPENED\020\000\022\017\n\013FA", + "ILED_OPEN\020\001\022\n\n\006CLOSED\020\002\022\022\n\016READY_TO_SPLI" + + "T\020\003\022\022\n\016READY_TO_MERGE\020\004\022\016\n\nSPLIT_PONR\020\005\022" + + "\016\n\nMERGE_PONR\020\006\022\t\n\005SPLIT\020\007\022\n\n\006MERGED\020\010\022\022" + + "\n\016SPLIT_REVERTED\020\t\022\022\n\016MERGE_REVERTED\020\n\"m" + + "\n\"ReportRegionStateTransitionRequest\022\033\n\006" + + "server\030\001 \002(\0132\013.ServerName\022*\n\ntransition\030" + + "\002 \003(\0132\026.RegionStateTransition\"<\n#ReportR" + + "egionStateTransitionResponse\022\025\n\rerror_me" + + "ssage\030\001 \001(\t2\326\003\n\031RegionServerStatusServic" + + "e\022P\n\023RegionServerStartup\022\033.RegionServerS", + "tartupRequest\032\034.RegionServerStartupRespo" + + "nse\022M\n\022RegionServerReport\022\032.RegionServer" + + "ReportRequest\032\033.RegionServerReportRespon" + + "se\022M\n\022ReportRSFatalError\022\032.ReportRSFatal" + + "ErrorRequest\032\033.ReportRSFatalErrorRespons" + + "e\022_\n\030GetLastFlushedSequenceId\022 .GetLastF" + + "lushedSequenceIdRequest\032!.GetLastFlushed" + + "SequenceIdResponse\022h\n\033ReportRegionStateT" + + "ransition\022#.ReportRegionStateTransitionR" + + "equest\032$.ReportRegionStateTransitionResp", + "onseBN\n*org.apache.hadoop.hbase.protobuf" + + ".generatedB\030RegionServerStatusProtosH\001\210\001" + + "\001\240\001\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -8451,7 +8665,7 @@ public final class RegionServerStatusProtos { internal_static_RegionServerStartupRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_RegionServerStartupRequest_descriptor, - new java.lang.String[] { "Port", "ServerStartCode", "ServerCurrentTime", }); + new java.lang.String[] { "Port", "ServerStartCode", "ServerCurrentTime", "UseThisHostnameInstead", }); internal_static_RegionServerStartupResponse_descriptor = getDescriptor().getMessageTypes().get(1); internal_static_RegionServerStartupResponse_fieldAccessorTable = new diff --git a/hbase-protocol/src/main/protobuf/RegionServerStatus.proto b/hbase-protocol/src/main/protobuf/RegionServerStatus.proto index 75e5ae4..d6f7b35 100644 --- a/hbase-protocol/src/main/protobuf/RegionServerStatus.proto +++ b/hbase-protocol/src/main/protobuf/RegionServerStatus.proto @@ -36,6 +36,9 @@ message RegionServerStartupRequest { /** Current time of the region server in ms */ required uint64 server_current_time = 3; + + /** hostname for region server, optional */ + optional string use_this_hostname_instead = 4; } message RegionServerStartupResponse { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java index 0e81461..7128a3a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java @@ -302,8 +302,9 @@ public class MasterRpcServices extends RSRpcServices master.checkServiceStarted(); InetAddress ia = master.getRemoteInetAddress( request.getPort(), request.getServerStartCode()); - ServerName rs = master.serverManager.regionServerStartup(ia, request.getPort(), - request.getServerStartCode(), request.getServerCurrentTime()); + // if regionserver passed hostname to use, + // then use it instead of doing a reverse DNS lookup + ServerName rs = master.serverManager.regionServerStartup(request, ia); // Send back some config info RegionServerStartupResponse.Builder resp = createConfigurationSubset(); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java index 69c29fd..119202e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java @@ -59,6 +59,7 @@ import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.AdminService; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionResponse; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ServerInfo; +import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest; import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.SplitLogTask.RecoveryMode; import org.apache.hadoop.hbase.regionserver.HRegionServer; import org.apache.hadoop.hbase.regionserver.RegionOpeningState; @@ -229,16 +230,13 @@ public class ServerManager { /** * Let the server manager know a new regionserver has come online - * @param ia The remote address - * @param port The remote port - * @param serverStartcode - * @param serverCurrentTime The current time of the region server in ms + * @param request the startup request + * @param ia the InetAddress from which request is received * @return The ServerName we know this server as. * @throws IOException */ - ServerName regionServerStartup(final InetAddress ia, final int port, - final long serverStartcode, long serverCurrentTime) - throws IOException { + ServerName regionServerStartup(RegionServerStartupRequest request, InetAddress ia) + throws IOException { // Test for case where we get a region startup message from a regionserver // that has been quickly restarted but whose znode expiration handler has // not yet run, or from a server whose fail we are currently processing. @@ -246,8 +244,12 @@ public class ServerManager { // is, reject the server and trigger its expiration. The next time it comes // in, it should have been removed from serverAddressToServerInfo and queued // for processing by ProcessServerShutdown. - ServerName sn = ServerName.valueOf(ia.getHostName(), port, serverStartcode); - checkClockSkew(sn, serverCurrentTime); + + 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" diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java index fcb8c6f..4dea0c8 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java @@ -389,6 +389,16 @@ public class HRegionServer extends HasThread implements */ protected ServerName serverName; + /* + * hostname obtained from InetSocketAddress or, specified by hostname config + */ + protected String useThisHostnameInstead; + + // key to the config parameter of server hostname + // the specification of server hostname is optional. The hostname should be resolvable from + // both master and region server + final static String HOSTNAME_KEY = "hbase.regionserver.hostname"; + /** * This servers startcode. */ @@ -502,7 +512,9 @@ public class HRegionServer extends HasThread implements rpcServices = createRpcServices(); this.startcode = System.currentTimeMillis(); - String hostName = rpcServices.isa.getHostName(); + useThisHostnameInstead = conf.get(HOSTNAME_KEY); + String hostName = shouldUseThisHostnameInstead() ? useThisHostnameInstead : + rpcServices.isa.getHostName(); serverName = ServerName.valueOf(hostName, rpcServices.isa.getPort(), startcode); // login the zookeeper client principal (if using security) @@ -561,6 +573,13 @@ public class HRegionServer extends HasThread implements this.choreService = new ChoreService(getServerName().toString()); } + /* + * Returns true if configured hostname should be used + */ + protected boolean shouldUseThisHostnameInstead() { + return useThisHostnameInstead != null && !useThisHostnameInstead.isEmpty(); + } + protected void login(UserProvider user, String host) throws IOException { user.login("hbase.regionserver.keytab.file", "hbase.regionserver.kerberos.principal", host); @@ -1254,9 +1273,19 @@ public class HRegionServer extends HasThread implements String hostnameFromMasterPOV = e.getValue(); this.serverName = ServerName.valueOf(hostnameFromMasterPOV, rpcServices.isa.getPort(), this.startcode); - if (!hostnameFromMasterPOV.equals(rpcServices.isa.getHostName())) { - LOG.info("Master passed us a different hostname to use; was=" + - rpcServices.isa.getHostName() + ", but now=" + hostnameFromMasterPOV); + if (shouldUseThisHostnameInstead() && + !hostnameFromMasterPOV.equals(useThisHostnameInstead)) { + String msg = "Master passed us a different hostname to use; was=" + + this.useThisHostnameInstead + ", but now=" + hostnameFromMasterPOV; + LOG.error(msg); + throw new IOException(msg); + } + if (!shouldUseThisHostnameInstead() && + !hostnameFromMasterPOV.equals(rpcServices.isa.getHostName())) { + String msg = "Master passed us a different hostname to use; was=" + + rpcServices.isa.getHostName() + ", but now=" + hostnameFromMasterPOV; + LOG.error(msg); + throw new IOException(msg); } continue; } @@ -2137,6 +2166,9 @@ public class HRegionServer extends HasThread implements long now = EnvironmentEdgeManager.currentTime(); int port = rpcServices.isa.getPort(); RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder(); + if (shouldUseThisHostnameInstead()) { + request.setUseThisHostnameInstead(useThisHostnameInstead); + } request.setPort(port); request.setServerStartCode(this.startcode); request.setServerCurrentTime(now); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java index 3bdb528..8592b0b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java @@ -806,10 +806,16 @@ public class RSRpcServices implements HBaseRPCErrorHandler, } public static String getHostname(Configuration conf) throws UnknownHostException { - return conf.get("hbase.regionserver.ipc.address", + String hostname = conf.get(HRegionServer.HOSTNAME_KEY); + if (hostname == null || hostname.isEmpty()) { + return conf.get("hbase.regionserver.ipc.address", Strings.domainNamePointerToHostName(DNS.getDefaultHost( - conf.get("hbase.regionserver.dns.interface", "default"), - conf.get("hbase.regionserver.dns.nameserver", "default")))); + conf.get("hbase.regionserver.dns.interface", "default"), + conf.get("hbase.regionserver.dns.nameserver", "default")))); + } else { + LOG.info("hostname is configured to be " + hostname); + return hostname; + } } RegionScanner getScanner(long scannerId) { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClockSkewDetection.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClockSkewDetection.java index dd733ad..a19d5d8 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClockSkewDetection.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClockSkewDetection.java @@ -32,6 +32,7 @@ import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.Server; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.client.ClusterConnection; +import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest; import org.apache.hadoop.hbase.testclassification.MasterTests; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.zookeeper.MetaTableLocator; @@ -103,7 +104,11 @@ public class TestClockSkewDetection { LOG.debug("regionServerStartup 1"); InetAddress ia1 = InetAddress.getLocalHost(); - sm.regionServerStartup(ia1, 1234, -1, System.currentTimeMillis()); + RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder(); + request.setPort(1234); + request.setServerStartCode(-1); + request.setServerCurrentTime(System.currentTimeMillis()); + sm.regionServerStartup(request.build(), ia1); final Configuration c = HBaseConfiguration.create(); long maxSkew = c.getLong("hbase.master.maxclockskew", 30000); @@ -114,7 +119,11 @@ public class TestClockSkewDetection { LOG.debug("Test: Master Time > Region Server Time"); LOG.debug("regionServerStartup 2"); InetAddress ia2 = InetAddress.getLocalHost(); - sm.regionServerStartup(ia2, 1235, -1, System.currentTimeMillis() - maxSkew * 2); + request = RegionServerStartupRequest.newBuilder(); + request.setPort(1235); + request.setServerStartCode(-1); + request.setServerCurrentTime(System.currentTimeMillis() - maxSkew * 2); + sm.regionServerStartup(request.build(), ia2); fail("HMaster should have thrown a ClockOutOfSyncException but didn't."); } catch(ClockOutOfSyncException e) { //we want an exception @@ -126,7 +135,11 @@ public class TestClockSkewDetection { LOG.debug("Test: Master Time < Region Server Time"); LOG.debug("regionServerStartup 3"); InetAddress ia3 = InetAddress.getLocalHost(); - sm.regionServerStartup(ia3, 1236, -1, System.currentTimeMillis() + maxSkew * 2); + request = RegionServerStartupRequest.newBuilder(); + request.setPort(1236); + request.setServerStartCode(-1); + request.setServerCurrentTime(System.currentTimeMillis() + maxSkew * 2); + sm.regionServerStartup(request.build(), ia3); fail("HMaster should have thrown a ClockOutOfSyncException but didn't."); } catch (ClockOutOfSyncException e) { // we want an exception @@ -136,12 +149,20 @@ public class TestClockSkewDetection { // make sure values above warning threshold but below max threshold don't kill LOG.debug("regionServerStartup 4"); InetAddress ia4 = InetAddress.getLocalHost(); - sm.regionServerStartup(ia4, 1237, -1, System.currentTimeMillis() - warningSkew * 2); + request = RegionServerStartupRequest.newBuilder(); + request.setPort(1237); + request.setServerStartCode(-1); + request.setServerCurrentTime(System.currentTimeMillis() - warningSkew * 2); + sm.regionServerStartup(request.build(), ia4); // make sure values above warning threshold but below max threshold don't kill LOG.debug("regionServerStartup 5"); InetAddress ia5 = InetAddress.getLocalHost(); - sm.regionServerStartup(ia5, 1238, -1, System.currentTimeMillis() + warningSkew * 2); + request = RegionServerStartupRequest.newBuilder(); + request.setPort(1238); + request.setServerStartCode(-1); + request.setServerCurrentTime(System.currentTimeMillis() + warningSkew * 2); + sm.regionServerStartup(request.build(), ia5); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerHostname.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerHostname.java new file mode 100644 index 0000000..f07b793 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerHostname.java @@ -0,0 +1,108 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.regionserver; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.CoordinatedStateManager; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.MiniHBaseCluster.MiniHBaseClusterRegionServer; +import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.RegionServerStartupResponse; +import org.apache.hadoop.hbase.testclassification.MediumTests; +import org.apache.hadoop.hbase.testclassification.RegionServerTests; +import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; +import org.apache.hadoop.hbase.util.Threads; +import org.apache.hadoop.hbase.zookeeper.ZKUtil; +import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Tests for the hostname specification by region server + */ +@Category({RegionServerTests.class, MediumTests.class}) +public class TestRegionServerHostname { + private static final Log LOG = LogFactory.getLog(TestRegionServerHostname.class); + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + + @Test (timeout=30000) + public void testInvalidRegionServerHostnameAbortsServer() throws Exception { + final int NUM_MASTERS = 1; + final int NUM_RS = 1; + String invalidHostname = "hostAddr"; + TEST_UTIL.getConfiguration().set(HRegionServer.HOSTNAME_KEY, invalidHostname); + try { + TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS); + } catch (IOException ioe) { + Throwable t1 = ioe.getCause(); + Throwable t2 = t1.getCause(); + assertTrue(t2.getMessage().contains("Failed resolve of " + invalidHostname)); + return; + } finally { + TEST_UTIL.shutdownMiniCluster(); + } + assertTrue("Failed to validate against invalid hostname", false); + } + + @Test(timeout=120000) + public void testRegionServerHostname() throws Exception { + final int NUM_MASTERS = 1; + final int NUM_RS = 1; + Enumeration