Search in sources :

Example 6 with NonblockingStore

use of voldemort.store.nonblockingstore.NonblockingStore in project voldemort by voldemort.

the class PerformParallelRequests method execute.

public void execute(final Pipeline pipeline) {
    List<Node> nodes = pipelineData.getNodes();
    int attempts = Math.min(preferred, nodes.size());
    final Map<Integer, Response<ByteArray, Object>> responses = new ConcurrentHashMap<Integer, Response<ByteArray, Object>>();
    final CountDownLatch latch = new CountDownLatch(attempts);
    if (logger.isTraceEnabled())
        logger.trace("Attempting " + attempts + " " + pipeline.getOperation().getSimpleName() + " operations in parallel for key " + key);
    final AtomicBoolean isResponseProcessed = new AtomicBoolean(false);
    for (int i = 0; i < attempts; i++) {
        final Node node = nodes.get(i);
        pipelineData.incrementNodeIndex();
        final long startMs = logger.isDebugEnabled() ? System.currentTimeMillis() : -1;
        NonblockingStoreCallback callback = new NonblockingStoreCallback() {

            public void requestComplete(Object result, long requestTime) {
                if (logger.isTraceEnabled())
                    logger.trace(pipeline.getOperation().getSimpleName() + " response received (" + requestTime + " ms.) from node " + node.getId() + "for key " + key);
                Response<ByteArray, Object> response = new Response<ByteArray, Object>(node, key, result, requestTime);
                if (logger.isDebugEnabled())
                    logger.debug("Finished " + pipeline.getOperation().getSimpleName() + " for key " + ByteUtils.toHexString(key.get()) + " (keyRef: " + System.identityHashCode(key) + "); started at " + startMs + " took " + requestTime + " ms on node " + node.getId() + "(" + node.getHost() + ")");
                responses.put(node.getId(), response);
                latch.countDown();
                // This reduces the window where an exception is lost
                if (isResponseProcessed.get() && response.getValue() instanceof Exception) {
                    if (response.getValue() instanceof InvalidMetadataException) {
                        pipelineData.reportException((InvalidMetadataException) response.getValue());
                        logger.warn("Received invalid metadata problem after a successful " + pipeline.getOperation().getSimpleName() + " call on node " + node.getId() + ", store '" + pipelineData.getStoreName() + "' for key " + key);
                    } else {
                        handleResponseError(response, pipeline, failureDetector);
                    }
                }
            }
        };
        if (logger.isTraceEnabled())
            logger.trace("Submitting " + pipeline.getOperation().getSimpleName() + " request on node " + node.getId() + " for key " + key);
        NonblockingStore store = nonblockingStores.get(node.getId());
        if (pipeline.getOperation() == Operation.GET)
            store.submitGetRequest(key, transforms, callback, timeoutMs);
        else if (pipeline.getOperation() == Operation.GET_VERSIONS)
            store.submitGetVersionsRequest(key, callback, timeoutMs);
        else
            throw new IllegalStateException(getClass().getName() + " does not support pipeline operation " + pipeline.getOperation());
    }
    try {
        latch.await(timeoutMs, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        if (logger.isEnabledFor(Level.WARN))
            logger.warn(e, e);
    }
    for (Response<ByteArray, Object> response : responses.values()) {
        if (response.getValue() instanceof Exception) {
            if (handleResponseError(response, pipeline, failureDetector))
                return;
        } else {
            pipelineData.incrementSuccesses();
            Response<ByteArray, V> rCast = Utils.uncheckedCast(response);
            pipelineData.getResponses().add(rCast);
            failureDetector.recordSuccess(response.getNode(), response.getRequestTime());
            pipelineData.getZoneResponses().add(response.getNode().getZoneId());
        }
    }
    isResponseProcessed.set(true);
    if (logger.isDebugEnabled())
        logger.debug("GET for key " + ByteUtils.toHexString(key.get()) + " (keyRef: " + System.identityHashCode(key) + "); successes: " + pipelineData.getSuccesses() + " preferred: " + preferred + " required: " + required);
    if (pipelineData.getSuccesses() < required) {
        if (insufficientSuccessesEvent != null) {
            pipeline.addEvent(insufficientSuccessesEvent);
        } else {
            pipelineData.setFatalError(new InsufficientOperationalNodesException(required + " " + pipeline.getOperation().getSimpleName() + "s required, but only " + pipelineData.getSuccesses() + " succeeded", pipelineData.getReplicationSet(), pipelineData.getNodes(), pipelineData.getFailedNodes(), pipelineData.getFailures()));
            pipeline.abort();
        }
    } else {
        if (pipelineData.getZonesRequired() != null) {
            int zonesSatisfied = pipelineData.getZoneResponses().size();
            if (zonesSatisfied >= (pipelineData.getZonesRequired() + 1)) {
                pipeline.addEvent(completeEvent);
            } else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Operation " + pipeline.getOperation().getSimpleName() + "failed due to insufficient zone responses, required " + pipelineData.getZonesRequired() + " obtained " + zonesSatisfied + " " + pipelineData.getZoneResponses() + " for key " + key);
                }
                if (this.insufficientZonesEvent != null) {
                    pipeline.addEvent(this.insufficientZonesEvent);
                } else {
                    pipelineData.setFatalError(new InsufficientZoneResponsesException((pipelineData.getZonesRequired() + 1) + " " + pipeline.getOperation().getSimpleName() + "s required zone, but only " + zonesSatisfied + " succeeded"));
                }
            }
        } else {
            pipeline.addEvent(completeEvent);
        }
    }
}
Also used : NonblockingStore(voldemort.store.nonblockingstore.NonblockingStore) Node(voldemort.cluster.Node) InvalidMetadataException(voldemort.store.InvalidMetadataException) CountDownLatch(java.util.concurrent.CountDownLatch) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) InsufficientZoneResponsesException(voldemort.store.InsufficientZoneResponsesException) InvalidMetadataException(voldemort.store.InvalidMetadataException) Response(voldemort.store.routed.Response) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) NonblockingStoreCallback(voldemort.store.nonblockingstore.NonblockingStoreCallback) InsufficientZoneResponsesException(voldemort.store.InsufficientZoneResponsesException) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) ByteArray(voldemort.utils.ByteArray) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 7 with NonblockingStore

