Search in sources :

Example 31 with Version

use of voldemort.versioning.Version in project voldemort by voldemort.

the class RoutedStoreTest method testReadRepairWithFailuresZZZ.

/**
     * Test to ensure that read repair happens correctly across zones in case of
     * inconsistent writes in a 3 zone cluster.
     * 
     * @throws Exception
     */
@Test
public void testReadRepairWithFailuresZZZ() throws Exception {
    cluster = VoldemortTestConstants.getSixNodeClusterWith3Zones();
    HashMap<Integer, Integer> zoneReplicationFactor = Maps.newHashMap();
    zoneReplicationFactor.put(0, cluster.getNumberOfNodesInZone(0));
    zoneReplicationFactor.put(1, cluster.getNumberOfNodesInZone(0));
    zoneReplicationFactor.put(2, cluster.getNumberOfNodesInZone(0));
    // PR = RR = 6
    // PW = RW = 4
    // Zone Reads = # Zones - 1
    // Zone Writes = 1
    // Threads = 1
    RoutedStore routedStore = getStore(cluster, 6, 4, cluster.getNumberOfZones() - 1, 1, 1, zoneReplicationFactor);
    Store<ByteArray, byte[], byte[]> store = new InconsistencyResolvingStore<ByteArray, byte[], byte[]>(routedStore, new VectorClockInconsistencyResolver<byte[]>());
    BaseStoreRoutingPlan routingPlan = new BaseStoreRoutingPlan(cluster, this.storeDef);
    List<Integer> replicatingNodes = routingPlan.getReplicationNodeList(aKey.get());
    try {
        // Do the initial put with all nodes up
        store.put(aKey, new Versioned<byte[]>(aValue), null);
        List<Version> initialVersions = store.getVersions(aKey);
        assertEquals(6, initialVersions.size());
        Version mainVersion = initialVersions.get(0);
        for (int i = 1; i < initialVersions.size(); i++) {
            assertEquals(mainVersion, initialVersions.get(i));
        }
        // Do another put with all nodes in the zone 0 marked as
        // unavailable. This will force the put to use a different pseudo
        // master than before.
        byte[] anotherValue = "john".getBytes();
        // In this cluster, nodes 0 and 1 are in Zone 0. Mark them
        // unavailable
        recordException(failureDetector, cluster.getNodeById(0));
        recordException(failureDetector, cluster.getNodeById(1));
        Version newVersion = ((VectorClock) mainVersion).clone();
        store.put(aKey, new Versioned<byte[]>(anotherValue, newVersion), null);
        waitForOperationToComplete(500);
        // Mark the nodes in Zone 0 as available and do a get. The Required
        // reads = 4 and Zone count reads = 2 will force the client to read
        // from all the zones and do the essential read repairs.
        recordSuccess(failureDetector, cluster.getNodeById(0));
        recordSuccess(failureDetector, cluster.getNodeById(1));
        List<Versioned<byte[]>> versioneds = store.get(aKey, null);
        assertEquals(1, versioneds.size());
        assertEquals(new ByteArray(anotherValue), new ByteArray(versioneds.get(0).getValue()));
        // Read repairs are done asynchronously, so we sleep for a short
        // period. It may be a good idea to use a synchronous executor
        // service.
        Thread.sleep(500);
        for (Map.Entry<Integer, Store<ByteArray, byte[], byte[]>> innerStoreEntry : routedStore.getInnerStores().entrySet()) {
            // Only look at the nodes in the pref list
            if (replicatingNodes.contains(innerStoreEntry.getKey())) {
                List<Versioned<byte[]>> innerVersioneds = innerStoreEntry.getValue().get(aKey, null);
                assertEquals(1, versioneds.size());
                assertEquals(new ByteArray(anotherValue), new ByteArray(innerVersioneds.get(0).getValue()));
            }
        }
    } catch (VoldemortException ve) {
        fail("Unexpected error occurred : " + ve);
    }
}
Also used : Versioned(voldemort.versioning.Versioned) VectorClock(voldemort.versioning.VectorClock) Store(voldemort.store.Store) SleepyStore(voldemort.store.SleepyStore) StatTrackingStore(voldemort.store.stats.StatTrackingStore) InconsistencyResolvingStore(voldemort.store.versioned.InconsistencyResolvingStore) FailingStore(voldemort.store.FailingStore) FailingReadsStore(voldemort.store.FailingReadsStore) VoldemortException(voldemort.VoldemortException) InconsistencyResolvingStore(voldemort.store.versioned.InconsistencyResolvingStore) Version(voldemort.versioning.Version) ByteArray(voldemort.utils.ByteArray) BaseStoreRoutingPlan(voldemort.routing.BaseStoreRoutingPlan) Map(java.util.Map) HashMap(java.util.HashMap) AbstractByteArrayStoreTest(voldemort.store.AbstractByteArrayStoreTest) Test(org.junit.Test)

