Search in sources :

Example 1 with TabletLocation

use of org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation in project accumulo by apache.

the class ThriftScanner method scan.

public static List<KeyValue> scan(ClientContext context, ScanState scanState, long timeOut) throws ScanTimedOutException, AccumuloException, AccumuloSecurityException, TableNotFoundException {
    TabletLocation loc = null;
    long startTime = System.currentTimeMillis();
    String lastError = null;
    String error = null;
    int tooManyFilesCount = 0;
    long sleepMillis = 100;
    final long maxSleepTime = context.getConfiguration().getTimeInMillis(Property.GENERAL_MAX_SCANNER_RETRY_PERIOD);
    List<KeyValue> results = null;
    Span parent = TraceUtil.startSpan(ThriftScanner.class, "scan");
    try (Scope scope = parent.makeCurrent()) {
        while (results == null && !scanState.finished) {
            if (Thread.currentThread().isInterrupted()) {
                throw new AccumuloException("Thread interrupted");
            }
            if ((System.currentTimeMillis() - startTime) / 1000.0 > timeOut)
                throw new ScanTimedOutException();
            while (loc == null) {
                long currentTime = System.currentTimeMillis();
                if ((currentTime - startTime) / 1000.0 > timeOut)
                    throw new ScanTimedOutException();
                Span child1 = TraceUtil.startSpan(ThriftScanner.class, "scan::locateTablet");
                try (Scope locateSpan = child1.makeCurrent()) {
                    loc = TabletLocator.getLocator(context, scanState.tableId).locateTablet(context, scanState.startRow, scanState.skipStartRow, false);
                    if (loc == null) {
                        context.requireNotDeleted(scanState.tableId);
                        context.requireNotOffline(scanState.tableId, null);
                        error = "Failed to locate tablet for table : " + scanState.tableId + " row : " + scanState.startRow;
                        if (!error.equals(lastError))
                            log.debug("{}", error);
                        else if (log.isTraceEnabled())
                            log.trace("{}", error);
                        lastError = error;
                        sleepMillis = pause(sleepMillis, maxSleepTime);
                    } else {
                        // when a tablet splits we do want to continue scanning the low child
                        // of the split if we are already passed it
                        Range dataRange = loc.tablet_extent.toDataRange();
                        if (scanState.range.getStartKey() != null && dataRange.afterEndKey(scanState.range.getStartKey())) {
                            // go to the next tablet
                            scanState.startRow = loc.tablet_extent.endRow();
                            scanState.skipStartRow = true;
                            loc = null;
                        } else if (scanState.range.getEndKey() != null && dataRange.beforeStartKey(scanState.range.getEndKey())) {
                            // should not happen
                            throw new RuntimeException("Unexpected tablet, extent : " + loc.tablet_extent + "  range : " + scanState.range + " startRow : " + scanState.startRow);
                        }
                    }
                } catch (AccumuloServerException e) {
                    TraceUtil.setException(child1, e, true);
                    log.debug("Scan failed, server side exception : {}", e.getMessage());
                    throw e;
                } catch (AccumuloException e) {
                    error = "exception from tablet loc " + e.getMessage();
                    if (!error.equals(lastError))
                        log.debug("{}", error);
                    else if (log.isTraceEnabled())
                        log.trace("{}", error);
                    TraceUtil.setException(child1, e, false);
                    lastError = error;
                    sleepMillis = pause(sleepMillis, maxSleepTime);
                } finally {
                    child1.end();
                }
            }
            Span child2 = TraceUtil.startSpan(ThriftScanner.class, "scan::location", Map.of("tserver", loc.tablet_location));
            try (Scope scanLocation = child2.makeCurrent()) {
                results = scan(loc, scanState, context);
            } catch (AccumuloSecurityException e) {
                context.clearTableListCache();
                context.requireNotDeleted(scanState.tableId);
                e.setTableInfo(context.getPrintableTableInfoFromId(scanState.tableId));
                TraceUtil.setException(child2, e, true);
                throw e;
            } catch (TApplicationException tae) {
                TraceUtil.setException(child2, tae, true);
                throw new AccumuloServerException(loc.tablet_location, tae);
            } catch (TSampleNotPresentException tsnpe) {
                String message = "Table " + context.getPrintableTableInfoFromId(scanState.tableId) + " does not have sampling configured or built";
                TraceUtil.setException(child2, tsnpe, true);
                throw new SampleNotPresentException(message, tsnpe);
            } catch (NotServingTabletException e) {
                error = "Scan failed, not serving tablet " + loc;
                if (!error.equals(lastError))
                    log.debug("{}", error);
                else if (log.isTraceEnabled())
                    log.trace("{}", error);
                lastError = error;
                TabletLocator.getLocator(context, scanState.tableId).invalidateCache(loc.tablet_extent);
                loc = null;
                // no need to try the current scan id somewhere else
                scanState.scanID = null;
                if (scanState.isolated) {
                    TraceUtil.setException(child2, e, true);
                    throw new IsolationException();
                }
                TraceUtil.setException(child2, e, false);
                sleepMillis = pause(sleepMillis, maxSleepTime);
            } catch (NoSuchScanIDException e) {
                error = "Scan failed, no such scan id " + scanState.scanID + " " + loc;
                if (!error.equals(lastError))
                    log.debug("{}", error);
                else if (log.isTraceEnabled())
                    log.trace("{}", error);
                lastError = error;
                if (scanState.isolated) {
                    TraceUtil.setException(child2, e, true);
                    throw new IsolationException();
                }
                TraceUtil.setException(child2, e, false);
                scanState.scanID = null;
            } catch (TooManyFilesException e) {
                error = "Tablet has too many files " + loc + " retrying...";
                if (error.equals(lastError)) {
                    tooManyFilesCount++;
                    if (tooManyFilesCount == 300)
                        log.warn("{}", error);
                    else if (log.isTraceEnabled())
                        log.trace("{}", error);
                } else {
                    log.debug("{}", error);
                    tooManyFilesCount = 0;
                }
                lastError = error;
                // not sure what state the scan session on the server side is
                // in after this occurs, so lets be cautious and start a new
                // scan session
                scanState.scanID = null;
                if (scanState.isolated) {
                    TraceUtil.setException(child2, e, true);
                    throw new IsolationException();
                }
                TraceUtil.setException(child2, e, false);
                sleepMillis = pause(sleepMillis, maxSleepTime);
            } catch (TException e) {
                TabletLocator.getLocator(context, scanState.tableId).invalidateCache(context, loc.tablet_location);
                error = "Scan failed, thrift error " + e.getClass().getName() + "  " + e.getMessage() + " " + loc;
                if (!error.equals(lastError))
                    log.debug("{}", error);
                else if (log.isTraceEnabled())
                    log.trace("{}", error);
                lastError = error;
                loc = null;
                // do not want to continue using the same scan id, if a timeout occurred could cause a
                // batch to be skipped
                // because a thread on the server side may still be processing the timed out continue scan
                scanState.scanID = null;
                if (scanState.isolated) {
                    TraceUtil.setException(child2, e, true);
                    throw new IsolationException();
                }
                TraceUtil.setException(child2, e, false);
                sleepMillis = pause(sleepMillis, maxSleepTime);
            } finally {
                child2.end();
            }
        }
        if (results != null && results.isEmpty() && scanState.finished) {
            results = null;
        }
        return results;
    } catch (InterruptedException ex) {
        TraceUtil.setException(parent, ex, true);
        throw new AccumuloException(ex);
    } finally {
        parent.end();
    }
}
Also used : TException(org.apache.thrift.TException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) TKeyValue(org.apache.accumulo.core.dataImpl.thrift.TKeyValue) KeyValue(org.apache.accumulo.core.data.KeyValue) NotServingTabletException(org.apache.accumulo.core.tabletserver.thrift.NotServingTabletException) TooManyFilesException(org.apache.accumulo.core.tabletserver.thrift.TooManyFilesException) Range(org.apache.accumulo.core.data.Range) Span(io.opentelemetry.api.trace.Span) NoSuchScanIDException(org.apache.accumulo.core.tabletserver.thrift.NoSuchScanIDException) TApplicationException(org.apache.thrift.TApplicationException) TSampleNotPresentException(org.apache.accumulo.core.tabletserver.thrift.TSampleNotPresentException) SampleNotPresentException(org.apache.accumulo.core.client.SampleNotPresentException) Scope(io.opentelemetry.context.Scope) TabletLocation(org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation) TSampleNotPresentException(org.apache.accumulo.core.tabletserver.thrift.TSampleNotPresentException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException)