use of voldemort.store.nonblockingstore.NonblockingStore in project voldemort by voldemort.

the class StorageService method registerNodeStores.

/**
     * For server side routing create NodeStore (socketstore) and pass it on to
     * a {@link RebootstrappingStore}.
     * <p>
     * 
     * The {@link RebootstrappingStore} handles invalid-metadata exceptions
     * introduced due to changes in cluster.xml at different nodes.
     * 
     * @param def
     * @param cluster
     * @param localNode
     */
public void registerNodeStores(StoreDefinition def, Cluster cluster, int localNode) {
    Map<Integer, Store<ByteArray, byte[], byte[]>> nodeStores = new HashMap<Integer, Store<ByteArray, byte[], byte[]>>(cluster.getNumberOfNodes());
    Map<Integer, NonblockingStore> nonblockingStores = new HashMap<Integer, NonblockingStore>(cluster.getNumberOfNodes());
    try {
        for (Node node : cluster.getNodes()) {
            Store<ByteArray, byte[], byte[]> store = getNodeStore(def.getName(), node, localNode);
            this.storeRepository.addNodeStore(node.getId(), store);
            nodeStores.put(node.getId(), store);
            NonblockingStore nonblockingStore = routedStoreFactory.toNonblockingStore(store);
            nonblockingStores.put(node.getId(), nonblockingStore);
        }
        Store<ByteArray, byte[], byte[]> store = routedStoreFactory.create(cluster, def, nodeStores, nonblockingStores, null, null, failureDetector, routedStoreConfig);
        store = new RebootstrappingStore(metadata, storeRepository, voldemortConfig, (RoutedStore) store, storeFactory);
        store = new InconsistencyResolvingStore<ByteArray, byte[], byte[]>(store, new VectorClockInconsistencyResolver<byte[]>());
        this.storeRepository.addRoutedStore(store);
    } catch (Exception e) {
        // Roll back
        for (Node node : cluster.getNodes()) this.storeRepository.removeNodeStore(def.getName(), node.getId());
        throw new VoldemortException(e);
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) NonblockingStore(voldemort.store.nonblockingstore.NonblockingStore) Node(voldemort.cluster.Node) InvalidMetadataCheckingStore(voldemort.store.invalidmetadata.InvalidMetadataCheckingStore) RoutedStore(voldemort.store.routed.RoutedStore) RedirectingStore(voldemort.store.rebalancing.RedirectingStore) InconsistencyResolvingStore(voldemort.store.versioned.InconsistencyResolvingStore) RebootstrappingStore(voldemort.store.rebalancing.RebootstrappingStore) NonblockingStore(voldemort.store.nonblockingstore.NonblockingStore) Store(voldemort.store.Store) RetentionEnforcingStore(voldemort.store.retention.RetentionEnforcingStore) LoggingStore(voldemort.store.logging.LoggingStore) StatTrackingStore(voldemort.store.stats.StatTrackingStore) QuotaLimitingStore(voldemort.store.quota.QuotaLimitingStore) MetadataStore(voldemort.store.metadata.MetadataStore) RoutedStore(voldemort.store.routed.RoutedStore) VoldemortException(voldemort.VoldemortException) ConfigurationException(voldemort.utils.ConfigurationException) NoSuchCapabilityException(voldemort.store.NoSuchCapabilityException) DisabledStoreException(voldemort.store.DisabledStoreException) VoldemortException(voldemort.VoldemortException) RebootstrappingStore(voldemort.store.rebalancing.RebootstrappingStore) ByteArray(voldemort.utils.ByteArray) VectorClockInconsistencyResolver(voldemort.versioning.VectorClockInconsistencyResolver)

Example 8 with NonblockingStore

use of voldemort.store.nonblockingstore.NonblockingStore in project voldemort by voldemort.

the class HintedHandoffFailureTest method customSetup.

/**
     * Setup a cluster with 3 nodes, with the following characteristics:
     * 
     * If FAILURE_MODE is FAIL_FIRST_REPLICA_NODE set the first replica store to
     * a sleepy force failing store
     * 
     * If FAILURE_MODE is FAIL_ALL_REPLICAS: set all replicas to sleepy force
     * failing store
     * 
     * Pseudo master : Standard In-memory store (wrapped by Logging store)
     * 
     * In memory slop stores
     * 
     * @param key The ByteArray representation of the key
     * @param failureMode The Failure mode for the replicas
     * 
     * @throws Exception
     */
public List<Integer> customSetup(ByteArray key, FAILURE_MODE failureMode, ReplicaFactor replicaFactor, long sleepTime, long hintDelayTimeMs) throws Exception {
    cluster = getThreeNodeCluster();
    storeDef = getStoreDef(STORE_NAME, replicaFactor, RoutingStrategyType.CONSISTENT_STRATEGY);
    strategy = new RoutingStrategyFactory().updateRoutingStrategy(storeDef, cluster);
    InMemoryStorageEngine<ByteArray, byte[], byte[]> inMemoryStorageEngine = new InMemoryStorageEngine<ByteArray, byte[], byte[]>(STORE_NAME);
    LoggingStore<ByteArray, byte[], byte[]> loggingStore = new LoggingStore<ByteArray, byte[], byte[]>(inMemoryStorageEngine);
    VoldemortException e = new UnreachableStoreException("Node down");
    ForceFailStore<ByteArray, byte[], byte[]> failureStore = new ForceFailStore<ByteArray, byte[], byte[]>(loggingStore, e);
    SleepyStore<ByteArray, byte[], byte[]> sleepyFailureStore = new SleepyStore<ByteArray, byte[], byte[]>(sleepTime, failureStore);
    failureStore.setFail(true);
    List<Integer> failingNodeIdList = Lists.newArrayList();
    List<Node> replicaList = strategy.routeRequest(key.get());
    switch(failureMode) {
        case FAIL_FIRST_REPLICA_NODE:
            failingNodeIdList.add(replicaList.get(1).getId());
            break;
        case FAIL_ALL_REPLICAS:
            for (int nodeId = 1; nodeId < replicaList.size(); nodeId++) {
                failingNodeIdList.add(nodeId);
            }
            break;
    }
    subStores.clear();
    for (int i = 0; i < NUM_NODES_TOTAL; i++) {
        if (failingNodeIdList.contains(i)) {
            subStores.put(i, sleepyFailureStore);
        } else {
            subStores.put(i, loggingStore);
        }
    }
    setFailureDetector(subStores);
    routedStoreThreadPool = Executors.newFixedThreadPool(NUM_THREADS);
    routedStoreFactory = new RoutedStoreFactory(routedStoreThreadPool);
    Map<Integer, NonblockingStore> nonblockingSlopStores = Maps.newHashMap();
    for (Node node : cluster.getNodes()) {
        int nodeId = node.getId();
        SlopStorageEngine slopStorageEngine = new SlopStorageEngine(new InMemoryStorageEngine<ByteArray, byte[], byte[]>(SLOP_STORE_NAME), cluster);
        StorageEngine<ByteArray, Slop, byte[]> storageEngine = slopStorageEngine.asSlopStore();
        nonblockingSlopStores.put(nodeId, routedStoreFactory.toNonblockingStore(slopStorageEngine));
        slopStores.put(nodeId, storageEngine);
    }
    Map<Integer, NonblockingStore> nonblockingStores = Maps.newHashMap();
    for (Map.Entry<Integer, Store<ByteArray, byte[], byte[]>> entry : subStores.entrySet()) nonblockingStores.put(entry.getKey(), routedStoreFactory.toNonblockingStore(entry.getValue()));
    store = new DelayedPutPipelineRoutedStore(subStores, nonblockingStores, slopStores, nonblockingSlopStores, cluster, storeDef, failureDetector, hintDelayTimeMs);
    return failingNodeIdList;
}
Also used : RoutingStrategyFactory(voldemort.routing.RoutingStrategyFactory) Node(voldemort.cluster.Node) Store(voldemort.store.Store) SleepyStore(voldemort.store.SleepyStore) LoggingStore(voldemort.store.logging.LoggingStore) ForceFailStore(voldemort.store.ForceFailStore) NonblockingStore(voldemort.store.nonblockingstore.NonblockingStore) VoldemortException(voldemort.VoldemortException) InMemoryStorageEngine(voldemort.store.memory.InMemoryStorageEngine) ByteArray(voldemort.utils.ByteArray) SlopStorageEngine(voldemort.store.slop.SlopStorageEngine) UnreachableStoreException(voldemort.store.UnreachableStoreException) ForceFailStore(voldemort.store.ForceFailStore) NonblockingStore(voldemort.store.nonblockingstore.NonblockingStore) SleepyStore(voldemort.store.SleepyStore) LoggingStore(voldemort.store.logging.LoggingStore) Slop(voldemort.store.slop.Slop) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 9 with NonblockingStore

use of voldemort.store.nonblockingstore.NonblockingStore in project voldemort by voldemort.

the class HintedHandoff method sendOneAsyncHint.

/**
     * A callback that handles requestComplete event from NIO selector manager
     * Will try any possible nodes and pass itself as callback util all nodes
     * are exhausted
     * 
     * @param slopKey
     * @param slopVersioned
     * @param nodesToTry List of nodes to try to contact. Will become shorter
     *        after each callback
     */
private void sendOneAsyncHint(final ByteArray slopKey, final Versioned<byte[]> slopVersioned, final List<Node> nodesToTry) {
    Node nodeToHostHint = null;
    boolean foundNode = false;
    while (nodesToTry.size() > 0) {
        nodeToHostHint = nodesToTry.remove(0);
        if (!failedNodes.contains(nodeToHostHint) && failureDetector.isAvailable(nodeToHostHint)) {
            foundNode = true;
            break;
        }
    }
    if (!foundNode) {
        Slop slop = slopSerializer.toObject(slopVersioned.getValue());
        logger.error("Trying to send an async hint but used up all nodes. key: " + slop.getKey() + " version: " + slopVersioned.getVersion().toString());
        return;
    }
    final Node node = nodeToHostHint;
    int nodeId = node.getId();
    NonblockingStore nonblockingStore = nonblockingSlopStores.get(nodeId);
    Utils.notNull(nonblockingStore);
    final Long startNs = System.nanoTime();
    NonblockingStoreCallback callback = new NonblockingStoreCallback() {

        @Override
        public void requestComplete(Object result, long requestTime) {
            Slop slop = null;
            boolean loggerDebugEnabled = logger.isDebugEnabled();
            if (loggerDebugEnabled) {
                slop = slopSerializer.toObject(slopVersioned.getValue());
            }
            Response<ByteArray, Object> response = new Response<ByteArray, Object>(node, slopKey, result, requestTime);
            if (response.getValue() instanceof Exception && !(response.getValue() instanceof ObsoleteVersionException)) {
                if (!failedNodes.contains(node))
                    failedNodes.add(node);
                if (response.getValue() instanceof UnreachableStoreException) {
                    UnreachableStoreException use = (UnreachableStoreException) response.getValue();
                    if (loggerDebugEnabled) {
                        logger.debug("Write of key " + slop.getKey() + " for " + slop.getNodeId() + " to node " + node + " failed due to unreachable: " + use.getMessage());
                    }
                    failureDetector.recordException(node, (System.nanoTime() - startNs) / Time.NS_PER_MS, use);
                }
                sendOneAsyncHint(slopKey, slopVersioned, nodesToTry);
            }
            if (loggerDebugEnabled)
                logger.debug("Slop write of key " + slop.getKey() + " for node " + slop.getNodeId() + " to node " + node + " succeeded in " + (System.nanoTime() - startNs) + " ns");
            failureDetector.recordSuccess(node, (System.nanoTime() - startNs) / Time.NS_PER_MS);
        }
    };
    nonblockingStore.submitPutRequest(slopKey, slopVersioned, null, callback, timeoutMs);
}
Also used : NonblockingStore(voldemort.store.nonblockingstore.NonblockingStore) Node(voldemort.cluster.Node) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) UnreachableStoreException(voldemort.store.UnreachableStoreException) Response(voldemort.store.routed.Response) NonblockingStoreCallback(voldemort.store.nonblockingstore.NonblockingStoreCallback) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) ByteArray(voldemort.utils.ByteArray) UnreachableStoreException(voldemort.store.UnreachableStoreException)

