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