Example 2 with TabletLocation

use of org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation in project accumulo by apache.

the class MetadataLocationObtainer method lookupTablets.

@Override
public List<TabletLocation> lookupTablets(ClientContext context, String tserver, Map<KeyExtent, List<Range>> tabletsRanges, TabletLocator parent) throws AccumuloSecurityException, AccumuloException {
    final TreeMap<Key, Value> results = new TreeMap<>();
    ResultReceiver rr = entries -> {
        for (Entry<Key, Value> entry : entries) {
            try {
                results.putAll(WholeRowIterator.decodeRow(entry.getKey(), entry.getValue()));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    };
    ScannerOptions opts = null;
    try (SettableScannerOptions unsetOpts = new SettableScannerOptions()) {
        opts = unsetOpts.setColumns(locCols);
    }
    Map<KeyExtent, List<Range>> unscanned = new HashMap<>();
    Map<KeyExtent, List<Range>> failures = new HashMap<>();
    try {
        TabletServerBatchReaderIterator.doLookup(context, tserver, tabletsRanges, failures, unscanned, rr, columns, opts, Authorizations.EMPTY);
        if (!failures.isEmpty()) {
            // invalidate extents in parents cache
            if (log.isTraceEnabled())
                log.trace("lookupTablets failed for {} extents", failures.size());
            parent.invalidateCache(failures.keySet());
        }
    } catch (IOException e) {
        log.trace("lookupTablets failed server={}", tserver, e);
        parent.invalidateCache(context, tserver);
    } catch (AccumuloServerException e) {
        log.trace("lookupTablets failed server={}", tserver, e);
        throw e;
    }
    return MetadataLocationObtainer.getMetadataLocationEntries(results).getLocations();
}
Also used : TabletServerBatchReaderIterator(org.apache.accumulo.core.clientImpl.TabletServerBatchReaderIterator) SortedSet(java.util.SortedSet) TabletLocation(org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation) LoggerFactory(org.slf4j.LoggerFactory) Text(org.apache.hadoop.io.Text) HashMap(java.util.HashMap) ResultReceiver(org.apache.accumulo.core.clientImpl.TabletServerBatchReaderIterator.ResultReceiver) IterInfo(org.apache.accumulo.core.dataImpl.thrift.IterInfo) FutureLocationColumnFamily(org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.FutureLocationColumnFamily) TextUtil(org.apache.accumulo.core.util.TextUtil) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) TabletLocator(org.apache.accumulo.core.clientImpl.TabletLocator) CurrentLocationColumnFamily(org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.CurrentLocationColumnFamily) Map(java.util.Map) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) Key(org.apache.accumulo.core.data.Key) Value(org.apache.accumulo.core.data.Value) ScannerOptions(org.apache.accumulo.core.clientImpl.ScannerOptions) ThriftScanner(org.apache.accumulo.core.clientImpl.ThriftScanner) Logger(org.slf4j.Logger) ClientContext(org.apache.accumulo.core.clientImpl.ClientContext) Column(org.apache.accumulo.core.data.Column) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) IOException(java.io.IOException) Constants(org.apache.accumulo.core.Constants) Authorizations(org.apache.accumulo.core.security.Authorizations) AccumuloException(org.apache.accumulo.core.client.AccumuloException) Range(org.apache.accumulo.core.data.Range) AccumuloServerException(org.apache.accumulo.core.clientImpl.AccumuloServerException) IteratorSetting(org.apache.accumulo.core.client.IteratorSetting) List(java.util.List) TabletLocationObtainer(org.apache.accumulo.core.clientImpl.TabletLocatorImpl.TabletLocationObtainer) OpTimer(org.apache.accumulo.core.util.OpTimer) TreeMap(java.util.TreeMap) Entry(java.util.Map.Entry) TabletLocations(org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocations) TabletColumnFamily(org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily) PartialKey(org.apache.accumulo.core.data.PartialKey) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) SortedMap(java.util.SortedMap) WholeRowIterator(org.apache.accumulo.core.iterators.user.WholeRowIterator) HashMap(java.util.HashMap) IOException(java.io.IOException) TreeMap(java.util.TreeMap) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) AccumuloServerException(org.apache.accumulo.core.clientImpl.AccumuloServerException) Entry(java.util.Map.Entry) Value(org.apache.accumulo.core.data.Value) ArrayList(java.util.ArrayList) List(java.util.List) ScannerOptions(org.apache.accumulo.core.clientImpl.ScannerOptions) Key(org.apache.accumulo.core.data.Key) PartialKey(org.apache.accumulo.core.data.PartialKey) ResultReceiver(org.apache.accumulo.core.clientImpl.TabletServerBatchReaderIterator.ResultReceiver)

