1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.util;
21
22 import java.io.IOException;
23 import java.io.InterruptedIOException;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.concurrent.Callable;
28 import java.util.concurrent.CompletionService;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.ExecutorCompletionService;
31 import java.util.concurrent.Future;
32 import java.util.concurrent.ThreadFactory;
33 import java.util.concurrent.ThreadPoolExecutor;
34 import java.util.concurrent.TimeUnit;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.hadoop.hbase.classification.InterfaceAudience;
39 import org.apache.hadoop.conf.Configuration;
40 import org.apache.hadoop.fs.Path;
41 import org.apache.hadoop.hbase.HRegionInfo;
42 import org.apache.hadoop.hbase.HTableDescriptor;
43 import org.apache.hadoop.hbase.regionserver.HRegion;
44 import org.apache.hadoop.hbase.master.AssignmentManager;
45
46
47
48
49 @InterfaceAudience.Private
50 public abstract class ModifyRegionUtils {
51 private static final Log LOG = LogFactory.getLog(ModifyRegionUtils.class);
52
53 private ModifyRegionUtils() {
54 }
55
56 public interface RegionFillTask {
57 void fillRegion(final HRegion region) throws IOException;
58 }
59
60 public interface RegionEditTask {
61 void editRegion(final HRegionInfo region) throws IOException;
62 }
63
64
65
66
67
68
69
70
71
72
73
74 public static List<HRegionInfo> createRegions(final Configuration conf, final Path rootDir,
75 final HTableDescriptor hTableDescriptor, final HRegionInfo[] newRegions) throws IOException {
76 return createRegions(conf, rootDir, hTableDescriptor, newRegions, null);
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90 public static List<HRegionInfo> createRegions(final Configuration conf, final Path rootDir,
91 final HTableDescriptor hTableDescriptor, final HRegionInfo[] newRegions,
92 final RegionFillTask task) throws IOException {
93
94 Path tableDir = FSUtils.getTableDir(rootDir, hTableDescriptor.getTableName());
95 return createRegions(conf, rootDir, tableDir, hTableDescriptor, newRegions, task);
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109
110 public static List<HRegionInfo> createRegions(final Configuration conf, final Path rootDir,
111 final Path tableDir, final HTableDescriptor hTableDescriptor, final HRegionInfo[] newRegions,
112 final RegionFillTask task) throws IOException {
113 if (newRegions == null) return null;
114 int regionNumber = newRegions.length;
115 ThreadPoolExecutor exec = getRegionOpenAndInitThreadPool(conf,
116 "RegionOpenAndInitThread-" + hTableDescriptor.getTableName(), regionNumber);
117 try {
118 return createRegions(exec, conf, rootDir, tableDir, hTableDescriptor, newRegions, task);
119 } finally {
120 exec.shutdownNow();
121 }
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public static List<HRegionInfo> createRegions(final ThreadPoolExecutor exec,
138 final Configuration conf, final Path rootDir, final Path tableDir,
139 final HTableDescriptor hTableDescriptor, final HRegionInfo[] newRegions,
140 final RegionFillTask task) throws IOException {
141 if (newRegions == null) return null;
142 int regionNumber = newRegions.length;
143 CompletionService<HRegionInfo> completionService =
144 new ExecutorCompletionService<HRegionInfo>(exec);
145 List<HRegionInfo> regionInfos = new ArrayList<HRegionInfo>();
146 for (final HRegionInfo newRegion : newRegions) {
147 completionService.submit(new Callable<HRegionInfo>() {
148 @Override
149 public HRegionInfo call() throws IOException {
150 return createRegion(conf, rootDir, tableDir, hTableDescriptor, newRegion, task);
151 }
152 });
153 }
154 try {
155
156 for (int i = 0; i < regionNumber; i++) {
157 Future<HRegionInfo> future = completionService.take();
158 HRegionInfo regionInfo = future.get();
159 regionInfos.add(regionInfo);
160 }
161 } catch (InterruptedException e) {
162 LOG.error("Caught " + e + " during region creation");
163 throw new InterruptedIOException(e.getMessage());
164 } catch (ExecutionException e) {
165 throw new IOException(e);
166 }
167 return regionInfos;
168 }
169
170
171
172
173
174
175
176
177
178
179
180 public static HRegionInfo createRegion(final Configuration conf, final Path rootDir,
181 final Path tableDir, final HTableDescriptor hTableDescriptor, final HRegionInfo newRegion,
182 final RegionFillTask task) throws IOException {
183
184 HRegion region = HRegion.createHRegion(newRegion,
185 rootDir, tableDir, conf, hTableDescriptor, null,
186 false, true);
187 try {
188
189 if (task != null) {
190 task.fillRegion(region);
191 }
192 } finally {
193
194 region.close();
195 }
196 return region.getRegionInfo();
197 }
198
199
200
201
202
203
204
205
206
207 public static void editRegions(final ThreadPoolExecutor exec,
208 final Collection<HRegionInfo> regions, final RegionEditTask task) throws IOException {
209 final ExecutorCompletionService<Void> completionService =
210 new ExecutorCompletionService<Void>(exec);
211 for (final HRegionInfo hri: regions) {
212 completionService.submit(new Callable<Void>() {
213 @Override
214 public Void call() throws IOException {
215 task.editRegion(hri);
216 return null;
217 }
218 });
219 }
220
221 try {
222 for (HRegionInfo hri: regions) {
223 completionService.take().get();
224 }
225 } catch (InterruptedException e) {
226 throw new InterruptedIOException(e.getMessage());
227 } catch (ExecutionException e) {
228 IOException ex = new IOException();
229 ex.initCause(e.getCause());
230 throw ex;
231 }
232 }
233
234
235
236
237
238 static ThreadPoolExecutor getRegionOpenAndInitThreadPool(final Configuration conf,
239 final String threadNamePrefix, int regionNumber) {
240 int maxThreads = Math.min(regionNumber, conf.getInt(
241 "hbase.hregion.open.and.init.threads.max", 10));
242 ThreadPoolExecutor regionOpenAndInitThreadPool = Threads
243 .getBoundedCachedThreadPool(maxThreads, 30L, TimeUnit.SECONDS,
244 new ThreadFactory() {
245 private int count = 1;
246
247 @Override
248 public Thread newThread(Runnable r) {
249 Thread t = new Thread(r, threadNamePrefix + "-" + count++);
250 return t;
251 }
252 });
253 return regionOpenAndInitThreadPool;
254 }
255
256
257
258
259
260
261
262
263 public static void assignRegions(final AssignmentManager assignmentManager,
264 final List<HRegionInfo> regionInfos) throws IOException {
265 try {
266 assignmentManager.getRegionStates().createRegionStates(regionInfos);
267 assignmentManager.assign(regionInfos);
268 } catch (InterruptedException e) {
269 LOG.error("Caught " + e + " during round-robin assignment");
270 InterruptedIOException ie = new InterruptedIOException(e.getMessage());
271 ie.initCause(e);
272 throw ie;
273 }
274 }
275 }