You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2015/04/01 15:47:37 UTC
hbase git commit: HBASE-12954 Ability impaired using HBase on
multihomed hosts
Repository: hbase
Updated Branches:
refs/heads/branch-1 394b46093 -> 4df24b8e6
HBASE-12954 Ability impaired using HBase on multihomed hosts
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/4df24b8e
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/4df24b8e
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/4df24b8e
Branch: refs/heads/branch-1
Commit: 4df24b8e6dda59f71cbfc88ce7062a73329730de
Parents: 394b460
Author: tedyu <yu...@gmail.com>
Authored: Wed Apr 1 06:47:26 2015 -0700
Committer: tedyu <yu...@gmail.com>
Committed: Wed Apr 1 06:47:26 2015 -0700
----------------------------------------------------------------------
.../src/main/resources/hbase-default.xml | 7 +
.../generated/RegionServerStatusProtos.java | 300 ++++++++++++++++---
.../src/main/protobuf/RegionServerStatus.proto | 3 +
.../hadoop/hbase/master/MasterRpcServices.java | 5 +-
.../hadoop/hbase/master/ServerManager.java | 20 +-
.../hbase/regionserver/HRegionServer.java | 41 ++-
.../hbase/regionserver/RSRpcServices.java | 12 +-
.../hbase/master/TestClockSkewDetection.java | 32 +-
.../regionserver/TestRegionServerHostname.java | 103 +++++++
9 files changed, 455 insertions(+), 68 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-common/src/main/resources/hbase-default.xml
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/resources/hbase-default.xml b/hbase-common/src/main/resources/hbase-default.xml
index df1894b..db99f12 100644
--- a/hbase-common/src/main/resources/hbase-default.xml
+++ b/hbase-common/src/main/resources/hbase-default.xml
@@ -817,6 +817,13 @@ possible configurations would overwhelm and obscure the important.
<description>Set no delay on rpc socket connections. See
http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Socket.html#getTcpNoDelay()</description>
</property>
+ <property>
+ <name>hbase.regionserver.hostname</name>
+ <value></value>
+ <description>This config is for experts: don't set its value unless you really know what you are doing.
+ When set to a non-empty value, this represents the (external facing) hostname for the underlying server.
+ See https://issues.apache.org/jira/browse/HBASE-12954 for details.</description>
+ </property>
<!-- The following properties configure authentication information for
HBase processes when using Kerberos security. There are no default
values, included here for documentation purposes -->
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/RegionServerStatusProtos.java
----------------------------------------------------------------------
diff --git a/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/RegionServerStatusProtos.java b/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/RegionServerStatusProtos.java
index 1a4e1a5..a8cd58a 100644
--- a/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/RegionServerStatusProtos.java
+++ b/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/RegionServerStatusProtos.java
@@ -64,6 +64,33 @@ public final class RegionServerStatusProtos {
* </pre>
*/
long getServerCurrentTime();
+
+ // optional string use_this_hostname_instead = 4;
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ boolean hasUseThisHostnameInstead();
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ java.lang.String getUseThisHostnameInstead();
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ 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_;
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ public boolean hasUseThisHostnameInstead() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ 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;
+ }
+ }
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ 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_ = "";
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ public boolean hasUseThisHostnameInstead() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ 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;
+ }
+ }
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ 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;
+ }
+ }
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ public Builder setUseThisHostnameInstead(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000008;
+ useThisHostnameInstead_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ public Builder clearUseThisHostnameInstead() {
+ bitField0_ = (bitField0_ & ~0x00000008);
+ useThisHostnameInstead_ = getDefaultInstance().getUseThisHostnameInstead();
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string use_this_hostname_instead = 4;</code>
+ *
+ * <pre>
+ ** hostname for region server, optional
+ * </pre>
+ */
+ 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)
}
@@ -8891,48 +9104,49 @@ 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\"~\n GetLa" +
- "stFlushedSequenceIdResponse\022 \n\030last_flus" +
- "hed_sequence_id\030\001 \002(\004\0228\n\036store_last_flus" +
- "hed_sequence_id\030\002 \003(\0132\020.StoreSequenceId\"" +
- "\322\002\n\025RegionStateTransition\022>\n\017transition_" +
- "code\030\001 \002(\0162%.RegionStateTransition.Trans" +
- "itionCode\022 \n\013region_info\030\002 \003(\0132\013.RegionI" +
- "nfo\022\024\n\014open_seq_num\030\003 \001(\004\"\300\001\n\016Transition",
- "Code\022\n\n\006OPENED\020\000\022\017\n\013FAILED_OPEN\020\001\022\n\n\006CLO" +
- "SED\020\002\022\022\n\016READY_TO_SPLIT\020\003\022\022\n\016READY_TO_ME" +
- "RGE\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\"ReportRegionStat" +
- "eTransitionRequest\022\033\n\006server\030\001 \002(\0132\013.Ser" +
- "verName\022*\n\ntransition\030\002 \003(\0132\026.RegionStat" +
- "eTransition\"<\n#ReportRegionStateTransiti" +
- "onResponse\022\025\n\rerror_message\030\001 \001(\t2\326\003\n\031Re" +
- "gionServerStatusService\022P\n\023RegionServerS",
- "tartup\022\033.RegionServerStartupRequest\032\034.Re" +
- "gionServerStartupResponse\022M\n\022RegionServe" +
- "rReport\022\032.RegionServerReportRequest\032\033.Re" +
- "gionServerReportResponse\022M\n\022ReportRSFata" +
- "lError\022\032.ReportRSFatalErrorRequest\032\033.Rep" +
- "ortRSFatalErrorResponse\022_\n\030GetLastFlushe" +
- "dSequenceId\022 .GetLastFlushedSequenceIdRe" +
- "quest\032!.GetLastFlushedSequenceIdResponse" +
- "\022h\n\033ReportRegionStateTransition\022#.Report" +
- "RegionStateTransitionRequest\032$.ReportReg",
- "ionStateTransitionResponseBN\n*org.apache" +
- ".hadoop.hbase.protobuf.generatedB\030Region" +
- "ServerStatusProtosH\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\"~\n GetLastFl" +
+ "ushedSequenceIdResponse\022 \n\030last_flushed_" +
+ "sequence_id\030\001 \002(\004\0228\n\036store_last_flushed_" +
+ "sequence_id\030\002 \003(\0132\020.StoreSequenceId\"\322\002\n\025" +
+ "RegionStateTransition\022>\n\017transition_code" +
+ "\030\001 \002(\0162%.RegionStateTransition.Transitio" +
+ "nCode\022 \n\013region_info\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\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_PONR\020\005\022\016\n\nMERGE_PONR\020\006\022\t\n\005SPL" +
+ "IT\020\007\022\n\n\006MERGED\020\010\022\022\n\016SPLIT_REVERTED\020\t\022\022\n\016" +
+ "MERGE_REVERTED\020\n\"m\n\"ReportRegionStateTra" +
+ "nsitionRequest\022\033\n\006server\030\001 \002(\0132\013.ServerN" +
+ "ame\022*\n\ntransition\030\002 \003(\0132\026.RegionStateTra" +
+ "nsition\"<\n#ReportRegionStateTransitionRe" +
+ "sponse\022\025\n\rerror_message\030\001 \001(\t2\326\003\n\031Region",
+ "ServerStatusService\022P\n\023RegionServerStart" +
+ "up\022\033.RegionServerStartupRequest\032\034.Region" +
+ "ServerStartupResponse\022M\n\022RegionServerRep" +
+ "ort\022\032.RegionServerReportRequest\032\033.Region" +
+ "ServerReportResponse\022M\n\022ReportRSFatalErr" +
+ "or\022\032.ReportRSFatalErrorRequest\032\033.ReportR" +
+ "SFatalErrorResponse\022_\n\030GetLastFlushedSeq" +
+ "uenceId\022 .GetLastFlushedSequenceIdReques" +
+ "t\032!.GetLastFlushedSequenceIdResponse\022h\n\033" +
+ "ReportRegionStateTransition\022#.ReportRegi",
+ "onStateTransitionRequest\032$.ReportRegionS" +
+ "tateTransitionResponseBN\n*org.apache.had" +
+ "oop.hbase.protobuf.generatedB\030RegionServ" +
+ "erStatusProtosH\001\210\001\001\240\001\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -8944,7 +9158,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
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-protocol/src/main/protobuf/RegionServerStatus.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol/src/main/protobuf/RegionServerStatus.proto b/hbase-protocol/src/main/protobuf/RegionServerStatus.proto
index 855c2a1..33de501 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 {
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
----------------------------------------------------------------------
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 88ff74c..98f7507 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
@@ -301,8 +301,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();
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
----------------------------------------------------------------------
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 ab0bcdb..5c8bd34 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
@@ -63,6 +63,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.ClusterStatusProtos.RegionStoreSequenceIds;
import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos.StoreSequenceId;
import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.SplitLogTask.RecoveryMode;
@@ -241,16 +242,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.
@@ -258,8 +256,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"
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
----------------------------------------------------------------------
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 a091d23..af457ec 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
@@ -395,6 +395,16 @@ public class HRegionServer extends HasThread implements
*/
protected ServerName serverName;
+ /*
+ * hostname specified by hostname config
+ */
+ private 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.
*/
@@ -513,7 +523,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);
rpcControllerFactory = RpcControllerFactory.instantiate(this.conf);
@@ -577,6 +589,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);
@@ -627,7 +646,7 @@ public class HRegionServer extends HasThread implements
coprocessorServiceHandlers.put(serviceDesc.getFullName(), instance);
if (LOG.isDebugEnabled()) {
- LOG.debug("Registered regionserver coprocessor service: service=" + serviceDesc.getFullName());
+ LOG.debug("Registered regionserver coprocessor service: service="+serviceDesc.getFullName());
}
return true;
}
@@ -1274,9 +1293,18 @@ 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);
}
continue;
}
@@ -2168,6 +2196,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);
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
----------------------------------------------------------------------
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 bb446d1..9b47c75 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
@@ -826,9 +826,15 @@ public class RSRpcServices implements HBaseRPCErrorHandler,
}
public static String getHostname(Configuration conf) throws UnknownHostException {
- return Strings.domainNamePointerToHostName(DNS.getDefaultHost(
- conf.get("hbase.regionserver.dns.interface", "default"),
- conf.get("hbase.regionserver.dns.nameserver", "default")));
+ String hostname = conf.get(HRegionServer.HOSTNAME_KEY);
+ if (hostname == null || hostname.isEmpty()) {
+ return Strings.domainNamePointerToHostName(DNS.getDefaultHost(
+ 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) {
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClockSkewDetection.java
----------------------------------------------------------------------
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 d9ec036..963f36e 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.SmallTests;
import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
@@ -102,7 +103,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);
@@ -113,7 +118,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
@@ -125,7 +134,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
@@ -135,13 +148,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);
}
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/4df24b8e/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerHostname.java
----------------------------------------------------------------------
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..436bf02
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerHostname.java
@@ -0,0 +1,103 @@
+/**
+ * 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.util.Enumeration;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+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({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<NetworkInterface> netInterfaceList = NetworkInterface.getNetworkInterfaces();
+
+ while (netInterfaceList.hasMoreElements()) {
+ NetworkInterface ni = netInterfaceList.nextElement();
+ Enumeration<InetAddress> addrList = ni.getInetAddresses();
+ // iterate through host addresses and use each as hostname
+ while (addrList.hasMoreElements()) {
+ InetAddress addr = addrList.nextElement();
+ if (addr.isLoopbackAddress() || addr.isLinkLocalAddress() || addr.isMulticastAddress()
+ || !ni.getDisplayName().startsWith("e")) {
+ continue;
+ }
+ String hostName = addr.getHostName();
+ LOG.info("Found " + hostName + " on " + ni);
+
+ TEST_UTIL.getConfiguration().set(HRegionServer.HOSTNAME_KEY, hostName);
+ TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS);
+ try {
+ ZooKeeperWatcher zkw = TEST_UTIL.getZooKeeperWatcher();
+ List<String> servers = ZKUtil.listChildrenNoWatch(zkw, zkw.rsZNode);
+ while (servers == null) {
+ Threads.sleep(10);
+ }
+ assertTrue(servers.size() == NUM_RS);
+ for (String server : servers) {
+ assertTrue(server.startsWith(hostName+","));
+ }
+ zkw.close();
+ } finally {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+ }
+ }
+ }
+}