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
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.classification.InterfaceAudience;
27 import org.apache.hadoop.hbase.HRegionInfo;
28 import org.apache.hadoop.hbase.RegionLoad;
29 import org.apache.hadoop.hbase.ServerName;
30 import org.apache.hadoop.hbase.executor.EventHandler;
31 import org.apache.hadoop.hbase.executor.EventType;
32 import org.apache.hadoop.hbase.master.CatalogJanitor;
33 import org.apache.hadoop.hbase.master.MasterServices;
34 import org.apache.hadoop.hbase.master.RegionPlan;
35 import org.apache.hadoop.hbase.master.RegionStates;
36 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
37
38
39
40
41
42
43
44
45 @InterfaceAudience.Private
46 public class DispatchMergingRegionHandler extends EventHandler {
47 private static final Log LOG = LogFactory.getLog(DispatchMergingRegionHandler.class);
48 private final MasterServices masterServices;
49 private final CatalogJanitor catalogJanitor;
50 private HRegionInfo region_a;
51 private HRegionInfo region_b;
52 private final boolean forcible;
53 private final int timeout;
54
55 public DispatchMergingRegionHandler(final MasterServices services,
56 final CatalogJanitor catalogJanitor, final HRegionInfo region_a,
57 final HRegionInfo region_b, final boolean forcible) {
58 super(services, EventType.C_M_MERGE_REGION);
59 this.masterServices = services;
60 this.catalogJanitor = catalogJanitor;
61 this.region_a = region_a;
62 this.region_b = region_b;
63 this.forcible = forcible;
64 this.timeout = server.getConfiguration().getInt(
65 "hbase.master.regionmerge.timeout", 30 * 1000);
66 }
67
68 @Override
69 public void process() throws IOException {
70 boolean regionAHasMergeQualifier = !catalogJanitor.cleanMergeQualifier(region_a);
71 if (regionAHasMergeQualifier
72 || !catalogJanitor.cleanMergeQualifier(region_b)) {
73 LOG.info("Skip merging regions " + region_a.getRegionNameAsString()
74 + ", " + region_b.getRegionNameAsString() + ", because region "
75 + (regionAHasMergeQualifier ? region_a.getEncodedName() : region_b
76 .getEncodedName()) + " has merge qualifier");
77 return;
78 }
79
80 RegionStates regionStates = masterServices.getAssignmentManager()
81 .getRegionStates();
82 ServerName region_a_location = regionStates.getRegionServerOfRegion(region_a);
83 ServerName region_b_location = regionStates.getRegionServerOfRegion(region_b);
84 if (region_a_location == null || region_b_location == null) {
85 LOG.info("Skip merging regions " + region_a.getRegionNameAsString()
86 + ", " + region_b.getRegionNameAsString() + ", because region "
87 + (region_a_location == null ? region_a.getEncodedName() : region_b
88 .getEncodedName()) + " is not online now");
89 return;
90 }
91 long startTime = EnvironmentEdgeManager.currentTimeMillis();
92 boolean onSameRS = region_a_location.equals(region_b_location);
93
94
95
96 if (!onSameRS) {
97
98
99
100 RegionLoad loadOfRegionA = masterServices.getServerManager()
101 .getLoad(region_a_location).getRegionsLoad()
102 .get(region_a.getRegionName());
103 RegionLoad loadOfRegionB = masterServices.getServerManager()
104 .getLoad(region_b_location).getRegionsLoad()
105 .get(region_b.getRegionName());
106 if (loadOfRegionA != null && loadOfRegionB != null
107 && loadOfRegionA.getRequestsCount() < loadOfRegionB
108 .getRequestsCount()) {
109
110 HRegionInfo tmpRegion = this.region_a;
111 this.region_a = this.region_b;
112 this.region_b = tmpRegion;
113 ServerName tmpLocation = region_a_location;
114 region_a_location = region_b_location;
115 region_b_location = tmpLocation;
116 }
117
118 RegionPlan regionPlan = new RegionPlan(region_b, region_b_location,
119 region_a_location);
120 masterServices.getAssignmentManager().balance(regionPlan);
121 while (!masterServices.isStopped()) {
122 try {
123 Thread.sleep(20);
124 region_b_location = masterServices.getAssignmentManager()
125 .getRegionStates().getRegionServerOfRegion(region_b);
126 onSameRS = region_a_location.equals(region_b_location);
127 if (onSameRS || !regionStates.isRegionInTransition(region_b)) {
128
129
130 break;
131 }
132 if ((EnvironmentEdgeManager.currentTimeMillis() - startTime) > timeout) break;
133 } catch (InterruptedException e) {
134 InterruptedIOException iioe = new InterruptedIOException();
135 iioe.initCause(e);
136 throw iioe;
137 }
138 }
139 }
140
141 if (onSameRS) {
142 try{
143 masterServices.getServerManager().sendRegionsMerge(region_a_location,
144 region_a, region_b, forcible);
145 LOG.info("Successfully send MERGE REGIONS RPC to server "
146 + region_a_location.toString() + " for region "
147 + region_a.getRegionNameAsString() + ","
148 + region_b.getRegionNameAsString() + ", focible=" + forcible);
149 } catch (IOException ie) {
150 LOG.info("Failed send MERGE REGIONS RPC to server "
151 + region_a_location.toString() + " for region "
152 + region_a.getRegionNameAsString() + ","
153 + region_b.getRegionNameAsString() + ", focible=" + forcible + ", "
154 + ie.getMessage());
155 }
156 } else {
157 LOG.info("Cancel merging regions " + region_a.getRegionNameAsString()
158 + ", " + region_b.getRegionNameAsString()
159 + ", because can't move them together after "
160 + (EnvironmentEdgeManager.currentTimeMillis() - startTime) + "ms");
161 }
162 }
163
164 }