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