Search in sources :

Example 6 with Assignment

use of org.apache.accumulo.server.manager.state.Assignment in project accumulo by apache.

the class AssignmentHandler method run.

@Override
public void run() {
    synchronized (server.unopenedTablets) {
        synchronized (server.openingTablets) {
            synchronized (server.onlineTablets) {
                // nothing should be moving between sets, do a sanity
                // check
                Set<KeyExtent> unopenedOverlapping = KeyExtent.findOverlapping(extent, server.unopenedTablets);
                Set<KeyExtent> openingOverlapping = KeyExtent.findOverlapping(extent, server.openingTablets);
                Set<KeyExtent> onlineOverlapping = KeyExtent.findOverlapping(extent, server.onlineTablets.snapshot());
                if (openingOverlapping.contains(extent) || onlineOverlapping.contains(extent)) {
                    return;
                }
                if (!unopenedOverlapping.contains(extent)) {
                    log.info("assignment {} no longer in the unopened set", extent);
                    return;
                }
                if (unopenedOverlapping.size() != 1 || !openingOverlapping.isEmpty() || !onlineOverlapping.isEmpty()) {
                    throw new IllegalStateException("overlaps assigned " + extent + " " + !server.unopenedTablets.contains(extent) + " " + unopenedOverlapping + " " + openingOverlapping + " " + onlineOverlapping);
                }
            }
            server.unopenedTablets.remove(extent);
            server.openingTablets.add(extent);
        }
    }
    // check Metadata table before accepting assignment
    Text locationToOpen = null;
    TabletMetadata tabletMetadata = null;
    boolean canLoad = false;
    try {
        tabletMetadata = server.getContext().getAmple().readTablet(extent);
        canLoad = checkTabletMetadata(extent, server.getTabletSession(), tabletMetadata);
        if (canLoad && tabletMetadata.sawOldPrevEndRow()) {
            KeyExtent fixedExtent = ManagerMetadataUtil.fixSplit(server.getContext(), tabletMetadata, server.getLock());
            synchronized (server.openingTablets) {
                server.openingTablets.remove(extent);
                server.openingTablets.notifyAll();
                // should not be added to unopenedTablets
                if (!KeyExtent.findOverlapping(extent, new TreeSet<>(Arrays.asList(fixedExtent))).contains(fixedExtent)) {
                    throw new IllegalStateException("Fixed split does not overlap " + extent + " " + fixedExtent);
                }
                server.unopenedTablets.add(fixedExtent);
            }
            // split was rolled back... try again
            new AssignmentHandler(server, fixedExtent).run();
            return;
        }
    } catch (Exception e) {
        synchronized (server.openingTablets) {
            server.openingTablets.remove(extent);
            server.openingTablets.notifyAll();
        }
        log.warn("Failed to verify tablet " + extent, e);
        server.enqueueManagerMessage(new TabletStatusMessage(TabletLoadState.LOAD_FAILURE, extent));
        throw new RuntimeException(e);
    }
    if (!canLoad) {
        log.debug("Reporting tablet {} assignment failure: unable to verify Tablet Information", extent);
        synchronized (server.openingTablets) {
            server.openingTablets.remove(extent);
            server.openingTablets.notifyAll();
        }
        server.enqueueManagerMessage(new TabletStatusMessage(TabletLoadState.LOAD_FAILURE, extent));
        return;
    }
    Tablet tablet = null;
    boolean successful = false;
    try {
        server.acquireRecoveryMemory(extent);
        TabletResourceManager trm = server.resourceManager.createTabletResourceManager(extent, server.getTableConfiguration(extent));
        TabletData data = new TabletData(tabletMetadata);
        tablet = new Tablet(server, extent, trm, data);
        // this could cause duplicate data to replay.
        if (tablet.getNumEntriesInMemory() > 0 && !tablet.minorCompactNow(MinorCompactionReason.RECOVERY)) {
            throw new RuntimeException("Minor compaction after recovery fails for " + extent);
        }
        Assignment assignment = new Assignment(extent, server.getTabletSession());
        TabletStateStore.setLocation(server.getContext(), assignment);
        synchronized (server.openingTablets) {
            synchronized (server.onlineTablets) {
                server.openingTablets.remove(extent);
                server.onlineTablets.put(extent, tablet);
                server.openingTablets.notifyAll();
                server.recentlyUnloadedCache.remove(tablet.getExtent());
            }
        }
        // release this reference
        tablet = null;
        successful = true;
    } catch (Exception e) {
        log.warn("exception trying to assign tablet {} {}", extent, locationToOpen, e);
        if (e.getMessage() != null) {
            log.warn("{}", e.getMessage());
        }
        TableId tableId = extent.tableId();
        ProblemReports.getInstance(server.getContext()).report(new ProblemReport(tableId, TABLET_LOAD, extent.getUUID().toString(), server.getClientAddressString(), e));
    } finally {
        server.releaseRecoveryMemory(extent);
    }
    if (successful) {
        server.enqueueManagerMessage(new TabletStatusMessage(TabletLoadState.LOADED, extent));
    } else {
        synchronized (server.unopenedTablets) {
            synchronized (server.openingTablets) {
                server.openingTablets.remove(extent);
                server.unopenedTablets.add(extent);
                server.openingTablets.notifyAll();
            }
        }
        log.warn("failed to open tablet {} reporting failure to manager", extent);
        server.enqueueManagerMessage(new TabletStatusMessage(TabletLoadState.LOAD_FAILURE, extent));
        long reschedule = Math.min((1L << Math.min(32, retryAttempt)) * 1000, MINUTES.toMillis(10));
        log.warn(String.format("rescheduling tablet load in %.2f seconds", reschedule / 1000.));
        this.server.getContext().getScheduledExecutor().schedule(new Runnable() {

            @Override
            public void run() {
                log.info("adding tablet {} back to the assignment pool (retry {})", extent, retryAttempt);
                AssignmentHandler handler = new AssignmentHandler(server, extent, retryAttempt + 1);
                if (extent.isMeta()) {
                    if (extent.isRootTablet()) {
                        Threads.createThread("Root tablet assignment retry", handler).start();
                    } else {
                        server.resourceManager.addMetaDataAssignment(extent, log, handler);
                    }
                } else {
                    server.resourceManager.addAssignment(extent, log, handler);
                }
            }
        }, reschedule, TimeUnit.MILLISECONDS);
    }
}
Also used : TabletResourceManager(org.apache.accumulo.tserver.TabletServerResourceManager.TabletResourceManager) TableId(org.apache.accumulo.core.data.TableId) TabletStatusMessage(org.apache.accumulo.tserver.managermessage.TabletStatusMessage) TabletData(org.apache.accumulo.tserver.tablet.TabletData) Text(org.apache.hadoop.io.Text) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) AccumuloException(org.apache.accumulo.core.client.AccumuloException) Assignment(org.apache.accumulo.server.manager.state.Assignment) ProblemReport(org.apache.accumulo.server.problems.ProblemReport) TabletMetadata(org.apache.accumulo.core.metadata.schema.TabletMetadata) Tablet(org.apache.accumulo.tserver.tablet.Tablet)