Example 32 with Version

use of voldemort.versioning.Version in project voldemort by voldemort.

the class RoutedStoreTest method testZoneRouting.

@Test
public void testZoneRouting() throws Exception {
    cluster = VoldemortTestConstants.getEightNodeClusterWithZones();
    HashMap<Integer, Integer> zoneReplicationFactor = Maps.newHashMap();
    zoneReplicationFactor.put(0, 2);
    zoneReplicationFactor.put(1, 2);
    long start;
    Versioned<byte[]> versioned = new Versioned<byte[]>(new byte[] { 1 });
    // Basic put with zone read = 0, zone write = 0 and timeout < cross-zone
    // latency
    Store<ByteArray, byte[], byte[]> s1 = getStore(cluster, 1, 1, 0, 0, 8, null, Sets.newHashSet(4, 5, 6, 7), zoneReplicationFactor, RoutingStrategyType.ZONE_STRATEGY, SLEEPY_TIME, OPERATION_TIMEOUT, new VoldemortException());
    start = System.nanoTime();
    try {
        s1.put(new ByteArray("test".getBytes()), versioned, null);
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    // Putting extra key to test getAll
    s1.put(new ByteArray("test2".getBytes()), versioned, null);
    start = System.nanoTime();
    try {
        s1.get(new ByteArray("test".getBytes()), null);
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    start = System.nanoTime();
    try {
        List<Version> versions = s1.getVersions(new ByteArray("test".getBytes()));
        for (Version version : versions) {
            assertEquals(version.compare(versioned.getVersion()), Occurred.BEFORE);
        }
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    start = System.nanoTime();
    try {
        s1.delete(new ByteArray("test".getBytes()), versioned.getVersion());
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    // make sure sleepy stores processed the delete before checking,
    // otherwise, we might be bailing
    // out of the test too early for the delete to be processed.
    Thread.sleep(SLEEPY_TIME * 2);
    List<ByteArray> keys = Lists.newArrayList(new ByteArray("test".getBytes()), new ByteArray("test2".getBytes()));
    Map<ByteArray, List<Versioned<byte[]>>> values = s1.getAll(keys, null);
    assertFalse("'test' did not get deleted.", values.containsKey(new ByteArray("test".getBytes())));
    ByteUtils.compare(values.get(new ByteArray("test2".getBytes())).get(0).getValue(), new byte[] { 1 });
    // Basic put with zone read = 1, zone write = 1
    Store<ByteArray, byte[], byte[]> s2 = getStore(cluster, 1, 1, 1, 1, 8, null, Sets.newHashSet(4, 5, 6, 7), zoneReplicationFactor, RoutingStrategyType.ZONE_STRATEGY, SLEEPY_TIME, BANNAGE_PERIOD, new VoldemortException());
    start = System.nanoTime();
    try {
        s2.put(new ByteArray("test".getBytes()), versioned, null);
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " > " + SLEEPY_TIME, elapsed >= SLEEPY_TIME);
    }
    s2.put(new ByteArray("test2".getBytes()), versioned, null);
    try {
        s2.get(new ByteArray("test".getBytes()), null);
        fail("Should have shown exception");
    } catch (InsufficientZoneResponsesException e) {
    /*
             * Why would you want responses from two zones and wait for only one
             * response...
             */
    }
    try {
        s2.getVersions(new ByteArray("test".getBytes()));
        fail("Should have shown exception");
    } catch (InsufficientZoneResponsesException e) {
    /*
             * Why would you want responses from two zones and wait for only one
             * response...
             */
    }
    try {
        s2.delete(new ByteArray("test".getBytes()), null);
    } catch (InsufficientZoneResponsesException e) {
    /*
             * Why would you want responses from two zones and wait for only one
             * response...
             */
    }
    values = s2.getAll(keys, null);
    assertFalse("'test' did not get deleted.", values.containsKey(new ByteArray("test".getBytes())));
    ByteUtils.compare(values.get(new ByteArray("test2".getBytes())).get(0).getValue(), new byte[] { 1 });
    // Basic put with zone read = 0, zone write = 0 and failures in other
    // dc, but should still work
    Store<ByteArray, byte[], byte[]> s3 = getStore(cluster, 1, 1, 0, 0, 8, Sets.newHashSet(4, 5, 6, 7), null, zoneReplicationFactor, RoutingStrategyType.ZONE_STRATEGY, SLEEPY_TIME, BANNAGE_PERIOD, new VoldemortException());
    start = System.nanoTime();
    try {
        s3.put(new ByteArray("test".getBytes()), versioned, null);
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    // Putting extra key to test getAll
    s3.put(new ByteArray("test2".getBytes()), versioned, null);
    start = System.nanoTime();
    try {
        List<Version> versions = s3.getVersions(new ByteArray("test".getBytes()));
        for (Version version : versions) {
            assertEquals(version.compare(versioned.getVersion()), Occurred.BEFORE);
        }
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    start = System.nanoTime();
    try {
        s3.get(new ByteArray("test".getBytes()), null);
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    start = System.nanoTime();
    try {
        s3.delete(new ByteArray("test".getBytes()), versioned.getVersion());
    } finally {
        long elapsed = (System.nanoTime() - start) / Time.NS_PER_MS;
        assertTrue(elapsed + " < " + SLEEPY_TIME, elapsed < SLEEPY_TIME);
    }
    // Basic put with zone read = 1, zone write = 1 and failures in other
    // dc, should not work
    Store<ByteArray, byte[], byte[]> s4 = getStore(cluster, 2, 2, 1, 1, 8, Sets.newHashSet(4, 5, 6, 7), null, zoneReplicationFactor, RoutingStrategyType.ZONE_STRATEGY, SLEEPY_TIME, BANNAGE_PERIOD, new VoldemortException());
    try {
        s4.put(new ByteArray("test".getBytes()), new Versioned<byte[]>(new byte[] { 1 }), null);
        fail("Should have shown exception");
    } catch (InsufficientZoneResponsesException e) {
    /*
             * The other zone is down and you expect a result from both zones
             */
    }
    try {
        s4.getVersions(new ByteArray("test".getBytes()));
        fail("Should have shown exception");
    } catch (InsufficientZoneResponsesException e) {
    /*
             * The other zone is down and you expect a result from both zones
             */
    }
    try {
        s4.get(new ByteArray("test".getBytes()), null);
        fail("Should have shown exception");
    } catch (InsufficientZoneResponsesException e) {
    /*
             * The other zone is down and you expect a result from both zones
             */
    }
    try {
        s4.delete(new ByteArray("test".getBytes()), versioned.getVersion());
        fail("Should have shown exception");
    } catch (InsufficientZoneResponsesException e) {
    /*
             * The other zone is down and you expect a result from both zones
             */
    }
}
Also used : Versioned(voldemort.versioning.Versioned) VoldemortException(voldemort.VoldemortException) Version(voldemort.versioning.Version) InsufficientZoneResponsesException(voldemort.store.InsufficientZoneResponsesException) ByteArray(voldemort.utils.ByteArray) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) AbstractByteArrayStoreTest(voldemort.store.AbstractByteArrayStoreTest) Test(org.junit.Test)

Example 33 with Version

use of voldemort.versioning.Version in project voldemort by voldemort.

the class EndToEndTest method testUnversionedPutReturnVersion.

@Test
public void testUnversionedPutReturnVersion() {
    Version oldVersion = null;
    Version newVersion = null;
    Versioned<String> getVersioned = null;
    String oldValue = null;
    String newValue = null;
    for (int i = 0; i < 5; i++) {
        oldValue = "value" + i;
        newValue = "value" + i + 1;
        oldVersion = storeClient.put("key1", oldValue);
        newVersion = storeClient.put("key1", newValue);
        assertEquals("Version did not advance", Occurred.AFTER, newVersion.compare(oldVersion));
        getVersioned = storeClient.get("key1");
        verifyResults(oldVersion, newVersion, getVersioned, newValue);
    }
}
Also used : Version(voldemort.versioning.Version) Test(org.junit.Test)

Example 34 with Version

use of voldemort.versioning.Version in project voldemort by voldemort.

the class EndToEndTest method testPutReturnVersion.

/**
     * Test the new put that returns the new version
     */
@Test
public void testPutReturnVersion() {
    Version baseVersion = new VectorClock();
    Version oldVersion = null;
    Version newVersion = null;
    Versioned<String> getVersioned = null;
    String oldValue = null;
    String newValue = null;
    for (int i = 0; i < 5; i++) {
        oldValue = "value" + i;
        newValue = "value" + (i + 1);
        oldVersion = storeClient.put("key1", Versioned.value(oldValue, baseVersion));
        newVersion = storeClient.put("key1", Versioned.value(newValue, ((VectorClock) oldVersion).clone()));
        getVersioned = storeClient.get("key1");
        baseVersion = newVersion;
        verifyResults(oldVersion, newVersion, getVersioned, newValue);
    }
}
Also used : Version(voldemort.versioning.Version) VectorClock(voldemort.versioning.VectorClock) Test(org.junit.Test)

Example 35 with Version

use of voldemort.versioning.Version in project voldemort by voldemort.

the class StorageWorkerThread method run.

@Override
public void run() {
    Object message = messageEvent.getMessage();
    boolean fromLocalZone = false;
    if (message instanceof VoldemortStoreRequest) {
        VoldemortStoreRequest storeRequestObject = (VoldemortStoreRequest) message;
        this.requestObject = storeRequestObject.getRequestObject();
        long now = System.currentTimeMillis();
        if (requestObject.getRequestOriginTimeInMs() + requestObject.getRoutingTimeoutInMs() <= now) {
            RestErrorHandler.writeErrorResponse(messageEvent, HttpResponseStatus.REQUEST_TIMEOUT, "current time: " + now + "\torigin time: " + requestObject.getRequestOriginTimeInMs() + "\ttimeout in ms: " + requestObject.getRoutingTimeoutInMs());
            return;
        } else {
            fromLocalZone = isLocalZoneId(storeRequestObject.getZoneId());
            this.store = storeRequestObject.getStore();
            String storeName = store.getName();
            performanceStats = storeStatsMap.get(storeName);
            if (performanceStats == null) {
                // Add to concurrentHashMap
                storeStatsMap.putIfAbsent(storeName, new StoreStats(storeName, aggregatedStoreStats));
                performanceStats = storeStatsMap.get(storeName);
                // Register MBeans for new store performance stats
                if (isJmxEnabled) {
                    JmxUtils.registerMbean(new StoreStatsJmx(performanceStats), JmxUtils.createObjectName(JmxUtils.getPackageName(this.getClass()) + ".store.stats", storeName));
                }
            }
            switch(requestObject.getOperationType()) {
                case VoldemortOpCode.GET_OP_CODE:
                    if (logger.isDebugEnabled()) {
                        logger.debug("Incoming get request");
                    }
                    try {
                        List<Versioned<byte[]>> versionedValues = store.get(requestObject.getKey(), null);
                        // handle non existing key
                        if (versionedValues.size() > 0) {
                            GetResponseSender responseConstructor = new GetResponseSender(messageEvent, requestObject.getKey(), versionedValues, storeName);
                            responseConstructor.sendResponse(performanceStats, fromLocalZone, requestObject.getRequestOriginTimeInMs());
                        } else {
                            logger.error("Error when doing get. Key does not exist");
                            RestErrorHandler.writeErrorResponse(messageEvent, NOT_FOUND, "Key does not exist");
                        }
                    } catch (Exception e) {
                        getErrorHandler.handleExceptions(messageEvent, e);
                    }
                    break;
                case VoldemortOpCode.GET_ALL_OP_CODE:
                    if (logger.isDebugEnabled()) {
                        logger.debug("Incoming get all request");
                    }
                    try {
                        Map<ByteArray, List<Versioned<byte[]>>> keyValuesMap = store.getAll(requestObject.getIterableKeys(), null);
                        // check if there is at least one valid key
                        // before sending response
                        boolean hasAtleastOneValidKey = false;
                        for (List<Versioned<byte[]>> values : keyValuesMap.values()) {
                            if (values.size() > 0) {
                                hasAtleastOneValidKey = true;
                                break;
                            }
                        }
                        if (hasAtleastOneValidKey) {
                            GetAllResponseSender responseConstructor = new GetAllResponseSender(messageEvent, keyValuesMap, storeName);
                            responseConstructor.sendResponse(performanceStats, fromLocalZone, requestObject.getRequestOriginTimeInMs());
                        } else {
                            logger.error("Error when doing getall. Key does not exist or key is null");
                            RestErrorHandler.writeErrorResponse(messageEvent, NOT_FOUND, "Key does not exist or key is null");
                        }
                    } catch (Exception e) {
                        getErrorHandler.handleExceptions(messageEvent, e);
                    }
                    break;
                case VoldemortOpCode.PUT_OP_CODE:
                    if (logger.isDebugEnabled()) {
                        logger.debug("Incoming put request");
                    }
                    try {
                        store.put(requestObject.getKey(), requestObject.getValue(), null);
                        PutResponseSender responseConstructor = new PutResponseSender(messageEvent);
                        responseConstructor.sendResponse(performanceStats, fromLocalZone, requestObject.getRequestOriginTimeInMs());
                    } catch (Exception e) {
                        putErrorHandler.handleExceptions(messageEvent, e);
                    }
                    break;
                case VoldemortOpCode.DELETE_OP_CODE:
                    if (logger.isDebugEnabled()) {
                        logger.debug("Incoming delete request");
                    }
                    try {
                        boolean result = store.delete(requestObject.getKey(), requestObject.getVersion());
                        if (!result) {
                            logger.error("Error when doing delete. Non Existing key/version. Nothing to delete");
                            RestErrorHandler.writeErrorResponse(messageEvent, NOT_FOUND, "Non Existing key/version. Nothing to delete");
                            break;
                        }
                        DeleteResponseSender responseConstructor = new DeleteResponseSender(messageEvent);
                        responseConstructor.sendResponse(performanceStats, fromLocalZone, requestObject.getRequestOriginTimeInMs());
                    } catch (Exception e) {
                        deleteErrorHandler.handleExceptions(messageEvent, e);
                    }
                    break;
                case VoldemortOpCode.GET_VERSION_OP_CODE:
                    if (logger.isDebugEnabled()) {
                        logger.debug("Incoming get version request");
                    }
                    try {
                        List<Version> versions = store.getVersions(requestObject.getKey());
                        // handle non existing key
                        if (versions.size() > 0) {
                            GetVersionResponseSender responseConstructor = new GetVersionResponseSender(messageEvent, requestObject.getKey(), versions, storeName);
                            responseConstructor.sendResponse(performanceStats, fromLocalZone, requestObject.getRequestOriginTimeInMs());
                        } else {
                            logger.error("Error when doing getversion. Key does not exist or key is null");
                            RestErrorHandler.writeErrorResponse(messageEvent, NOT_FOUND, "Key does not exist or key is null");
                        }
                    } catch (Exception e) {
                        getVersionErrorHandler.handleExceptions(messageEvent, e);
                    }
                    break;
                default:
                    // above, the code stops here.
                    return;
            }
        }
    }
}
Also used : PutResponseSender(voldemort.rest.PutResponseSender) StoreStats(voldemort.store.stats.StoreStats) GetResponseSender(voldemort.rest.GetResponseSender) Versioned(voldemort.versioning.Versioned) DeleteResponseSender(voldemort.rest.DeleteResponseSender) GetAllResponseSender(voldemort.rest.GetAllResponseSender) GetVersionResponseSender(voldemort.rest.GetVersionResponseSender) Version(voldemort.versioning.Version) ByteArray(voldemort.utils.ByteArray) List(java.util.List) StoreStatsJmx(voldemort.store.stats.StoreStatsJmx)

Aggregations

Version (voldemort.versioning.Version)35 VectorClock (voldemort.versioning.VectorClock)16 Versioned (voldemort.versioning.Versioned)13 Test (org.junit.Test)11 ByteArray (voldemort.utils.ByteArray)10 VoldemortException (voldemort.VoldemortException)7 ArrayList (java.util.ArrayList)6 AbstractByteArrayStoreTest (voldemort.store.AbstractByteArrayStoreTest)5 HashMap (java.util.HashMap)4 IOException (java.io.IOException)3 List (java.util.List)3 ByteString (com.linkedin.data.ByteString)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 InvalidMetadataException (voldemort.store.InvalidMetadataException)2 Pair (voldemort.utils.Pair)2 ObsoleteVersionException (voldemort.versioning.ObsoleteVersionException)2 ImmutableList (com.google.common.collect.ImmutableList)1 RestException (com.linkedin.r2.message.rest.RestException)1 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)1