Search in sources :

Example 6 with ValidationResponse

use of org.apache.cassandra.repair.messages.ValidationResponse in project cassandra by apache.

the class ValidatorTest method testSizeLimiting.

/*
     * Test for CASSANDRA-14096 size limiting. We:
     * 1. Limit the size of a repair session
     * 2. Submit a validation
     * 3. Check that the resulting tree is of limited depth
     */
@Test
public void testSizeLimiting() throws Exception {
    Keyspace ks = Keyspace.open(keyspace);
    ColumnFamilyStore cfs = ks.getColumnFamilyStore(columnFamily);
    cfs.clearUnsafe();
    DatabaseDescriptor.setRepairSessionSpaceInMiB(1);
    // disable compaction while flushing
    cfs.disableAutoCompaction();
    // 2 ** 14 rows would normally use 2^14 leaves, but with only 1 meg we should only use 2^12
    CompactionsTest.populate(keyspace, columnFamily, 0, 1 << 14, 0);
    cfs.forceBlockingFlush();
    assertEquals(1, cfs.getLiveSSTables().size());
    // wait enough to force single compaction
    TimeUnit.SECONDS.sleep(5);
    SSTableReader sstable = cfs.getLiveSSTables().iterator().next();
    UUID repairSessionId = UUIDGen.getTimeUUID();
    final RepairJobDesc desc = new RepairJobDesc(repairSessionId, UUIDGen.getTimeUUID(), cfs.keyspace.getName(), cfs.getTableName(), Collections.singletonList(new Range<>(sstable.first.getToken(), sstable.last.getToken())));
    InetAddressAndPort host = InetAddressAndPort.getByName("127.0.0.2");
    ActiveRepairService.instance.registerParentRepairSession(repairSessionId, host, Collections.singletonList(cfs), desc.ranges, false, ActiveRepairService.UNREPAIRED_SSTABLE, false, PreviewKind.NONE);
    final CompletableFuture<Message> outgoingMessageSink = registerOutgoingMessageSink();
    Validator validator = new Validator(desc, host, 0, true, false, PreviewKind.NONE);
    ValidationManager.instance.submitValidation(cfs, validator);
    Message message = outgoingMessageSink.get(TEST_TIMEOUT, TimeUnit.SECONDS);
    MerkleTrees trees = ((ValidationResponse) message.payload).trees;
    Iterator<Map.Entry<Range<Token>, MerkleTree>> iterator = trees.iterator();
    int numTrees = 0;
    while (iterator.hasNext()) {
        assertEquals(1 << 12, iterator.next().getValue().size(), 0.0);
        numTrees++;
    }
    assertEquals(1, numTrees);
    assertEquals(trees.rowCount(), 1 << 14);
}
Also used : MerkleTrees(org.apache.cassandra.utils.MerkleTrees) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) Message(org.apache.cassandra.net.Message) Token(org.apache.cassandra.dht.Token) Range(org.apache.cassandra.dht.Range) SSTableReader(org.apache.cassandra.io.sstable.format.SSTableReader) ValidationResponse(org.apache.cassandra.repair.messages.ValidationResponse) Keyspace(org.apache.cassandra.db.Keyspace) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) UUID(java.util.UUID) CompactionsTest(org.apache.cassandra.db.compaction.CompactionsTest) Test(org.junit.Test)

Example 7 with ValidationResponse

use of org.apache.cassandra.repair.messages.ValidationResponse in project cassandra by apache.

the class ValidatorTest method testRangeSplittingTreeSizeLimit.

/*
     * Test for CASSANDRA-11390. When there are multiple subranges the trees should
     * automatically size down to make each subrange fit in the provided memory
     * 1. Limit the size of all the trees
     * 2. Submit a validation against more than one range
     * 3. Check that we have the right number and sizes of trees
     */