Example 7 with Assignment

use of org.apache.accumulo.server.manager.state.Assignment in project accumulo by apache.

the class NullTserver method main.

public static void main(String[] args) throws Exception {
    Opts opts = new Opts();
    opts.parseArgs(NullTserver.class.getName(), args);
    // modify metadata
    int zkTimeOut = (int) DefaultConfiguration.getInstance().getTimeInMillis(Property.INSTANCE_ZK_TIMEOUT);
    var siteConfig = SiteConfiguration.auto();
    ServerContext context = ServerContext.override(siteConfig, opts.iname, opts.keepers, zkTimeOut);
    TransactionWatcher watcher = new TransactionWatcher(context);
    ThriftClientHandler tch = new ThriftClientHandler(context, watcher);
    Processor<Iface> processor = new Processor<>(tch);
    TServerUtils.startTServer(context.getConfiguration(), ThriftServerType.CUSTOM_HS_HA, processor, "NullTServer", "null tserver", 2, ThreadPools.DEFAULT_TIMEOUT_MILLISECS, 1000, 10 * 1024 * 1024, null, null, -1, HostAndPort.fromParts("0.0.0.0", opts.port));
    HostAndPort addr = HostAndPort.fromParts(InetAddress.getLocalHost().getHostName(), opts.port);
    TableId tableId = context.getTableId(opts.tableName);
    // read the locations for the table
    Range tableRange = new KeyExtent(tableId, null, null).toMetaRange();
    List<Assignment> assignments = new ArrayList<>();
    try (var s = new MetaDataTableScanner(context, tableRange, MetadataTable.NAME)) {
        long randomSessionID = opts.port;
        TServerInstance instance = new TServerInstance(addr, randomSessionID);
        while (s.hasNext()) {
            TabletLocationState next = s.next();
            assignments.add(new Assignment(next.extent, instance));
        }
    }
    // point them to this server
    TabletStateStore store = TabletStateStore.getStoreForLevel(DataLevel.USER, context);
    store.setLocations(assignments);
    while (true) {
        sleepUninterruptibly(10, TimeUnit.SECONDS);
    }
}
Also used : TableId(org.apache.accumulo.core.data.TableId) Processor(org.apache.accumulo.core.tabletserver.thrift.TabletClientService.Processor) ArrayList(java.util.ArrayList) TabletStateStore(org.apache.accumulo.server.manager.state.TabletStateStore) TRange(org.apache.accumulo.core.dataImpl.thrift.TRange) TRowRange(org.apache.accumulo.core.dataImpl.thrift.TRowRange) Range(org.apache.accumulo.core.data.Range) TKeyExtent(org.apache.accumulo.core.dataImpl.thrift.TKeyExtent) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) TServerInstance(org.apache.accumulo.core.metadata.TServerInstance) Assignment(org.apache.accumulo.server.manager.state.Assignment) HostAndPort(org.apache.accumulo.core.util.HostAndPort) Iface(org.apache.accumulo.core.tabletserver.thrift.TabletClientService.Iface) TransactionWatcher(org.apache.accumulo.server.zookeeper.TransactionWatcher) ServerContext(org.apache.accumulo.server.ServerContext) MetaDataTableScanner(org.apache.accumulo.server.manager.state.MetaDataTableScanner) TabletLocationState(org.apache.accumulo.core.metadata.TabletLocationState)