Example 3 with TabletLocation

use of org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation in project accumulo by apache.

the class TabletLocatorImplTest method createMetaCacheKE.

static TreeMap<KeyExtent, TabletLocation> createMetaCacheKE(Object... data) {
    TreeMap<KeyExtent, TabletLocation> mcke = new TreeMap<>();
    for (int i = 0; i < data.length; i += 2) {
        KeyExtent ke = (KeyExtent) data[i];
        String loc = (String) data[i + 1];
        mcke.put(ke, new TabletLocation(ke, loc, "1"));
    }
    return mcke;
}
Also used : TabletLocation(org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation) TreeMap(java.util.TreeMap) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent)

Example 4 with TabletLocation

use of org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation in project accumulo by apache.

the class BulkImporter method findOverlappingTablets.

public static List<TabletLocation> findOverlappingTablets(ServerContext context, VolumeManager vm, TabletLocator locator, Path file, Text startRow, Text endRow) throws Exception {
    List<TabletLocation> result = new ArrayList<>();
    Collection<ByteSequence> columnFamilies = Collections.emptyList();
    String filename = file.toString();
    // log.debug(filename + " finding overlapping tablets " + startRow + " -> " + endRow);
    FileSystem fs = vm.getFileSystemByPath(file);
    try (FileSKVIterator reader = FileOperations.getInstance().newReaderBuilder().forFile(filename, fs, fs.getConf(), context.getCryptoService()).withTableConfiguration(context.getConfiguration()).seekToBeginning().build()) {
        Text row = startRow;
        if (row == null)
            row = new Text();
        while (true) {
            // log.debug(filename + " Seeking to row " + row);
            reader.seek(new Range(row, null), columnFamilies, false);
            if (!reader.hasTop()) {
                // log.debug(filename + " not found");
                break;
            }
            row = reader.getTopKey().getRow();
            TabletLocation tabletLocation = locator.locateTablet(context, row, false, true);
            // log.debug(filename + " found row " + row + " at location " + tabletLocation);
            result.add(tabletLocation);
            row = tabletLocation.tablet_extent.endRow();
            if (row != null && (endRow == null || row.compareTo(endRow) < 0)) {
                row = new Text(row);
                row.append(byte0, 0, byte0.length);
            } else
                break;
        }
    }
    // log.debug(filename + " to be sent to " + result);
    return result;
}
Also used : FileSKVIterator(org.apache.accumulo.core.file.FileSKVIterator) TabletLocation(org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation) FileSystem(org.apache.hadoop.fs.FileSystem) ArrayList(java.util.ArrayList) Text(org.apache.hadoop.io.Text) Range(org.apache.accumulo.core.data.Range) ByteSequence(org.apache.accumulo.core.data.ByteSequence)

