1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.util;
20
21 import java.io.IOException;
22 import java.util.PriorityQueue;
23 import java.util.Queue;
24 import java.util.Set;
25 import java.util.concurrent.ArrayBlockingQueue;
26 import java.util.concurrent.BlockingQueue;
27 import java.util.concurrent.ConcurrentSkipListSet;
28 import java.util.concurrent.TimeUnit;
29 import java.util.concurrent.atomic.AtomicLong;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.HRegionLocation;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.client.Table;
37 import org.apache.hadoop.hbase.util.test.LoadTestDataGenerator;
38
39
40 public abstract class MultiThreadedWriterBase extends MultiThreadedAction {
41 private static final Log LOG = LogFactory.getLog(MultiThreadedWriterBase.class);
42
43
44
45
46
47
48
49 protected BlockingQueue<Long> wroteKeys;
50
51
52
53
54
55 protected AtomicLong nextKeyToWrite = new AtomicLong();
56
57
58
59
60 protected AtomicLong wroteUpToKey = new AtomicLong();
61
62
63 protected Set<Long> failedKeySet = new ConcurrentSkipListSet<Long>();
64
65
66
67
68
69
70 protected AtomicLong wroteKeyQueueSize = new AtomicLong();
71
72
73 protected boolean trackWroteKeys;
74
75 public MultiThreadedWriterBase(LoadTestDataGenerator dataGen, Configuration conf,
76 TableName tableName, String actionLetter) throws IOException {
77 super(dataGen, conf, tableName, actionLetter);
78 this.wroteKeys = createWriteKeysQueue(conf);
79 }
80
81 protected BlockingQueue<Long> createWriteKeysQueue(Configuration conf) {
82 return new ArrayBlockingQueue<Long>(10000);
83 }
84
85 @Override
86 public void start(long startKey, long endKey, int numThreads) throws IOException {
87 super.start(startKey, endKey, numThreads);
88 nextKeyToWrite.set(startKey);
89 wroteUpToKey.set(startKey - 1);
90
91 if (trackWroteKeys) {
92 new Thread(new WroteKeysTracker(),
93 "MultiThreadedWriterBase-WroteKeysTracker-" + System.currentTimeMillis()).start();
94 numThreadsWorking.incrementAndGet();
95 }
96 }
97
98 protected String getRegionDebugInfoSafe(Table table, byte[] rowKey) {
99 HRegionLocation cached = null, real = null;
100 try {
101 cached = connection.getRegionLocation(tableName, rowKey, false);
102 real = connection.getRegionLocation(tableName, rowKey, true);
103 } catch (Throwable t) {
104
105 }
106 String result = "no information can be obtained";
107 if (cached != null) {
108 result = "cached: " + cached.toString();
109 }
110 if (real != null && real.getServerName() != null) {
111 if (cached != null && cached.getServerName() != null && real.equals(cached)) {
112 result += "; cache is up to date";
113 } else {
114 result = (cached != null) ? (result + "; ") : "";
115 result += "real: " + real.toString();
116 }
117 }
118 return result;
119 }
120
121
122
123
124
125 private class WroteKeysTracker implements Runnable {
126
127 @Override
128 public void run() {
129 Thread.currentThread().setName(getClass().getSimpleName());
130 try {
131 long expectedKey = startKey;
132 Queue<Long> sortedKeys = new PriorityQueue<Long>();
133 while (expectedKey < endKey) {
134
135 Long k;
136 try {
137 k = wroteKeys.poll(1, TimeUnit.SECONDS);
138 } catch (InterruptedException e) {
139 LOG.info("Inserted key tracker thread interrupted", e);
140 break;
141 }
142 if (k == null) {
143 continue;
144 }
145 if (k == expectedKey) {
146
147 wroteUpToKey.set(k);
148 ++expectedKey;
149 } else {
150 sortedKeys.add(k);
151 }
152
153
154 while (!sortedKeys.isEmpty()
155 && ((k = sortedKeys.peek()) == expectedKey)) {
156 sortedKeys.poll();
157 wroteUpToKey.set(k);
158 ++expectedKey;
159 }
160
161 wroteKeyQueueSize.set(wroteKeys.size() + sortedKeys.size());
162 }
163 } catch (Exception ex) {
164 LOG.error("Error in inserted/updaed key tracker", ex);
165 } finally {
166 numThreadsWorking.decrementAndGet();
167 }
168 }
169 }
170
171 public int getNumWriteFailures() {
172 return failedKeySet.size();
173 }
174
175
176
177
178
179 public long wroteUpToKey() {
180 return wroteUpToKey.get();
181 }
182
183 public boolean failedToWriteKey(long k) {
184 return failedKeySet.contains(k);
185 }
186
187 @Override
188 protected String progressInfo() {
189 StringBuilder sb = new StringBuilder();
190 appendToStatus(sb, "wroteUpTo", wroteUpToKey.get());
191 appendToStatus(sb, "wroteQSize", wroteKeyQueueSize.get());
192 return sb.toString();
193 }
194
195
196
197
198
199
200 public void setTrackWroteKeys(boolean enable) {
201 trackWroteKeys = enable;
202 }
203 }