Skip to content

Commit e4d83cc

Browse files
committed
Merge branch '2.1' into 3.1
2 parents fbe236d + c817c97 commit e4d83cc

File tree

5 files changed

+380
-24
lines changed

5 files changed

+380
-24
lines changed

core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ public static <E extends Entry<Key,Value>> TabletMetadata convertRow(Iterator<E>
518518
}
519519

520520
@VisibleForTesting
521-
static TabletMetadata create(String id, String prevEndRow, String endRow) {
521+
public static TabletMetadata create(String id, String prevEndRow, String endRow) {
522522
final var tmBuilder = new Builder();
523523
tmBuilder.table(TableId.of(id));
524524
tmBuilder.sawPrevEndRow(true);

core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,8 @@ private TabletsMetadata(TabletMetadata tm) {
619619
this.tablets = Collections.singleton(tm);
620620
}
621621

622-
private TabletsMetadata(AutoCloseable closeable, Iterable<TabletMetadata> tmi) {
622+
// visible for testing
623+
public TabletsMetadata(AutoCloseable closeable, Iterable<TabletMetadata> tmi) {
623624
this.closeable = closeable;
624625
this.tablets = tmi;
625626
}

server/manager/src/main/java/org/apache/accumulo/manager/tableOps/bulkVer2/LoadFiles.java

+71-20
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOCATION;
2424
import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW;
2525

26+
import java.time.Duration;
2627
import java.util.ArrayList;
2728
import java.util.Comparator;
2829
import java.util.HashMap;
@@ -41,7 +42,6 @@
4142
import org.apache.accumulo.core.clientImpl.bulk.LoadMappingIterator;
4243
import org.apache.accumulo.core.conf.Property;
4344
import org.apache.accumulo.core.data.Mutation;
44-
import org.apache.accumulo.core.data.TableId;
4545
import org.apache.accumulo.core.dataImpl.KeyExtent;
4646
import org.apache.accumulo.core.dataImpl.thrift.TKeyExtent;
4747
import org.apache.accumulo.core.fate.FateTxId;
@@ -64,6 +64,7 @@
6464
import org.apache.accumulo.core.util.MapCounter;
6565
import org.apache.accumulo.core.util.PeekingIterator;
6666
import org.apache.accumulo.core.util.TextUtil;
67+
import org.apache.accumulo.core.util.Timer;
6768
import org.apache.accumulo.manager.Manager;
6869
import org.apache.accumulo.manager.tableOps.ManagerRepo;
6970
import org.apache.accumulo.server.fs.VolumeManager;
@@ -82,6 +83,13 @@
8283
*/
8384
class LoadFiles extends ManagerRepo {
8485

86+
// visible for testing
87+
interface TabletsMetadataFactory {
88+
89+
TabletsMetadata newTabletsMetadata(Text startRow);
90+
91+
}
92+
8593
private static final long serialVersionUID = 1L;
8694

8795
private static final Logger log = LoggerFactory.getLogger(LoadFiles.class);
@@ -94,6 +102,7 @@ public LoadFiles(BulkInfo bulkInfo) {
94102

95103
@Override
96104
public long isReady(long tid, Manager manager) throws Exception {
105+
log.info("Starting bulk import for {} (tid = {})", bulkInfo.sourceDir, FateTxId.formatTid(tid));
97106
if (manager.onlineTabletServers().isEmpty()) {
98107
log.warn("There are no tablet server to process bulkDir import, waiting (tid = "
99108
+ FateTxId.formatTid(tid) + ")");
@@ -104,7 +113,19 @@ public long isReady(long tid, Manager manager) throws Exception {
104113
manager.updateBulkImportStatus(bulkInfo.sourceDir, BulkImportState.LOADING);
105114
try (LoadMappingIterator lmi =
106115
BulkSerialize.getUpdatedLoadMapping(bulkDir.toString(), bulkInfo.tableId, fs::open)) {
107-
return loadFiles(bulkInfo.tableId, bulkDir, lmi, manager, tid);
116+
117+
Loader loader;
118+
if (bulkInfo.tableState == TableState.ONLINE) {
119+
loader = new OnlineLoader();
120+
} else {
121+
loader = new OfflineLoader();
122+
}
123+
124+
TabletsMetadataFactory tmf = (startRow) -> TabletsMetadata.builder(manager.getContext())
125+
.forTable(bulkInfo.tableId).overlapping(startRow, null).checkConsistency()
126+
.fetch(PREV_ROW, LOCATION, LOADED).build();
127+
128+
return loadFiles(loader, bulkInfo, bulkDir, lmi, tmf, manager, tid);
108129
}
109130
}
110131

@@ -117,7 +138,8 @@ public Repo<Manager> call(final long tid, final Manager manager) {
117138
}
118139
}
119140

120-
private abstract static class Loader {
141+
// visible for testing
142+
public abstract static class Loader {
121143
protected Path bulkDir;
122144
protected Manager manager;
123145
protected long tid;
@@ -315,14 +337,26 @@ long finish() throws Exception {
315337
}
316338
}
317339

340+
/**
341+
* Stats for the loadFiles method. Helps track wasted time and iterations.
342+
*/
343+
static class ImportTimingStats {
344+
Duration totalWastedTime = Duration.ZERO;
345+
long wastedIterations = 0;
346+
long tabletCount = 0;
347+
long callCount = 0;
348+
}
349+
318350
/**
319351
* Make asynchronous load calls to each overlapping Tablet in the bulk mapping. Return a sleep
320352
* time to isReady based on a factor of the TabletServer with the most Tablets. This method will
321353
* scan the metadata table getting Tablet range and location information. It will return 0 when
322354
* all files have been loaded.
323355
*/
324-
private long loadFiles(TableId tableId, Path bulkDir, LoadMappingIterator loadMapIter,
325-
Manager manager, long tid) throws Exception {
356+
// visible for testing
357+
static long loadFiles(Loader loader, BulkInfo bulkInfo, Path bulkDir,
358+
LoadMappingIterator loadMapIter, TabletsMetadataFactory factory, Manager manager, long tid)
359+
throws Exception {
326360
PeekingIterator<Map.Entry<KeyExtent,Bulk.Files>> lmi = new PeekingIterator<>(loadMapIter);
327361
Map.Entry<KeyExtent,Bulk.Files> loadMapEntry = lmi.peek();
328362

@@ -331,33 +365,38 @@ private long loadFiles(TableId tableId, Path bulkDir, LoadMappingIterator loadMa
331365
String fmtTid = FateTxId.formatTid(tid);
332366
log.trace("{}: Starting bulk load at row: {}", fmtTid, startRow);
333367

334-
Loader loader;
335-
if (bulkInfo.tableState == TableState.ONLINE) {
336-
loader = new OnlineLoader();
337-
} else {
338-
loader = new OfflineLoader();
339-
}
340-
long t1;
341368
loader.start(bulkDir, manager, tid, bulkInfo.setTime);
342-
try (TabletsMetadata tabletsMetadata =
343-
TabletsMetadata.builder(manager.getContext()).forTable(tableId).overlapping(startRow, null)
344-
.checkConsistency().fetch(PREV_ROW, LOCATION, LOADED).build()) {
345369

346-
t1 = System.currentTimeMillis();
370+
ImportTimingStats importTimingStats = new ImportTimingStats();
371+
Timer timer = Timer.startNew();
372+
try (TabletsMetadata tabletsMetadata = factory.newTabletsMetadata(startRow)) {
373+
374+
Iterator<TabletMetadata> tabletIter = tabletsMetadata.iterator();
347375
while (lmi.hasNext()) {
348376
loadMapEntry = lmi.next();
349377
List<TabletMetadata> tablets =
350-
findOverlappingTablets(fmtTid, loadMapEntry.getKey(), tabletsMetadata.iterator());
378+
findOverlappingTablets(fmtTid, loadMapEntry.getKey(), tabletIter, importTimingStats);
351379
loader.load(tablets, loadMapEntry.getValue());
352380
}
353381
}
382+
Duration totalProcessingTime = timer.elapsed();
354383

355384
log.trace("{}: Completed Finding Overlapping Tablets", fmtTid);
356385

386+
if (importTimingStats.callCount > 0) {
387+
log.debug(
388+
"Bulk import stats for {} (tid = {}): processed {} tablets in {} calls which took {}ms ({} nanos). Skipped {} iterations which took {}ms ({} nanos) or {}% of the processing time.",
389+
bulkInfo.sourceDir, FateTxId.formatTid(tid), importTimingStats.tabletCount,
390+
importTimingStats.callCount, totalProcessingTime.toMillis(),
391+
totalProcessingTime.toNanos(), importTimingStats.wastedIterations,
392+
importTimingStats.totalWastedTime.toMillis(), importTimingStats.totalWastedTime.toNanos(),
393+
(importTimingStats.totalWastedTime.toNanos() * 100) / totalProcessingTime.toNanos());
394+
}
395+
357396
long sleepTime = loader.finish();
358397
if (sleepTime > 0) {
359398
log.trace("{}: Tablet Max Sleep is {}", fmtTid, sleepTime);
360-
long scanTime = Math.min(System.currentTimeMillis() - t1, 30_000);
399+
long scanTime = Math.min(totalProcessingTime.toMillis(), 30_000);
361400
log.trace("{}: Scan time is {}", fmtTid, scanTime);
362401
sleepTime = Math.max(sleepTime, scanTime * 2);
363402
}
@@ -371,8 +410,9 @@ private long loadFiles(TableId tableId, Path bulkDir, LoadMappingIterator loadMa
371410
/**
372411
* Find all the tablets within the provided bulk load mapping range.
373412
*/
374-
private List<TabletMetadata> findOverlappingTablets(String fmtTid, KeyExtent loadRange,
375-
Iterator<TabletMetadata> tabletIter) {
413+
// visible for testing
414+
static List<TabletMetadata> findOverlappingTablets(String fmtTid, KeyExtent loadRange,
415+
Iterator<TabletMetadata> tabletIter, ImportTimingStats importTimingStats) {
376416

377417
TabletMetadata currTablet = null;
378418

@@ -384,12 +424,18 @@ private List<TabletMetadata> findOverlappingTablets(String fmtTid, KeyExtent loa
384424

385425
int cmp;
386426

427+
long wastedIterations = 0;
428+
Timer timer = Timer.startNew();
429+
387430
// skip tablets until we find the prevEndRow of loadRange
388431
while ((cmp = PREV_COMP.compare(currTablet.getPrevEndRow(), loadRange.prevEndRow())) < 0) {
432+
wastedIterations++;
389433
log.trace("{}: Skipping tablet: {}", fmtTid, currTablet.getExtent());
390434
currTablet = tabletIter.next();
391435
}
392436

437+
Duration wastedTime = timer.elapsed();
438+
393439
if (cmp != 0) {
394440
throw new IllegalStateException(
395441
"Unexpected prev end row " + currTablet.getExtent() + " " + loadRange);
@@ -410,6 +456,11 @@ private List<TabletMetadata> findOverlappingTablets(String fmtTid, KeyExtent loa
410456
throw new IllegalStateException("Unexpected end row " + currTablet + " " + loadRange);
411457
}
412458

459+
importTimingStats.wastedIterations += wastedIterations;
460+
importTimingStats.totalWastedTime = importTimingStats.totalWastedTime.plus(wastedTime);
461+
importTimingStats.tabletCount += tablets.size();
462+
importTimingStats.callCount++;
463+
413464
return tablets;
414465
} catch (NoSuchElementException e) {
415466
NoSuchElementException ne2 = new NoSuchElementException(

0 commit comments

Comments
 (0)