001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import static org.apache.hadoop.hbase.ChoreService.CHORE_SERVICE_INITIAL_POOL_SIZE; 021import static org.apache.hadoop.hbase.ChoreService.DEFAULT_CHORE_SERVICE_INITIAL_POOL_SIZE; 022import static org.apache.hadoop.hbase.HConstants.DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK; 023import static org.apache.hadoop.hbase.HConstants.HBASE_SPLIT_WAL_COORDINATED_BY_ZK; 024 025import com.google.errorprone.annotations.RestrictedApi; 026import io.opentelemetry.api.trace.Span; 027import io.opentelemetry.api.trace.StatusCode; 028import io.opentelemetry.context.Scope; 029import java.io.IOException; 030import java.lang.management.MemoryType; 031import java.net.BindException; 032import java.net.InetAddress; 033import java.net.InetSocketAddress; 034import java.util.concurrent.atomic.AtomicBoolean; 035import javax.servlet.http.HttpServlet; 036import org.apache.commons.lang3.StringUtils; 037import org.apache.commons.lang3.SystemUtils; 038import org.apache.hadoop.conf.Configuration; 039import org.apache.hadoop.fs.FileSystem; 040import org.apache.hadoop.fs.Path; 041import org.apache.hadoop.hbase.client.AsyncClusterConnection; 042import org.apache.hadoop.hbase.client.ClusterConnectionFactory; 043import org.apache.hadoop.hbase.client.Connection; 044import org.apache.hadoop.hbase.client.ConnectionFactory; 045import org.apache.hadoop.hbase.client.ConnectionRegistryEndpoint; 046import org.apache.hadoop.hbase.conf.ConfigurationManager; 047import org.apache.hadoop.hbase.conf.ConfigurationObserver; 048import org.apache.hadoop.hbase.coordination.ZkCoordinatedStateManager; 049import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; 050import org.apache.hadoop.hbase.executor.ExecutorService; 051import org.apache.hadoop.hbase.fs.HFileSystem; 052import org.apache.hadoop.hbase.http.InfoServer; 053import org.apache.hadoop.hbase.io.util.MemorySizeUtil; 054import org.apache.hadoop.hbase.ipc.RpcServerInterface; 055import org.apache.hadoop.hbase.master.HMaster; 056import org.apache.hadoop.hbase.master.MasterCoprocessorHost; 057import org.apache.hadoop.hbase.namequeues.NamedQueueRecorder; 058import org.apache.hadoop.hbase.regionserver.ChunkCreator; 059import org.apache.hadoop.hbase.regionserver.HeapMemoryManager; 060import org.apache.hadoop.hbase.regionserver.MemStoreLAB; 061import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost; 062import org.apache.hadoop.hbase.regionserver.ShutdownHook; 063import org.apache.hadoop.hbase.security.Superusers; 064import org.apache.hadoop.hbase.security.User; 065import org.apache.hadoop.hbase.security.UserProvider; 066import org.apache.hadoop.hbase.security.access.AccessChecker; 067import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher; 068import org.apache.hadoop.hbase.trace.TraceUtil; 069import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent; 070import org.apache.hadoop.hbase.util.Addressing; 071import org.apache.hadoop.hbase.util.CommonFSUtils; 072import org.apache.hadoop.hbase.util.DNS; 073import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 074import org.apache.hadoop.hbase.util.FSTableDescriptors; 075import org.apache.hadoop.hbase.util.NettyEventLoopGroupConfig; 076import org.apache.hadoop.hbase.util.Pair; 077import org.apache.hadoop.hbase.util.Sleeper; 078import org.apache.hadoop.hbase.zookeeper.ClusterStatusTracker; 079import org.apache.hadoop.hbase.zookeeper.ZKAuthentication; 080import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 081import org.apache.yetus.audience.InterfaceAudience; 082import org.slf4j.Logger; 083import org.slf4j.LoggerFactory; 084 085/** 086 * Base class for hbase services, such as master or region server. 087 */ 088@InterfaceAudience.Private 089public abstract class HBaseServerBase<R extends HBaseRpcServicesBase<?>> extends Thread 090 implements Server, ConfigurationObserver, ConnectionRegistryEndpoint { 091 092 private static final Logger LOG = LoggerFactory.getLogger(HBaseServerBase.class); 093 094 protected final Configuration conf; 095 096 // Go down hard. Used if file system becomes unavailable and also in 097 // debugging and unit tests. 098 protected final AtomicBoolean abortRequested = new AtomicBoolean(false); 099 100 // Set when a report to the master comes back with a message asking us to 101 // shutdown. Also set by call to stop when debugging or running unit tests 102 // of HRegionServer in isolation. 103 protected volatile boolean stopped = false; 104 105 // Only for testing 106 private boolean isShutdownHookInstalled = false; 107 108 /** 109 * This servers startcode. 110 */ 111 protected final long startcode; 112 113 protected final UserProvider userProvider; 114 115 // zookeeper connection and watcher 116 protected final ZKWatcher zooKeeper; 117 118 /** 119 * The server name the Master sees us as. Its made from the hostname the master passes us, port, 120 * and server startcode. Gets set after registration against Master. 121 */ 122 protected ServerName serverName; 123 124 protected final R rpcServices; 125 126 /** 127 * hostname specified by hostname config 128 */ 129 protected final String useThisHostnameInstead; 130 131 /** 132 * Provide online slow log responses from ringbuffer 133 */ 134 protected final NamedQueueRecorder namedQueueRecorder; 135 136 /** 137 * Configuration manager is used to register/deregister and notify the configuration observers 138 * when the regionserver is notified that there was a change in the on disk configs. 139 */ 140 protected final ConfigurationManager configurationManager; 141 142 /** 143 * ChoreService used to schedule tasks that we want to run periodically 144 */ 145 protected final ChoreService choreService; 146 147 // Instance of the hbase executor executorService. 148 protected final ExecutorService executorService; 149 150 // Cluster Status Tracker 151 protected final ClusterStatusTracker clusterStatusTracker; 152 153 protected final CoordinatedStateManager csm; 154 155 // Info server. Default access so can be used by unit tests. REGIONSERVER 156 // is name of the webapp and the attribute name used stuffing this instance 157 // into web context. 158 protected InfoServer infoServer; 159 160 protected HFileSystem dataFs; 161 162 protected HFileSystem walFs; 163 164 protected Path dataRootDir; 165 166 protected Path walRootDir; 167 168 protected final int msgInterval; 169 170 // A sleeper that sleeps for msgInterval. 171 protected final Sleeper sleeper; 172 173 /** 174 * Go here to get table descriptors. 175 */ 176 protected TableDescriptors tableDescriptors; 177 178 /** 179 * The asynchronous cluster connection to be shared by services. 180 */ 181 protected AsyncClusterConnection asyncClusterConnection; 182 183 /** 184 * Cache for the meta region replica's locations. Also tracks their changes to avoid stale cache 185 * entries. Used for serving ClientMetaService. 186 */ 187 protected final MetaRegionLocationCache metaRegionLocationCache; 188 189 protected final NettyEventLoopGroupConfig eventLoopGroupConfig; 190 191 private void setupSignalHandlers() { 192 if (!SystemUtils.IS_OS_WINDOWS) { 193 HBasePlatformDependent.handle("HUP", (number, name) -> { 194 try { 195 updateConfiguration(); 196 } catch (IOException e) { 197 LOG.error("Problem while reloading configuration", e); 198 } 199 }); 200 } 201 } 202 203 /** 204 * Setup our cluster connection if not already initialized. 205 */ 206 protected final synchronized void setupClusterConnection() throws IOException { 207 if (asyncClusterConnection == null) { 208 InetSocketAddress localAddress = 209 new InetSocketAddress(rpcServices.getSocketAddress().getAddress(), 0); 210 User user = userProvider.getCurrent(); 211 asyncClusterConnection = 212 ClusterConnectionFactory.createAsyncClusterConnection(this, conf, localAddress, user); 213 } 214 } 215 216 protected final void initializeFileSystem() throws IOException { 217 // Get fs instance used by this RS. Do we use checksum verification in the hbase? If hbase 218 // checksum verification enabled, then automatically switch off hdfs checksum verification. 219 boolean useHBaseChecksum = conf.getBoolean(HConstants.HBASE_CHECKSUM_VERIFICATION, true); 220 String walDirUri = CommonFSUtils.getDirUri(this.conf, 221 new Path(conf.get(CommonFSUtils.HBASE_WAL_DIR, conf.get(HConstants.HBASE_DIR)))); 222 // set WAL's uri 223 if (walDirUri != null) { 224 CommonFSUtils.setFsDefault(this.conf, walDirUri); 225 } 226 // init the WALFs 227 this.walFs = new HFileSystem(this.conf, useHBaseChecksum); 228 this.walRootDir = CommonFSUtils.getWALRootDir(this.conf); 229 // Set 'fs.defaultFS' to match the filesystem on hbase.rootdir else 230 // underlying hadoop hdfs accessors will be going against wrong filesystem 231 // (unless all is set to defaults). 232 String rootDirUri = 233 CommonFSUtils.getDirUri(this.conf, new Path(conf.get(HConstants.HBASE_DIR))); 234 if (rootDirUri != null) { 235 CommonFSUtils.setFsDefault(this.conf, rootDirUri); 236 } 237 // init the filesystem 238 this.dataFs = new HFileSystem(this.conf, useHBaseChecksum); 239 this.dataRootDir = CommonFSUtils.getRootDir(this.conf); 240 int tableDescriptorParallelLoadThreads = 241 conf.getInt("hbase.tabledescriptor.parallel.load.threads", 0); 242 this.tableDescriptors = new FSTableDescriptors(this.dataFs, this.dataRootDir, 243 !canUpdateTableDescriptor(), cacheTableDescriptor(), tableDescriptorParallelLoadThreads); 244 } 245 246 public HBaseServerBase(Configuration conf, String name) throws IOException { 247 super(name); // thread name 248 final Span span = TraceUtil.createSpan("HBaseServerBase.cxtor"); 249 try (Scope ignored = span.makeCurrent()) { 250 this.conf = conf; 251 this.eventLoopGroupConfig = 252 NettyEventLoopGroupConfig.setup(conf, getClass().getSimpleName() + "-EventLoopGroup"); 253 this.startcode = EnvironmentEdgeManager.currentTime(); 254 this.userProvider = UserProvider.instantiate(conf); 255 this.msgInterval = conf.getInt("hbase.regionserver.msginterval", 3 * 1000); 256 this.sleeper = new Sleeper(this.msgInterval, this); 257 this.namedQueueRecorder = createNamedQueueRecord(); 258 useThisHostnameInstead = getUseThisHostnameInstead(conf); 259 // Resolve the hostname up-front and log in before creating the RpcServer. The RpcServer 260 // constructor reads UserGroupInformation.getCurrentUser() (HBASE-28321); if the server 261 // has not logged in yet, UGI bootstraps from the ticket cache and spawns a TGT renewer 262 // for whichever principal happens to be there. 263 String hostName = resolveHostName(conf, useThisHostnameInstead); 264 // login the zookeeper client principal (if using security) 265 ZKAuthentication.loginClient(this.conf, HConstants.ZK_CLIENT_KEYTAB_FILE, 266 HConstants.ZK_CLIENT_KERBEROS_PRINCIPAL, hostName); 267 // login the server principal (if using secure Hadoop) 268 login(userProvider, hostName); 269 this.rpcServices = createRpcServices(); 270 InetSocketAddress addr = rpcServices.getSocketAddress(); 271 serverName = ServerName.valueOf(hostName, addr.getPort(), this.startcode); 272 // init superusers and add the server principal (if using security) 273 // or process owner as default super user. 274 Superusers.initialize(conf); 275 zooKeeper = 276 new ZKWatcher(conf, getProcessName() + ":" + addr.getPort(), this, canCreateBaseZNode()); 277 278 this.configurationManager = new ConfigurationManager(); 279 setupSignalHandlers(); 280 281 initializeFileSystem(); 282 283 int choreServiceInitialSize = 284 conf.getInt(CHORE_SERVICE_INITIAL_POOL_SIZE, DEFAULT_CHORE_SERVICE_INITIAL_POOL_SIZE); 285 this.choreService = new ChoreService(getName(), choreServiceInitialSize, true); 286 this.executorService = new ExecutorService(getName()); 287 288 this.metaRegionLocationCache = new MetaRegionLocationCache(zooKeeper); 289 290 if (clusterMode()) { 291 if ( 292 conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK) 293 ) { 294 csm = new ZkCoordinatedStateManager(this); 295 } else { 296 csm = null; 297 } 298 clusterStatusTracker = new ClusterStatusTracker(zooKeeper, this); 299 clusterStatusTracker.start(); 300 } else { 301 csm = null; 302 clusterStatusTracker = null; 303 } 304 putUpWebUI(); 305 span.setStatus(StatusCode.OK); 306 } catch (Throwable t) { 307 TraceUtil.setError(span, t); 308 throw t; 309 } finally { 310 span.end(); 311 } 312 } 313 314 /** 315 * Puts up the webui. 316 */ 317 private void putUpWebUI() throws IOException { 318 int port = 319 this.conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT); 320 String addr = this.conf.get("hbase.regionserver.info.bindAddress", "0.0.0.0"); 321 322 boolean isMaster = false; 323 if (this instanceof HMaster) { 324 port = conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT); 325 addr = this.conf.get("hbase.master.info.bindAddress", "0.0.0.0"); 326 isMaster = true; 327 } 328 // -1 is for disabling info server 329 if (port < 0) { 330 return; 331 } 332 333 if (!Addressing.isLocalAddress(InetAddress.getByName(addr))) { 334 String msg = "Failed to start http info server. Address " + addr 335 + " does not belong to this host. Correct configuration parameter: " 336 + (isMaster ? "hbase.master.info.bindAddress" : "hbase.regionserver.info.bindAddress"); 337 LOG.error(msg); 338 throw new IOException(msg); 339 } 340 // check if auto port bind enabled 341 boolean auto = this.conf.getBoolean(HConstants.REGIONSERVER_INFO_PORT_AUTO, false); 342 while (true) { 343 try { 344 this.infoServer = new InfoServer(getProcessName(), addr, port, false, this.conf); 345 infoServer.addPrivilegedServlet("dump", "/dump", getDumpServlet()); 346 configureInfoServer(infoServer); 347 this.infoServer.start(); 348 break; 349 } catch (BindException e) { 350 if (!auto) { 351 // auto bind disabled throw BindException 352 LOG.error("Failed binding http info server to port: " + port); 353 throw e; 354 } 355 // auto bind enabled, try to use another port 356 LOG.info("Failed binding http info server to port: " + port); 357 port++; 358 LOG.info("Retry starting http info server with port: " + port); 359 } 360 } 361 port = this.infoServer.getPort(); 362 conf.setInt(HConstants.REGIONSERVER_INFO_PORT, port); 363 int masterInfoPort = 364 conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT); 365 conf.setInt("hbase.master.info.port.orig", masterInfoPort); 366 conf.setInt(HConstants.MASTER_INFO_PORT, port); 367 } 368 369 /** 370 * Sets the abort state if not already set. 371 * @return True if abortRequested set to True successfully, false if an abort is already in 372 * progress. 373 */ 374 protected final boolean setAbortRequested() { 375 return abortRequested.compareAndSet(false, true); 376 } 377 378 @Override 379 public boolean isStopped() { 380 return stopped; 381 } 382 383 @Override 384 public boolean isAborted() { 385 return abortRequested.get(); 386 } 387 388 @Override 389 public Configuration getConfiguration() { 390 return conf; 391 } 392 393 @Override 394 public AsyncClusterConnection getAsyncClusterConnection() { 395 return asyncClusterConnection; 396 } 397 398 @Override 399 public ZKWatcher getZooKeeper() { 400 return zooKeeper; 401 } 402 403 protected final void shutdownChore(ScheduledChore chore) { 404 if (chore != null) { 405 chore.shutdown(); 406 } 407 } 408 409 protected final void initializeMemStoreChunkCreator(HeapMemoryManager hMemManager) { 410 if (MemStoreLAB.isEnabled(conf)) { 411 // MSLAB is enabled. So initialize MemStoreChunkPool 412 // By this time, the MemstoreFlusher is already initialized. We can get the global limits from 413 // it. 414 Pair<Long, MemoryType> pair = MemorySizeUtil.getGlobalMemStoreSize(conf); 415 long globalMemStoreSize = pair.getFirst(); 416 boolean offheap = pair.getSecond() == MemoryType.NON_HEAP; 417 // When off heap memstore in use, take full area for chunk pool. 418 float poolSizePercentage = offheap 419 ? 1.0F 420 : conf.getFloat(MemStoreLAB.CHUNK_POOL_MAXSIZE_KEY, MemStoreLAB.POOL_MAX_SIZE_DEFAULT); 421 float initialCountPercentage = conf.getFloat(MemStoreLAB.CHUNK_POOL_INITIALSIZE_KEY, 422 MemStoreLAB.POOL_INITIAL_SIZE_DEFAULT); 423 int chunkSize = conf.getInt(MemStoreLAB.CHUNK_SIZE_KEY, MemStoreLAB.CHUNK_SIZE_DEFAULT); 424 float indexChunkSizePercent = conf.getFloat(MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_KEY, 425 MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT); 426 // init the chunkCreator 427 ChunkCreator.initialize(chunkSize, offheap, globalMemStoreSize, poolSizePercentage, 428 initialCountPercentage, hMemManager, indexChunkSizePercent); 429 } 430 } 431 432 protected abstract void stopChores(); 433 434 protected final void stopChoreService() { 435 // clean up the scheduled chores 436 if (choreService != null) { 437 LOG.info("Shutdown chores and chore service"); 438 stopChores(); 439 // cancel the remaining scheduled chores (in case we missed out any) 440 // TODO: cancel will not cleanup the chores, so we need make sure we do not miss any 441 choreService.shutdown(); 442 } 443 } 444 445 protected final void stopExecutorService() { 446 if (executorService != null) { 447 LOG.info("Shutdown executor service"); 448 executorService.shutdown(); 449 } 450 } 451 452 protected final void closeClusterConnection() { 453 if (asyncClusterConnection != null) { 454 LOG.info("Close async cluster connection"); 455 try { 456 this.asyncClusterConnection.close(); 457 } catch (IOException e) { 458 // Although the {@link Closeable} interface throws an {@link 459 // IOException}, in reality, the implementation would never do that. 460 LOG.warn("Attempt to close server's AsyncClusterConnection failed.", e); 461 } 462 } 463 } 464 465 protected final void stopInfoServer() { 466 if (this.infoServer != null) { 467 LOG.info("Stop info server"); 468 try { 469 this.infoServer.stop(); 470 } catch (Exception e) { 471 LOG.error("Failed to stop infoServer", e); 472 } 473 } 474 } 475 476 protected final void closeZooKeeper() { 477 if (this.zooKeeper != null) { 478 LOG.info("Close zookeeper"); 479 this.zooKeeper.close(); 480 } 481 } 482 483 protected final void closeTableDescriptors() { 484 if (this.tableDescriptors != null) { 485 LOG.info("Close table descriptors"); 486 try { 487 this.tableDescriptors.close(); 488 } catch (IOException e) { 489 LOG.debug("Failed to close table descriptors gracefully", e); 490 } 491 } 492 } 493 494 /** 495 * In order to register ShutdownHook, this method is called when HMaster and HRegionServer are 496 * started. For details, please refer to HBASE-26951 497 */ 498 protected final void installShutdownHook() { 499 ShutdownHook.install(conf, dataFs, this, Thread.currentThread()); 500 isShutdownHookInstalled = true; 501 } 502 503 @RestrictedApi(explanation = "Should only be called in tests", link = "", 504 allowedOnPath = ".*/src/test/.*") 505 public boolean isShutdownHookInstalled() { 506 return isShutdownHookInstalled; 507 } 508 509 @Override 510 public ServerName getServerName() { 511 return serverName; 512 } 513 514 @Override 515 public ChoreService getChoreService() { 516 return choreService; 517 } 518 519 /** Returns Return table descriptors implementation. */ 520 public TableDescriptors getTableDescriptors() { 521 return this.tableDescriptors; 522 } 523 524 public ExecutorService getExecutorService() { 525 return executorService; 526 } 527 528 public AccessChecker getAccessChecker() { 529 return rpcServices.getAccessChecker(); 530 } 531 532 public ZKPermissionWatcher getZKPermissionWatcher() { 533 return rpcServices.getZkPermissionWatcher(); 534 } 535 536 @Override 537 public CoordinatedStateManager getCoordinatedStateManager() { 538 return csm; 539 } 540 541 @Override 542 public Connection createConnection(Configuration conf) throws IOException { 543 User user = UserProvider.instantiate(conf).getCurrent(); 544 return ConnectionFactory.createConnection(conf, null, user); 545 } 546 547 /** Returns Return the rootDir. */ 548 public Path getDataRootDir() { 549 return dataRootDir; 550 } 551 552 @Override 553 public FileSystem getFileSystem() { 554 return dataFs; 555 } 556 557 /** Returns Return the walRootDir. */ 558 public Path getWALRootDir() { 559 return walRootDir; 560 } 561 562 /** Returns Return the walFs. */ 563 public FileSystem getWALFileSystem() { 564 return walFs; 565 } 566 567 /** Returns True if the cluster is up. */ 568 public boolean isClusterUp() { 569 return !clusterMode() || this.clusterStatusTracker.isClusterUp(); 570 } 571 572 /** Returns time stamp in millis of when this server was started */ 573 public long getStartcode() { 574 return this.startcode; 575 } 576 577 public InfoServer getInfoServer() { 578 return infoServer; 579 } 580 581 public int getMsgInterval() { 582 return msgInterval; 583 } 584 585 /** 586 * get NamedQueue Provider to add different logs to ringbuffer 587 */ 588 public NamedQueueRecorder getNamedQueueRecorder() { 589 return this.namedQueueRecorder; 590 } 591 592 public RpcServerInterface getRpcServer() { 593 return rpcServices.getRpcServer(); 594 } 595 596 public NettyEventLoopGroupConfig getEventLoopGroupConfig() { 597 return eventLoopGroupConfig; 598 } 599 600 public R getRpcServices() { 601 return rpcServices; 602 } 603 604 @RestrictedApi(explanation = "Should only be called in tests", link = "", 605 allowedOnPath = ".*/src/test/.*") 606 public MetaRegionLocationCache getMetaRegionLocationCache() { 607 return this.metaRegionLocationCache; 608 } 609 610 @RestrictedApi(explanation = "Should only be called in tests", link = "", 611 allowedOnPath = ".*/src/test/.*") 612 public ConfigurationManager getConfigurationManager() { 613 return configurationManager; 614 } 615 616 /** 617 * Reload the configuration from disk. 618 */ 619 public void updateConfiguration() throws IOException { 620 LOG.info("Reloading the configuration from disk."); 621 // Reload the configuration from disk. 622 preUpdateConfiguration(); 623 conf.reloadConfiguration(); 624 configurationManager.notifyAllObservers(conf); 625 postUpdateConfiguration(); 626 } 627 628 private void preUpdateConfiguration() throws IOException { 629 CoprocessorHost<?, ?> coprocessorHost = getCoprocessorHost(); 630 if (coprocessorHost instanceof RegionServerCoprocessorHost) { 631 ((RegionServerCoprocessorHost) coprocessorHost).preUpdateConfiguration(conf); 632 } else if (coprocessorHost instanceof MasterCoprocessorHost) { 633 ((MasterCoprocessorHost) coprocessorHost).preUpdateConfiguration(conf); 634 } 635 } 636 637 private void postUpdateConfiguration() throws IOException { 638 CoprocessorHost<?, ?> coprocessorHost = getCoprocessorHost(); 639 if (coprocessorHost instanceof RegionServerCoprocessorHost) { 640 ((RegionServerCoprocessorHost) coprocessorHost).postUpdateConfiguration(conf); 641 } else if (coprocessorHost instanceof MasterCoprocessorHost) { 642 ((MasterCoprocessorHost) coprocessorHost).postUpdateConfiguration(conf); 643 } 644 } 645 646 @Override 647 public String toString() { 648 return getServerName().toString(); 649 } 650 651 protected abstract CoprocessorHost<?, ?> getCoprocessorHost(); 652 653 protected abstract boolean canCreateBaseZNode(); 654 655 protected abstract String getProcessName(); 656 657 protected abstract R createRpcServices() throws IOException; 658 659 protected abstract String getUseThisHostnameInstead(Configuration conf) throws IOException; 660 661 protected abstract void login(UserProvider user, String host) throws IOException; 662 663 protected abstract DNS.ServerType getDNSServerType(); 664 665 private String resolveHostName(Configuration conf, String useThisHostnameInstead) 666 throws IOException { 667 if (!StringUtils.isBlank(useThisHostnameInstead)) { 668 return useThisHostnameInstead; 669 } 670 // if use-ip is enabled, we will use ip to expose Master/RS service for client, 671 // see HBASE-27304 for details. 672 boolean useIp = conf.getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY, 673 HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT); 674 InetAddress addr = InetAddress.getByName(DNS.getHostname(conf, getDNSServerType())); 675 return useIp ? addr.getHostAddress() : addr.getHostName(); 676 } 677 678 protected abstract NamedQueueRecorder createNamedQueueRecord(); 679 680 protected abstract void configureInfoServer(InfoServer infoServer); 681 682 protected abstract Class<? extends HttpServlet> getDumpServlet(); 683 684 protected abstract boolean canUpdateTableDescriptor(); 685 686 protected abstract boolean cacheTableDescriptor(); 687 688 protected abstract boolean clusterMode(); 689}