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.master.balancer.replicas; 019 020import java.time.Duration; 021import java.util.function.Supplier; 022import org.apache.hadoop.conf.Configurable; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.hbase.client.RegionInfo; 025import org.apache.yetus.audience.InterfaceAudience; 026 027import org.apache.hbase.thirdparty.com.google.common.base.Suppliers; 028import org.apache.hbase.thirdparty.com.google.common.cache.CacheBuilder; 029import org.apache.hbase.thirdparty.com.google.common.cache.CacheLoader; 030import org.apache.hbase.thirdparty.com.google.common.cache.LoadingCache; 031 032@InterfaceAudience.Private 033public final class ReplicaKeyCache implements Configurable { 034 /** 035 * ReplicaKey creation is expensive if you have lots of regions. If your HMaster has adequate 036 * memory, and you would like balancing to be faster, then you can turn on this flag to cache 037 * ReplicaKey objects. 038 */ 039 public static final String CACHE_REPLICA_KEYS_KEY = 040 "hbase.replica.distribution.conditional.cacheReplicaKeys"; 041 public static final boolean CACHE_REPLICA_KEYS_DEFAULT = false; 042 043 /** 044 * If memory is available, then set this to a value greater than your region count to maximize 045 * replica distribution performance. 046 */ 047 public static final String REPLICA_KEY_CACHE_SIZE_KEY = 048 "hbase.replica.distribution.conditional.replicaKeyCacheSize"; 049 public static final int REPLICA_KEY_CACHE_SIZE_DEFAULT = 1000; 050 051 private static final Supplier<ReplicaKeyCache> INSTANCE = Suppliers.memoize(ReplicaKeyCache::new); 052 053 private volatile LoadingCache<RegionInfo, ReplicaKey> replicaKeyCache = null; 054 055 private Configuration conf; 056 057 public static ReplicaKeyCache getInstance() { 058 return INSTANCE.get(); 059 } 060 061 private ReplicaKeyCache() { 062 } 063 064 public ReplicaKey getReplicaKey(RegionInfo regionInfo) { 065 return replicaKeyCache == null 066 ? new ReplicaKey(regionInfo) 067 : replicaKeyCache.getUnchecked(regionInfo); 068 } 069 070 @Override 071 public void setConf(Configuration conf) { 072 this.conf = conf; 073 boolean cacheKeys = conf.getBoolean(CACHE_REPLICA_KEYS_KEY, CACHE_REPLICA_KEYS_DEFAULT); 074 if (cacheKeys && replicaKeyCache == null) { 075 int replicaKeyCacheSize = 076 conf.getInt(REPLICA_KEY_CACHE_SIZE_KEY, REPLICA_KEY_CACHE_SIZE_DEFAULT); 077 replicaKeyCache = CacheBuilder.newBuilder().maximumSize(replicaKeyCacheSize) 078 .expireAfterAccess(Duration.ofMinutes(30)).build(new CacheLoader<RegionInfo, ReplicaKey>() { 079 @Override 080 public ReplicaKey load(RegionInfo regionInfo) { 081 return new ReplicaKey(regionInfo); 082 } 083 }); 084 } else if (!cacheKeys) { 085 replicaKeyCache = null; 086 } 087 } 088 089 @Override 090 public Configuration getConf() { 091 return conf; 092 } 093}