Example 8 with Assignment

use of org.apache.accumulo.server.manager.state.Assignment in project accumulo by apache.

the class SplitRecoveryIT method splitPartiallyAndRecover.

private void splitPartiallyAndRecover(ServerContext context, KeyExtent extent, KeyExtent high, KeyExtent low, double splitRatio, SortedMap<StoredTabletFile, DataFileValue> mapFiles, Text midRow, String location, int steps, ServiceLock zl) throws Exception {
    SortedMap<StoredTabletFile, DataFileValue> lowDatafileSizes = new TreeMap<>();
    SortedMap<StoredTabletFile, DataFileValue> highDatafileSizes = new TreeMap<>();
    List<StoredTabletFile> highDatafilesToRemove = new ArrayList<>();
    MetadataTableUtil.splitDatafiles(midRow, splitRatio, new HashMap<>(), mapFiles, lowDatafileSizes, highDatafileSizes, highDatafilesToRemove);
    MetadataTableUtil.splitTablet(high, extent.prevEndRow(), splitRatio, context, zl, Set.of());
    TServerInstance instance = new TServerInstance(location, zl.getSessionId());
    Assignment assignment = new Assignment(high, instance);
    TabletMutator tabletMutator = context.getAmple().mutateTablet(extent);
    tabletMutator.putLocation(assignment.server, LocationType.FUTURE);
    tabletMutator.mutate();
    if (steps >= 1) {
        Map<Long, List<TabletFile>> bulkFiles = getBulkFilesLoaded(context, high);
        ManagerMetadataUtil.addNewTablet(context, low, "lowDir", instance, lowDatafileSizes, bulkFiles, new MetadataTime(0, TimeType.LOGICAL), -1L, -1L, zl);
    }
    if (steps >= 2) {
        MetadataTableUtil.finishSplit(high, highDatafileSizes, highDatafilesToRemove, context, zl);
    }
    TabletMetadata meta = context.getAmple().readTablet(high);
    KeyExtent fixedExtent = ManagerMetadataUtil.fixSplit(context, meta, zl);
    if (steps < 2)
        assertEquals(splitRatio, meta.getSplitRatio(), 0.0);
    if (steps >= 1) {
        assertEquals(high, fixedExtent);
        ensureTabletHasNoUnexpectedMetadataEntries(context, low, lowDatafileSizes);
        ensureTabletHasNoUnexpectedMetadataEntries(context, high, highDatafileSizes);
        Map<Long, ? extends Collection<TabletFile>> lowBulkFiles = getBulkFilesLoaded(context, low);
        Map<Long, ? extends Collection<TabletFile>> highBulkFiles = getBulkFilesLoaded(context, high);
        if (!lowBulkFiles.equals(highBulkFiles)) {
            throw new Exception(" " + lowBulkFiles + " != " + highBulkFiles + " " + low + " " + high);
        }
        if (lowBulkFiles.isEmpty()) {
            throw new Exception(" no bulk files " + low);
        }
    } else {
        assertEquals(extent, fixedExtent);
        ensureTabletHasNoUnexpectedMetadataEntries(context, extent, mapFiles);
    }
}
Also used : DataFileValue(org.apache.accumulo.core.metadata.schema.DataFileValue) ArrayList(java.util.ArrayList) TabletMutator(org.apache.accumulo.core.metadata.schema.Ample.TabletMutator) TreeMap(java.util.TreeMap) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) TServerInstance(org.apache.accumulo.core.metadata.TServerInstance) Assignment(org.apache.accumulo.server.manager.state.Assignment) TabletMetadata(org.apache.accumulo.core.metadata.schema.TabletMetadata) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) List(java.util.List) ArrayList(java.util.ArrayList) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) TabletFile(org.apache.accumulo.core.metadata.TabletFile) MetadataTime(org.apache.accumulo.core.metadata.schema.MetadataTime)