@Test
public void testRangeSplittingTreeSizeLimit() throws Exception {
    Keyspace ks = Keyspace.open(keyspace);
    ColumnFamilyStore cfs = ks.getColumnFamilyStore(columnFamily);
    cfs.clearUnsafe();
    DatabaseDescriptor.setRepairSessionSpaceInMiB(1);
    // disable compaction while flushing
    cfs.disableAutoCompaction();
    // 2 ** 14 rows would normally use 2^14 leaves, but with only 1 meg we should only use 2^12
    CompactionsTest.populate(keyspace, columnFamily, 0, 1 << 14, 0);
    cfs.forceBlockingFlush();
    assertEquals(1, cfs.getLiveSSTables().size());
    // wait enough to force single compaction
    TimeUnit.SECONDS.sleep(5);
    SSTableReader sstable = cfs.getLiveSSTables().iterator().next();
    UUID repairSessionId = UUIDGen.getTimeUUID();
    List<Range<Token>> ranges = splitHelper(new Range<>(sstable.first.getToken(), sstable.last.getToken()), 2);
    final RepairJobDesc desc = new RepairJobDesc(repairSessionId, UUIDGen.getTimeUUID(), cfs.keyspace.getName(), cfs.getTableName(), ranges);
    InetAddressAndPort host = InetAddressAndPort.getByName("127.0.0.2");
    ActiveRepairService.instance.registerParentRepairSession(repairSessionId, host, Collections.singletonList(cfs), desc.ranges, false, ActiveRepairService.UNREPAIRED_SSTABLE, false, PreviewKind.NONE);
    final CompletableFuture<Message> outgoingMessageSink = registerOutgoingMessageSink();
    Validator validator = new Validator(desc, host, 0, true, false, PreviewKind.NONE);
    ValidationManager.instance.submitValidation(cfs, validator);
    Message message = outgoingMessageSink.get(TEST_TIMEOUT, TimeUnit.SECONDS);
    MerkleTrees trees = ((ValidationResponse) message.payload).trees;
    // Should have 4 trees each with a depth of on average 10 (since each range should have gotten 0.25 mebibytes)
    Iterator<Map.Entry<Range<Token>, MerkleTree>> iterator = trees.iterator();
    int numTrees = 0;
    double totalResolution = 0;
    while (iterator.hasNext()) {
        long size = iterator.next().getValue().size();
        // So it turns out that sstable range estimates are pretty variable, depending on the sampling we can
        // get a wide range of values here. So we just make sure that we're smaller than in the single range
        // case and have the right total size.
        assertTrue(size <= (1 << 11));
        assertTrue(size >= (1 << 9));
        totalResolution += size;
        numTrees += 1;
    }
    assertEquals(trees.rowCount(), 1 << 14);
    assertEquals(4, numTrees);
    // With a single tree and a mebibyte we should had a total resolution of 2^12 leaves; with multiple
    // ranges we should get similar overall resolution, but not more.
    assertTrue(totalResolution > (1 << 11) && totalResolution < (1 << 13));
}
Also used : MerkleTrees(org.apache.cassandra.utils.MerkleTrees) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) Message(org.apache.cassandra.net.Message) Token(org.apache.cassandra.dht.Token) Range(org.apache.cassandra.dht.Range) SSTableReader(org.apache.cassandra.io.sstable.format.SSTableReader) ValidationResponse(org.apache.cassandra.repair.messages.ValidationResponse) Keyspace(org.apache.cassandra.db.Keyspace) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) UUID(java.util.UUID) CompactionsTest(org.apache.cassandra.db.compaction.CompactionsTest) Test(org.junit.Test)

Example 8 with ValidationResponse

use of org.apache.cassandra.repair.messages.ValidationResponse in project cassandra by apache.

the class ActiveRepairService method handleMessage.

public void handleMessage(Message<? extends RepairMessage> message) {
    RepairMessage payload = message.payload;
    RepairJobDesc desc = payload.desc;
    RepairSession session = sessions.get(desc.sessionId);
    if (session == null) {
        if (payload instanceof ValidationResponse) {
            // The trees may be off-heap, and will therefore need to be released.
            ValidationResponse validation = (ValidationResponse) payload;
            MerkleTrees trees = validation.trees;
            // The response from a failed validation won't have any trees.
            if (trees != null)
                trees.release();
        }
        return;
    }
    switch(message.verb()) {
        case VALIDATION_RSP:
            ValidationResponse validation = (ValidationResponse) payload;
            session.validationComplete(desc, message.from(), validation.trees);
            break;
        case SYNC_RSP:
            // one of replica is synced.
            SyncResponse sync = (SyncResponse) payload;
            session.syncComplete(desc, sync.nodes, sync.success, sync.summaries);
            break;
        default:
            break;
    }
}
Also used : RepairMessage(org.apache.cassandra.repair.messages.RepairMessage) MerkleTrees(org.apache.cassandra.utils.MerkleTrees) SyncResponse(org.apache.cassandra.repair.messages.SyncResponse) RepairJobDesc(org.apache.cassandra.repair.RepairJobDesc) ValidationResponse(org.apache.cassandra.repair.messages.ValidationResponse) RepairSession(org.apache.cassandra.repair.RepairSession)

Aggregations

ValidationResponse (org.apache.cassandra.repair.messages.ValidationResponse)8 Range (org.apache.cassandra.dht.Range)5 Token (org.apache.cassandra.dht.Token)5 InetAddressAndPort (org.apache.cassandra.locator.InetAddressAndPort)5 Message (org.apache.cassandra.net.Message)5 ColumnFamilyStore (org.apache.cassandra.db.ColumnFamilyStore)4 CompactionsTest (org.apache.cassandra.db.compaction.CompactionsTest)4 MerkleTrees (org.apache.cassandra.utils.MerkleTrees)4 Test (org.junit.Test)4 UUID (java.util.UUID)3 Keyspace (org.apache.cassandra.db.Keyspace)3 SSTableReader (org.apache.cassandra.io.sstable.format.SSTableReader)3 IOException (java.io.IOException)1 BufferDecoratedKey (org.apache.cassandra.db.BufferDecoratedKey)1 RepairJobDesc (org.apache.cassandra.repair.RepairJobDesc)1 RepairSession (org.apache.cassandra.repair.RepairSession)1 RepairMessage (org.apache.cassandra.repair.messages.RepairMessage)1 SyncResponse (org.apache.cassandra.repair.messages.SyncResponse)1