Search in sources :

Example 6 with QueryPath

use of org.apache.cassandra.db.filter.QueryPath in project eiger by wlloyd.

the class HintedHandOffManager method deliverHintsToEndpointInternal.

private void deliverHintsToEndpointInternal(InetAddress endpoint) throws IOException, DigestMismatchException, InvalidRequestException, InterruptedException {
    ColumnFamilyStore hintStore = Table.open(Table.SYSTEM_TABLE).getColumnFamilyStore(HINTS_CF);
    if (hintStore.isEmpty())
        // nothing to do, don't confuse users by logging a no-op handoff
        return;
    logger_.debug("Checking remote({}) schema before delivering hints", endpoint);
    int waited;
    try {
        waited = waitForSchemaAgreement(endpoint);
    } catch (TimeoutException e) {
        return;
    }
    // (if we had to wait, then gossiper randomness took care of that for us already.)
    if (waited == 0) {
        // use a 'rounded' sleep interval because of a strange bug with windows: CASSANDRA-3375
        int sleep = FBUtilities.threadLocalRandom().nextInt(2000) * 30;
        logger_.debug("Sleeping {}ms to stagger hint delivery", sleep);
        Thread.sleep(sleep);
    }
    if (!FailureDetector.instance.isAlive(endpoint)) {
        logger_.info("Endpoint {} died before hint delivery, aborting", endpoint);
        return;
    }
    // 1. Get the key of the endpoint we need to handoff
    // 2. For each column, deserialize the mutation and send it to the endpoint
    // 3. Delete the subcolumn if the write was successful
    // 4. Force a flush
    // 5. Do major compaction to clean up all deletes etc.
    // find the hints for the node using its token.
    Token<?> token = StorageService.instance.getTokenMetadata().getToken(endpoint);
    logger_.info("Started hinted handoff for token: {} with IP: {}", token, endpoint);
    ByteBuffer tokenBytes = StorageService.getPartitioner().getTokenFactory().toByteArray(token);
    DecoratedKey<?> epkey = StorageService.getPartitioner().decorateKey(tokenBytes);
    int rowsReplayed = 0;
    ByteBuffer startColumn = ByteBufferUtil.EMPTY_BYTE_BUFFER;
    int pageSize = PAGE_SIZE;
    // read less columns (mutations) per page if they are very large
    if (hintStore.getMeanColumns() > 0) {
        int averageColumnSize = (int) (hintStore.getMeanRowSize() / hintStore.getMeanColumns());
        pageSize = Math.min(PAGE_SIZE, DatabaseDescriptor.getInMemoryCompactionLimit() / averageColumnSize);
        // page size of 1 does not allow actual paging b/c of >= behavior on startColumn
        pageSize = Math.max(2, pageSize);
        logger_.debug("average hinted-row column size is {}; using pageSize of {}", averageColumnSize, pageSize);
    }
    delivery: while (true) {
        QueryFilter filter = QueryFilter.getSliceFilter(epkey, new QueryPath(HINTS_CF), startColumn, ByteBufferUtil.EMPTY_BYTE_BUFFER, false, pageSize);
        ColumnFamily hintsPage = ColumnFamilyStore.removeDeleted(hintStore.getColumnFamily(filter), Integer.MAX_VALUE);
        if (pagingFinished(hintsPage, startColumn))
            break;
        page: for (IColumn hint : hintsPage.getSortedColumns()) {
            startColumn = hint.name();
            for (IColumn subColumn : hint.getSubColumns()) {
                // both 0.8 and 1.0 column names are UTF8 strings, so this check is safe
                if (ByteBufferUtil.string(subColumn.name()).contains(SEPARATOR_08)) {
                    logger_.debug("0.8-style hint found.  This should have been taken care of by purgeIncompatibleHints");
                    deleteHint(tokenBytes, hint.name(), hint.maxTimestamp());
                    continue page;
                }
            }
            IColumn versionColumn = hint.getSubColumn(ByteBufferUtil.bytes("version"));
            IColumn tableColumn = hint.getSubColumn(ByteBufferUtil.bytes("table"));
            IColumn keyColumn = hint.getSubColumn(ByteBufferUtil.bytes("key"));
            IColumn mutationColumn = hint.getSubColumn(ByteBufferUtil.bytes("mutation"));
            assert versionColumn != null;
            assert tableColumn != null;
            assert keyColumn != null;
            assert mutationColumn != null;
            DataInputStream in = new DataInputStream(ByteBufferUtil.inputStream(mutationColumn.value()));
            RowMutation rm = RowMutation.serializer().deserialize(in, ByteBufferUtil.toInt(versionColumn.value()));
            try {
                sendMutation(endpoint, rm);
                deleteHint(tokenBytes, hint.name(), hint.maxTimestamp());
                rowsReplayed++;
            } catch (TimeoutException e) {
                logger_.info(String.format("Timed out replaying hints to %s; aborting further deliveries", endpoint));
                break delivery;
            }
        }
    }
    if (rowsReplayed > 0) {
        try {
            hintStore.forceBlockingFlush();
            CompactionManager.instance.submitMaximal(hintStore, Integer.MAX_VALUE).get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    logger_.info(String.format("Finished hinted handoff of %s rows to endpoint %s", rowsReplayed, endpoint));
}
Also used : DataInputStream(java.io.DataInputStream) ByteBuffer(java.nio.ByteBuffer) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) QueryPath(org.apache.cassandra.db.filter.QueryPath) NamesQueryFilter(org.apache.cassandra.db.filter.NamesQueryFilter) QueryFilter(org.apache.cassandra.db.filter.QueryFilter) TimeoutException(java.util.concurrent.TimeoutException)

Example 7 with QueryPath

use of org.apache.cassandra.db.filter.QueryPath in project eiger by wlloyd.

the class RowMutation method hintFor.

/**
     * Returns mutation representing a Hints to be sent to <code>address</code>
     * as soon as it becomes available.
     * The format is the following:
     *
     * HintsColumnFamily: {        // cf
     *   <dest token>: {           // key
     *     <uuid>: {               // super-column
     *       table: <table>        // columns
     *       key: <key>
     *       mutation: <mutation>
     *       version: <version>
     *     }
     *   }
     * }
     *
     */
public static RowMutation hintFor(RowMutation mutation, ByteBuffer token) throws IOException {
    RowMutation rm = new RowMutation(Table.SYSTEM_TABLE, token);
    ByteBuffer hintId = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes());
    // determine the TTL for the RowMutation
    // this is set at the smallest GCGraceSeconds for any of the CFs in the RM
    // this ensures that deletes aren't "undone" by delivery of an old hint
    int ttl = Integer.MAX_VALUE;
    for (ColumnFamily cf : mutation.getColumnFamilies()) ttl = Math.min(ttl, cf.metadata().getGcGraceSeconds());
    // serialized RowMutation
    QueryPath path = new QueryPath(HintedHandOffManager.HINTS_CF, hintId, ByteBufferUtil.bytes("mutation"));
    rm.add(path, ByteBuffer.wrap(mutation.getSerializedBuffer(MessagingService.version_)), System.currentTimeMillis(), System.currentTimeMillis(), ttl, null);
    // serialization version
    path = new QueryPath(HintedHandOffManager.HINTS_CF, hintId, ByteBufferUtil.bytes("version"));
    rm.add(path, ByteBufferUtil.bytes(MessagingService.version_), System.currentTimeMillis(), System.currentTimeMillis(), ttl, null);
    // table
    path = new QueryPath(HintedHandOffManager.HINTS_CF, hintId, ByteBufferUtil.bytes("table"));
    rm.add(path, ByteBufferUtil.bytes(mutation.getTable()), System.currentTimeMillis(), System.currentTimeMillis(), ttl, null);
    // key
    path = new QueryPath(HintedHandOffManager.HINTS_CF, hintId, ByteBufferUtil.bytes("key"));
    rm.add(path, mutation.key(), System.currentTimeMillis(), System.currentTimeMillis(), ttl, null);
    return rm;
}
Also used : QueryPath(org.apache.cassandra.db.filter.QueryPath) ByteBuffer(java.nio.ByteBuffer)