Example 9 with Assignment

use of org.apache.accumulo.server.manager.state.Assignment in project accumulo by apache.

the class MergeStateIT method test.

@Test
public void test() throws Exception {
    ServerContext context = getServerContext();
    try (AccumuloClient accumuloClient = Accumulo.newClient().from(getClientProperties()).build()) {
        accumuloClient.securityOperations().grantTablePermission(accumuloClient.whoami(), MetadataTable.NAME, TablePermission.WRITE);
        BatchWriter bw = accumuloClient.createBatchWriter(MetadataTable.NAME);
        // Create a fake METADATA table with these splits
        String[] splits = { "a", "e", "j", "o", "t", "z" };
        // create metadata for a table "t" with the splits above
        TableId tableId = TableId.of("t");
        Text pr = null;
        for (String s : splits) {
            Text split = new Text(s);
            Mutation prevRow = TabletColumnFamily.createPrevRowMutation(new KeyExtent(tableId, split, pr));
            prevRow.put(CurrentLocationColumnFamily.NAME, new Text("123456"), new Value("127.0.0.1:1234"));
            ChoppedColumnFamily.CHOPPED_COLUMN.put(prevRow, new Value("junk"));
            bw.addMutation(prevRow);
            pr = split;
        }
        // Add the default tablet
        Mutation defaultTablet = TabletColumnFamily.createPrevRowMutation(new KeyExtent(tableId, null, pr));
        defaultTablet.put(CurrentLocationColumnFamily.NAME, new Text("123456"), new Value("127.0.0.1:1234"));
        bw.addMutation(defaultTablet);
        bw.close();
        // Read out the TabletLocationStates
        MockCurrentState state = new MockCurrentState(new MergeInfo(new KeyExtent(tableId, new Text("p"), new Text("e")), MergeInfo.Operation.MERGE));
        // Verify the tablet state: hosted, and count
        TabletStateStore metaDataStateStore = TabletStateStore.getStoreForLevel(DataLevel.USER, context, state);
        int count = 0;
        for (TabletLocationState tss : metaDataStateStore) {
            if (tss != null)
                count++;
        }
        // the normal case is to skip tablets in a good state
        assertEquals(0, count);
        // Create the hole
        // Split the tablet at one end of the range
        Mutation m = TabletColumnFamily.createPrevRowMutation(new KeyExtent(tableId, new Text("t"), new Text("p")));
        TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value("0.5"));
        TabletColumnFamily.OLD_PREV_ROW_COLUMN.put(m, TabletColumnFamily.encodePrevEndRow(new Text("o")));
        update(accumuloClient, m);
        // do the state check
        MergeStats stats = scan(state, metaDataStateStore);
        MergeState newState = stats.nextMergeState(accumuloClient, state);
        assertEquals(MergeState.WAITING_FOR_OFFLINE, newState);
        // unassign the tablets
        try (BatchDeleter deleter = accumuloClient.createBatchDeleter(MetadataTable.NAME, Authorizations.EMPTY, 1000)) {
            deleter.fetchColumnFamily(CurrentLocationColumnFamily.NAME);
            deleter.setRanges(Collections.singletonList(new Range()));
            deleter.delete();
        }
        // now we should be ready to merge but, we have inconsistent metadata
        stats = scan(state, metaDataStateStore);
        assertEquals(MergeState.WAITING_FOR_OFFLINE, stats.nextMergeState(accumuloClient, state));
        // finish the split
        KeyExtent tablet = new KeyExtent(tableId, new Text("p"), new Text("o"));
        m = TabletColumnFamily.createPrevRowMutation(tablet);
        TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value("0.5"));
        update(accumuloClient, m);
        metaDataStateStore.setLocations(Collections.singletonList(new Assignment(tablet, state.someTServer)));
        // onos... there's a new tablet online
        stats = scan(state, metaDataStateStore);
        assertEquals(MergeState.WAITING_FOR_CHOPPED, stats.nextMergeState(accumuloClient, state));
        // chop it
        m = TabletColumnFamily.createPrevRowMutation(tablet);
        ChoppedColumnFamily.CHOPPED_COLUMN.put(m, new Value("junk"));
        update(accumuloClient, m);
        stats = scan(state, metaDataStateStore);
        assertEquals(MergeState.WAITING_FOR_OFFLINE, stats.nextMergeState(accumuloClient, state));
        // take it offline
        m = TabletColumnFamily.createPrevRowMutation(tablet);
        Collection<Collection<String>> walogs = Collections.emptyList();
        metaDataStateStore.unassign(Collections.singletonList(new TabletLocationState(tablet, null, state.someTServer, null, null, walogs, false)), null);
        // now we can split
        stats = scan(state, metaDataStateStore);
        assertEquals(MergeState.MERGING, stats.nextMergeState(accumuloClient, state));
    }
}
Also used : AccumuloClient(org.apache.accumulo.core.client.AccumuloClient) TableId(org.apache.accumulo.core.data.TableId) MergeInfo(org.apache.accumulo.server.manager.state.MergeInfo) BatchDeleter(org.apache.accumulo.core.client.BatchDeleter) MergeState(org.apache.accumulo.server.manager.state.MergeState) Text(org.apache.hadoop.io.Text) TabletStateStore(org.apache.accumulo.server.manager.state.TabletStateStore) Range(org.apache.accumulo.core.data.Range) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) Assignment(org.apache.accumulo.server.manager.state.Assignment) ServerContext(org.apache.accumulo.server.ServerContext) Value(org.apache.accumulo.core.data.Value) MergeStats(org.apache.accumulo.manager.state.MergeStats) TabletLocationState(org.apache.accumulo.core.metadata.TabletLocationState) Collection(java.util.Collection) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Mutation(org.apache.accumulo.core.data.Mutation) Test(org.junit.Test)

Aggregations

Assignment (org.apache.accumulo.server.manager.state.Assignment)9 TServerInstance (org.apache.accumulo.core.metadata.TServerInstance)6 KeyExtent (org.apache.accumulo.core.dataImpl.KeyExtent)5 TableId (org.apache.accumulo.core.data.TableId)4 TabletLocationState (org.apache.accumulo.core.metadata.TabletLocationState)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 TreeMap (java.util.TreeMap)2 AccumuloException (org.apache.accumulo.core.client.AccumuloException)2 Range (org.apache.accumulo.core.data.Range)2 TabletMetadata (org.apache.accumulo.core.metadata.schema.TabletMetadata)2 MergeStats (org.apache.accumulo.manager.state.MergeStats)2 ServerContext (org.apache.accumulo.server.ServerContext)2 TServerConnection (org.apache.accumulo.server.manager.LiveTServerSet.TServerConnection)2 MergeInfo (org.apache.accumulo.server.manager.state.MergeInfo)2 TabletStateStore (org.apache.accumulo.server.manager.state.TabletStateStore)2 Text (org.apache.hadoop.io.Text)2 IOException (java.io.IOException)1 Collection (java.util.Collection)1 List (java.util.List)1