1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.master.balancer;
19
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.LinkedList;
26 import java.util.List;
27 import java.util.concurrent.ExecutionException;
28 import java.util.concurrent.TimeUnit;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.ClusterStatus;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.HDFSBlocksDistribution;
36 import org.apache.hadoop.hbase.HRegionInfo;
37 import org.apache.hadoop.hbase.HTableDescriptor;
38 import org.apache.hadoop.hbase.ServerName;
39 import org.apache.hadoop.hbase.master.MasterServices;
40 import org.apache.hadoop.hbase.regionserver.HRegion;
41
42 import com.google.common.cache.CacheBuilder;
43 import com.google.common.cache.CacheLoader;
44 import com.google.common.cache.LoadingCache;
45
46
47
48
49
50
51
52 class RegionLocationFinder {
53
54 private static Log LOG = LogFactory.getLog(RegionLocationFinder.class);
55
56 private Configuration conf;
57 private ClusterStatus status;
58 private MasterServices services;
59
60 private CacheLoader<HRegionInfo, List<ServerName>> loader =
61 new CacheLoader<HRegionInfo, List<ServerName>>() {
62
63 @Override
64 public List<ServerName> load(HRegionInfo key) throws Exception {
65 List<ServerName> servers = internalGetTopBlockLocation(key);
66 if (servers == null) {
67 return new LinkedList<ServerName>();
68 }
69 return servers;
70 }
71 };
72
73
74 private LoadingCache<HRegionInfo, List<ServerName>> cache = null;
75
76
77
78
79
80
81 private LoadingCache<HRegionInfo, List<ServerName>> createCache(int mins) {
82 return CacheBuilder.newBuilder().expireAfterAccess(mins, TimeUnit.MINUTES).build(loader);
83 }
84
85 public Configuration getConf() {
86 return conf;
87 }
88
89 public void setConf(Configuration conf) {
90 this.conf = conf;
91 cache = createCache(conf.getInt("hbase.master.balancer.regionLocationCacheTime", 30));
92 }
93
94 public void setServices(MasterServices services) {
95 this.services = services;
96 }
97
98 public void setClusterStatus(ClusterStatus status) {
99 this.status = status;
100 }
101
102 protected List<ServerName> getTopBlockLocations(HRegionInfo region) {
103 List<ServerName> servers = null;
104 try {
105 servers = cache.get(region);
106 } catch (ExecutionException ex) {
107 servers = new LinkedList<ServerName>();
108 }
109 return servers;
110
111 }
112
113
114
115
116
117
118
119
120
121
122 protected List<ServerName> internalGetTopBlockLocation(HRegionInfo region) {
123 List<ServerName> topServerNames = null;
124 try {
125 HTableDescriptor tableDescriptor = getTableDescriptor(region.getTable());
126 if (tableDescriptor != null) {
127 HDFSBlocksDistribution blocksDistribution =
128 HRegion.computeHDFSBlocksDistribution(getConf(), tableDescriptor, region);
129 List<String> topHosts = blocksDistribution.getTopHosts();
130 topServerNames = mapHostNameToServerName(topHosts);
131 }
132 } catch (IOException ioe) {
133 LOG.debug("IOException during HDFSBlocksDistribution computation. for " + "region = "
134 + region.getEncodedName(), ioe);
135 }
136
137 return topServerNames;
138 }
139
140
141
142
143
144
145
146
147 protected HTableDescriptor getTableDescriptor(TableName tableName) throws IOException {
148 HTableDescriptor tableDescriptor = null;
149 try {
150 if (this.services != null && this.services.getTableDescriptors() != null) {
151 tableDescriptor = this.services.getTableDescriptors().get(tableName);
152 }
153 } catch (FileNotFoundException fnfe) {
154 LOG.debug("FileNotFoundException during getTableDescriptors." + " Current table name = "
155 + tableName, fnfe);
156 }
157
158 return tableDescriptor;
159 }
160
161
162
163
164
165
166
167
168 protected List<ServerName> mapHostNameToServerName(List<String> hosts) {
169 if (hosts == null || status == null) {
170 return null;
171 }
172
173 List<ServerName> topServerNames = new ArrayList<ServerName>();
174 Collection<ServerName> regionServers = status.getServers();
175
176
177 HashMap<String, List<ServerName>> hostToServerName = new HashMap<String, List<ServerName>>();
178 for (ServerName sn : regionServers) {
179 String host = sn.getHostname();
180 if (!hostToServerName.containsKey(host)) {
181 hostToServerName.put(host, new ArrayList<ServerName>());
182 }
183 hostToServerName.get(host).add(sn);
184 }
185
186 for (String host : hosts) {
187 if (!hostToServerName.containsKey(host)) {
188 continue;
189 }
190 for (ServerName sn : hostToServerName.get(host)) {
191
192
193 if (sn != null) {
194 topServerNames.add(sn);
195 }
196 }
197 }
198 return topServerNames;
199 }
200 }