Example 5 with TabletLocation

use of org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation in project accumulo by apache.

the class BulkImporterTest method testFindOverlappingTablets.

@Test
public void testFindOverlappingTablets() throws Exception {
    MockTabletLocator locator = new MockTabletLocator();
    FileSystem fs = FileSystem.getLocal(new Configuration());
    ServerContext context = MockServerContext.get();
    EasyMock.replay(context);
    String file = "target/testFile.rf";
    fs.delete(new Path(file), true);
    FileSKVWriter writer = FileOperations.getInstance().newWriterBuilder().forFile(file, fs, fs.getConf(), CryptoServiceFactory.newDefaultInstance()).withTableConfiguration(context.getConfiguration()).build();
    writer.startDefaultLocalityGroup();
    Value empty = new Value();
    writer.append(new Key("a", "cf", "cq"), empty);
    writer.append(new Key("a", "cf", "cq1"), empty);
    writer.append(new Key("a", "cf", "cq2"), empty);
    writer.append(new Key("a", "cf", "cq3"), empty);
    writer.append(new Key("a", "cf", "cq4"), empty);
    writer.append(new Key("a", "cf", "cq5"), empty);
    writer.append(new Key("d", "cf", "cq"), empty);
    writer.append(new Key("d", "cf", "cq1"), empty);
    writer.append(new Key("d", "cf", "cq2"), empty);
    writer.append(new Key("d", "cf", "cq3"), empty);
    writer.append(new Key("d", "cf", "cq4"), empty);
    writer.append(new Key("d", "cf", "cq5"), empty);
    writer.append(new Key("dd", "cf", "cq1"), empty);
    writer.append(new Key("ichabod", "cf", "cq"), empty);
    writer.append(new Key("icky", "cf", "cq1"), empty);
    writer.append(new Key("iffy", "cf", "cq2"), empty);
    writer.append(new Key("internal", "cf", "cq3"), empty);
    writer.append(new Key("is", "cf", "cq4"), empty);
    writer.append(new Key("iterator", "cf", "cq5"), empty);
    writer.append(new Key("xyzzy", "cf", "cq"), empty);
    writer.close();
    try (var vm = VolumeManagerImpl.getLocalForTesting("file:///")) {
        List<TabletLocation> overlaps = BulkImporter.findOverlappingTablets(context, vm, locator, new Path(file));
        assertEquals(5, overlaps.size());
        Collections.sort(overlaps);
        assertEquals(new KeyExtent(tableId, new Text("a"), null), overlaps.get(0).tablet_extent);
        assertEquals(new KeyExtent(tableId, new Text("d"), new Text("cm")), overlaps.get(1).tablet_extent);
        assertEquals(new KeyExtent(tableId, new Text("dm"), new Text("d")), overlaps.get(2).tablet_extent);
        assertEquals(new KeyExtent(tableId, new Text("j"), new Text("i")), overlaps.get(3).tablet_extent);
        assertEquals(new KeyExtent(tableId, null, new Text("l")), overlaps.get(4).tablet_extent);
        List<TabletLocation> overlaps2 = BulkImporter.findOverlappingTablets(context, vm, locator, new Path(file), new KeyExtent(tableId, new Text("h"), new Text("b")));
        assertEquals(3, overlaps2.size());
        assertEquals(new KeyExtent(tableId, new Text("d"), new Text("cm")), overlaps2.get(0).tablet_extent);
        assertEquals(new KeyExtent(tableId, new Text("dm"), new Text("d")), overlaps2.get(1).tablet_extent);
        assertEquals(new KeyExtent(tableId, new Text("j"), new Text("i")), overlaps2.get(2).tablet_extent);
        assertEquals(locator.invalidated, 1);
    }
}
Also used : Path(org.apache.hadoop.fs.Path) Configuration(org.apache.hadoop.conf.Configuration) FileSKVWriter(org.apache.accumulo.core.file.FileSKVWriter) Text(org.apache.hadoop.io.Text) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) MockServerContext(org.apache.accumulo.server.MockServerContext) ServerContext(org.apache.accumulo.server.ServerContext) TabletLocation(org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation) FileSystem(org.apache.hadoop.fs.FileSystem) Value(org.apache.accumulo.core.data.Value) Key(org.apache.accumulo.core.data.Key) Test(org.junit.Test)

Aggregations

TabletLocation (org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation)12 KeyExtent (org.apache.accumulo.core.dataImpl.KeyExtent)7 Text (org.apache.hadoop.io.Text)7 ArrayList (java.util.ArrayList)5 TreeMap (java.util.TreeMap)4 AccumuloSecurityException (org.apache.accumulo.core.client.AccumuloSecurityException)4 IOException (java.io.IOException)3 List (java.util.List)3 AccumuloException (org.apache.accumulo.core.client.AccumuloException)3 Key (org.apache.accumulo.core.data.Key)3 Range (org.apache.accumulo.core.data.Range)3 Value (org.apache.accumulo.core.data.Value)3 FileSystem (org.apache.hadoop.fs.FileSystem)3 HashSet (java.util.HashSet)2 Entry (java.util.Map.Entry)2 ExecutorService (java.util.concurrent.ExecutorService)2 TabletLocator (org.apache.accumulo.core.clientImpl.TabletLocator)2 TabletLocations (org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocations)2 ThriftSecurityException (org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException)2 PartialKey (org.apache.accumulo.core.data.PartialKey)2