1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master.handler;
20
21 import java.io.IOException;
22 import java.io.InterruptedIOException;
23 import java.util.Map;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.HRegionInfo;
29 import org.apache.hadoop.hbase.RegionLoad;
30 import org.apache.hadoop.hbase.ServerLoad;
31 import org.apache.hadoop.hbase.ServerName;
32 import org.apache.hadoop.hbase.exceptions.RegionOpeningException;
33 import org.apache.hadoop.hbase.executor.EventHandler;
34 import org.apache.hadoop.hbase.executor.EventType;
35 import org.apache.hadoop.hbase.master.CatalogJanitor;
36 import org.apache.hadoop.hbase.master.MasterServices;
37 import org.apache.hadoop.hbase.master.RegionPlan;
38 import org.apache.hadoop.hbase.master.RegionStates;
39 import org.apache.hadoop.hbase.master.ServerManager;
40 import org.apache.hadoop.hbase.security.User;
41 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
42
43
44
45
46
47
48
49
50 @InterfaceAudience.Private
51 public class DispatchMergingRegionHandler extends EventHandler {
52 private static final Log LOG = LogFactory.getLog(DispatchMergingRegionHandler.class);
53 private final MasterServices masterServices;
54 private final CatalogJanitor catalogJanitor;
55 private HRegionInfo region_a;
56 private HRegionInfo region_b;
57 private final boolean forcible;
58 private final int timeout;
59 private final User user;
60
61 public DispatchMergingRegionHandler(final MasterServices services,
62 final CatalogJanitor catalogJanitor, final HRegionInfo region_a,
63 final HRegionInfo region_b, final boolean forcible, final User user) {
64 super(services, EventType.C_M_MERGE_REGION);
65 this.masterServices = services;
66 this.catalogJanitor = catalogJanitor;
67 this.region_a = region_a;
68 this.region_b = region_b;
69 this.forcible = forcible;
70 this.user = user;
71 this.timeout = server.getConfiguration().getInt(
72 "hbase.master.regionmerge.timeout", 120 * 1000);
73 }
74
75 @Override
76 public void process() throws IOException {
77 boolean regionAHasMergeQualifier = !catalogJanitor.cleanMergeQualifier(region_a);
78 if (regionAHasMergeQualifier
79 || !catalogJanitor.cleanMergeQualifier(region_b)) {
80 LOG.info("Skip merging regions " + region_a.getRegionNameAsString()
81 + ", " + region_b.getRegionNameAsString() + ", because region "
82 + (regionAHasMergeQualifier ? region_a.getEncodedName() : region_b
83 .getEncodedName()) + " has merge qualifier");
84 return;
85 }
86
87 RegionStates regionStates = masterServices.getAssignmentManager()
88 .getRegionStates();
89 ServerName region_a_location = regionStates.getRegionServerOfRegion(region_a);
90 ServerName region_b_location = regionStates.getRegionServerOfRegion(region_b);
91 if (region_a_location == null || region_b_location == null) {
92 LOG.info("Skip merging regions " + region_a.getRegionNameAsString()
93 + ", " + region_b.getRegionNameAsString() + ", because region "
94 + (region_a_location == null ? region_a.getEncodedName() : region_b
95 .getEncodedName()) + " is not online now");
96 return;
97 }
98 long startTime = EnvironmentEdgeManager.currentTime();
99 boolean onSameRS = region_a_location.equals(region_b_location);
100
101
102
103 if (!onSameRS) {
104
105
106
107 RegionLoad loadOfRegionA = getRegionLoad(region_a_location, region_a);
108 RegionLoad loadOfRegionB = getRegionLoad(region_b_location, region_b);
109 if (loadOfRegionA != null && loadOfRegionB != null
110 && loadOfRegionA.getRequestsCount() < loadOfRegionB
111 .getRequestsCount()) {
112
113 HRegionInfo tmpRegion = this.region_a;
114 this.region_a = this.region_b;
115 this.region_b = tmpRegion;
116 ServerName tmpLocation = region_a_location;
117 region_a_location = region_b_location;
118 region_b_location = tmpLocation;
119 }
120
121 RegionPlan regionPlan = new RegionPlan(region_b, region_b_location,
122 region_a_location);
123 LOG.info("Moving regions to same server for merge: " + regionPlan.toString());
124 masterServices.getAssignmentManager().balance(regionPlan);
125 while (!masterServices.isStopped()) {
126 try {
127 Thread.sleep(20);
128
129
130
131 boolean isRIT = regionStates.isRegionInTransition(region_b);
132 region_b_location = masterServices.getAssignmentManager()
133 .getRegionStates().getRegionServerOfRegion(region_b);
134 onSameRS = region_a_location.equals(region_b_location);
135 if (onSameRS || !isRIT) {
136
137
138 break;
139 }
140 if ((EnvironmentEdgeManager.currentTime() - startTime) > timeout) break;
141 } catch (InterruptedException e) {
142 InterruptedIOException iioe = new InterruptedIOException();
143 iioe.initCause(e);
144 throw iioe;
145 }
146 }
147 }
148
149 if (onSameRS) {
150 startTime = EnvironmentEdgeManager.currentTime();
151 while (!masterServices.isStopped()) {
152 try {
153 masterServices.getServerManager().sendRegionsMerge(region_a_location,
154 region_a, region_b, forcible, user);
155 LOG.info("Sent merge to server " + region_a_location + " for region " +
156 region_a.getEncodedName() + "," + region_b.getEncodedName() + ", focible=" + forcible);
157 break;
158 } catch (RegionOpeningException roe) {
159 if ((EnvironmentEdgeManager.currentTime() - startTime) > timeout) {
160 LOG.warn("Failed sending merge to " + region_a_location + " after " + timeout + "ms",
161 roe);
162 break;
163 }
164
165 } catch (IOException ie) {
166 LOG.warn("Failed sending merge to " + region_a_location + " for region " +
167 region_a.getEncodedName() + "," + region_b.getEncodedName() + ", focible=" + forcible,
168 ie);
169 break;
170 }
171 }
172 } else {
173 LOG.info("Cancel merging regions " + region_a.getRegionNameAsString()
174 + ", " + region_b.getRegionNameAsString()
175 + ", because can't move them together after "
176 + (EnvironmentEdgeManager.currentTime() - startTime) + "ms");
177 }
178 }
179
180 private RegionLoad getRegionLoad(ServerName sn, HRegionInfo hri) {
181 ServerManager serverManager = masterServices.getServerManager();
182 ServerLoad load = serverManager.getLoad(sn);
183 if (load != null) {
184 Map<byte[], RegionLoad> regionsLoad = load.getRegionsLoad();
185 if (regionsLoad != null) {
186 return regionsLoad.get(hri.getRegionName());
187 }
188 }
189 return null;
190 }
191 }