Example 10 with NonblockingStore

use of voldemort.store.nonblockingstore.NonblockingStore in project voldemort by voldemort.

the class PipelineRoutedStore method close.

@Override
public void close() {
    VoldemortException exception = null;
    for (NonblockingStore store : nonblockingStores.values()) {
        try {
            store.close();
        } catch (VoldemortException e) {
            exception = e;
        }
    }
    if (this.jmxEnabled) {
        this.stats.unregisterJmxIfRequired();
    }
    if (exception != null)
        throw exception;
    super.close();
}
Also used : NonblockingStore(voldemort.store.nonblockingstore.NonblockingStore) VoldemortException(voldemort.VoldemortException)

Aggregations

NonblockingStore (voldemort.store.nonblockingstore.NonblockingStore)10 ByteArray (voldemort.utils.ByteArray)9 Node (voldemort.cluster.Node)8 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 NonblockingStoreCallback (voldemort.store.nonblockingstore.NonblockingStoreCallback)5 VoldemortException (voldemort.VoldemortException)4 InvalidMetadataException (voldemort.store.InvalidMetadataException)4 Response (voldemort.store.routed.Response)4 CountDownLatch (java.util.concurrent.CountDownLatch)3 InsufficientOperationalNodesException (voldemort.store.InsufficientOperationalNodesException)3 InsufficientZoneResponsesException (voldemort.store.InsufficientZoneResponsesException)3 Store (voldemort.store.Store)3 UnreachableStoreException (voldemort.store.UnreachableStoreException)3 LoggingStore (voldemort.store.logging.LoggingStore)3 Slop (voldemort.store.slop.Slop)3 ObsoleteVersionException (voldemort.versioning.ObsoleteVersionException)3 Map (java.util.Map)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 MetadataStore (voldemort.store.metadata.MetadataStore)2 QuotaExceededException (voldemort.store.quota.QuotaExceededException)2