Example 8 with QueryPath

use of org.apache.cassandra.db.filter.QueryPath in project eiger by wlloyd.

the class SystemTable method removeToken.

/**
     * Remove stored token being used by another node
     */
public static synchronized void removeToken(Token token) {
    IPartitioner p = StorageService.getPartitioner();
    RowMutation rm = new RowMutation(Table.SYSTEM_TABLE, RING_KEY);
    rm.delete(new QueryPath(STATUS_CF, null, p.getTokenFactory().toByteArray(token)), LamportClock.getVersion());
    try {
        rm.apply();
    } catch (IOException e) {
        throw new IOError(e);
    }
    forceBlockingFlush(STATUS_CF);
}
Also used : QueryPath(org.apache.cassandra.db.filter.QueryPath) IOError(java.io.IOError) IOException(java.io.IOException) IPartitioner(org.apache.cassandra.dht.IPartitioner)

Example 9 with QueryPath

use of org.apache.cassandra.db.filter.QueryPath in project eiger by wlloyd.

the class SystemTable method isBootstrapped.

public static boolean isBootstrapped() {
    Table table = Table.open(Table.SYSTEM_TABLE);
    QueryFilter filter = QueryFilter.getNamesFilter(decorate(BOOTSTRAP_KEY), new QueryPath(STATUS_CF), BOOTSTRAP);
    ColumnFamily cf = table.getColumnFamilyStore(STATUS_CF).getColumnFamily(filter);
    if (cf == null)
        return false;
    IColumn c = cf.getColumn(BOOTSTRAP);
    return c.value().get(c.value().position()) == 1;
}
Also used : QueryPath(org.apache.cassandra.db.filter.QueryPath) QueryFilter(org.apache.cassandra.db.filter.QueryFilter)

