1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.util;
19
20 import java.io.IOException;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.TreeMap;
28 import java.util.TreeSet;
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.HRegionLocation;
35 import org.apache.hadoop.hbase.RegionLoad;
36 import org.apache.hadoop.hbase.ServerLoad;
37 import org.apache.hadoop.hbase.ServerName;
38 import org.apache.hadoop.hbase.classification.InterfaceAudience;
39 import org.apache.hadoop.hbase.classification.InterfaceStability;
40 import org.apache.hadoop.hbase.client.Admin;
41 import org.apache.hadoop.hbase.client.HBaseAdmin;
42 import org.apache.hadoop.hbase.client.HTable;
43 import org.apache.hadoop.hbase.client.RegionLocator;
44
45
46
47
48
49 @InterfaceStability.Evolving
50 @InterfaceAudience.Private
51 public class RegionSizeCalculator {
52
53 private static final Log LOG = LogFactory.getLog(RegionSizeCalculator.class);
54
55
56
57
58 private final Map<byte[], Long> sizeMap = new TreeMap<byte[], Long>(Bytes.BYTES_COMPARATOR);
59
60 static final String ENABLE_REGIONSIZECALCULATOR = "hbase.regionsizecalculator.enable";
61
62
63
64
65
66
67 @Deprecated
68 public RegionSizeCalculator(HTable table) throws IOException {
69 HBaseAdmin admin = new HBaseAdmin(table.getConfiguration());
70 try {
71 init(table.getRegionLocator(), admin);
72 } finally {
73 admin.close();
74 }
75 }
76
77
78
79
80 public RegionSizeCalculator(RegionLocator regionLocator, Admin admin) throws IOException {
81 init(regionLocator, admin);
82 }
83
84 private void init(RegionLocator regionLocator, Admin admin)
85 throws IOException {
86 if (!enabled(admin.getConfiguration())) {
87 LOG.info("Region size calculation disabled.");
88 return;
89 }
90
91 LOG.info("Calculating region sizes for table \"" + regionLocator.getName() + "\".");
92
93
94 List<HRegionLocation> tableRegionInfos = regionLocator.getAllRegionLocations();
95 Set<byte[]> tableRegions = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
96 for (HRegionLocation regionInfo : tableRegionInfos) {
97 tableRegions.add(regionInfo.getRegionInfo().getRegionName());
98 }
99
100 ClusterStatus clusterStatus = admin.getClusterStatus();
101 Collection<ServerName> servers = clusterStatus.getServers();
102 final long megaByte = 1024L * 1024L;
103
104
105 for (ServerName serverName: servers) {
106 ServerLoad serverLoad = clusterStatus.getLoad(serverName);
107
108 for (RegionLoad regionLoad: serverLoad.getRegionsLoad().values()) {
109 byte[] regionId = regionLoad.getName();
110
111 if (tableRegions.contains(regionId)) {
112
113 long regionSizeBytes = regionLoad.getStorefileSizeMB() * megaByte;
114 sizeMap.put(regionId, regionSizeBytes);
115
116 if (LOG.isDebugEnabled()) {
117 LOG.debug("Region " + regionLoad.getNameAsString() + " has size " + regionSizeBytes);
118 }
119 }
120 }
121 }
122 LOG.debug("Region sizes calculated");
123 }
124
125 boolean enabled(Configuration configuration) {
126 return configuration.getBoolean(ENABLE_REGIONSIZECALCULATOR, true);
127 }
128
129
130
131
132 public long getRegionSize(byte[] regionId) {
133 Long size = sizeMap.get(regionId);
134 if (size == null) {
135 LOG.debug("Unknown region:" + Arrays.toString(regionId));
136 return 0;
137 } else {
138 return size;
139 }
140 }
141
142 public Map<byte[], Long> getRegionSizeMap() {
143 return Collections.unmodifiableMap(sizeMap);
144 }
145 }