Example 10 with QueryPath

use of org.apache.cassandra.db.filter.QueryPath in project eiger by wlloyd.

the class SystemTable method getCurrentLocalNodeId.

/**
     * Read the current local node id from the system table or null if no
     * such node id is recorded.
     */
public static NodeId getCurrentLocalNodeId() {
    ByteBuffer id = null;
    Table table = Table.open(Table.SYSTEM_TABLE);
    QueryFilter filter = QueryFilter.getIdentityFilter(decorate(CURRENT_LOCAL_NODE_ID_KEY), new QueryPath(NODE_ID_CF));
    ColumnFamily cf = table.getColumnFamilyStore(NODE_ID_CF).getColumnFamily(filter);
    if (cf != null) {
        // Even though gc_grace==0 on System table, we can have a race where we get back tombstones (see CASSANDRA-2824)
        cf = ColumnFamilyStore.removeDeleted(cf, 0);
        assert cf.getColumnCount() <= 1;
        if (cf.getColumnCount() > 0)
            id = cf.iterator().next().name();
    }
    if (id != null) {
        return NodeId.wrap(id);
    } else {
        return null;
    }
}
Also used : QueryPath(org.apache.cassandra.db.filter.QueryPath) QueryFilter(org.apache.cassandra.db.filter.QueryFilter) ByteBuffer(java.nio.ByteBuffer)

Aggregations

QueryPath (org.apache.cassandra.db.filter.QueryPath)123 Test (org.junit.Test)67 ByteBuffer (java.nio.ByteBuffer)40 QueryFilter (org.apache.cassandra.db.filter.QueryFilter)22 ColumnFamily (org.apache.cassandra.db.ColumnFamily)14 RowMutation (org.apache.cassandra.db.RowMutation)11 File (java.io.File)10 SSTableReader (org.apache.cassandra.io.sstable.SSTableReader)10 IOException (java.io.IOException)8 ColumnFamilyStore (org.apache.cassandra.db.ColumnFamilyStore)8 DecoratedKey (org.apache.cassandra.db.DecoratedKey)8 Table (org.apache.cassandra.db.Table)8 SSTableUtils.tempSSTableFile (org.apache.cassandra.io.sstable.SSTableUtils.tempSSTableFile)8 WrappedRunnable (org.apache.cassandra.utils.WrappedRunnable)8 IColumn (org.apache.cassandra.db.IColumn)6 ArrayList (java.util.ArrayList)5 PrintStream (java.io.PrintStream)4 UnknownHostException (java.net.UnknownHostException)4 HashSet (java.util.HashSet)4 DropColumnFamily (org.apache.cassandra.db.migration.DropColumnFamily)4