Search in sources :

Example 11 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class PipelineRoutedStore method getAll.

public Map<ByteArray, List<Versioned<byte[]>>> getAll(Iterable<ByteArray> keys, Map<ByteArray, byte[]> transforms, long getAllOpTimeoutInMs) throws VoldemortException {
    StoreUtils.assertValidKeys(keys);
    long startTimeMs = -1;
    long startTimeNs = -1;
    if (logger.isDebugEnabled()) {
        startTimeMs = System.currentTimeMillis();
        startTimeNs = System.nanoTime();
    }
    boolean allowReadRepair = repairReads && (transforms == null || transforms.size() == 0);
    GetAllPipelineData pipelineData = new GetAllPipelineData();
    if (zoneRoutingEnabled)
        pipelineData.setZonesRequired(storeDef.getZoneCountReads());
    else
        pipelineData.setZonesRequired(null);
    pipelineData.setStats(stats);
    Pipeline pipeline = new Pipeline(Operation.GET_ALL, getAllOpTimeoutInMs, TimeUnit.MILLISECONDS);
    pipeline.addEventAction(Event.STARTED, new GetAllConfigureNodes(pipelineData, Event.CONFIGURED, failureDetector, storeDef.getPreferredReads(), storeDef.getRequiredReads(), routingStrategy, keys, transforms, clientZone, zoneAffinity));
    pipeline.addEventAction(Event.CONFIGURED, new PerformParallelGetAllRequests(pipelineData, Event.INSUFFICIENT_SUCCESSES, failureDetector, getAllOpTimeoutInMs, nonblockingStores));
    pipeline.addEventAction(Event.INSUFFICIENT_SUCCESSES, new PerformSerialGetAllRequests(pipelineData, allowReadRepair ? Event.RESPONSES_RECEIVED : Event.COMPLETED, keys, failureDetector, innerStores, storeDef.getPreferredReads(), storeDef.getRequiredReads(), timeoutConfig.isPartialGetAllAllowed()));
    if (allowReadRepair)
        pipeline.addEventAction(Event.RESPONSES_RECEIVED, new GetAllReadRepair(pipelineData, Event.COMPLETED, storeDef.getPreferredReads(), getAllOpTimeoutInMs, nonblockingStores, readRepairer));
    pipeline.addEvent(Event.STARTED);
    if (logger.isDebugEnabled()) {
        StringBuilder keyStr = new StringBuilder();
        for (ByteArray key : keys) {
            keyStr.append(ByteUtils.toHexString(key.get()) + ",");
        }
        logger.debug("Operation " + pipeline.getOperation().getSimpleName() + " Keys " + keyStr.toString());
    }
    try {
        pipeline.execute();
    } catch (VoldemortException e) {
        stats.reportException(e);
        throw e;
    }
    if (pipelineData.getFatalError() != null)
        throw pipelineData.getFatalError();
    if (logger.isDebugEnabled()) {
        logger.debug("Finished " + pipeline.getOperation().getSimpleName() + "for keys " + ByteArray.toHexStrings(keys) + " keyRef: " + System.identityHashCode(keys) + "; started at " + startTimeMs + " took " + (System.nanoTime() - startTimeNs) + " values: " + formatNodeValuesFromGetAll(pipelineData.getResponses()));
    }
    return pipelineData.getResult();
}
Also used : GetAllReadRepair(voldemort.store.routed.action.GetAllReadRepair) PerformSerialGetAllRequests(voldemort.store.routed.action.PerformSerialGetAllRequests) GetAllConfigureNodes(voldemort.store.routed.action.GetAllConfigureNodes) ByteArray(voldemort.utils.ByteArray) PerformParallelGetAllRequests(voldemort.store.routed.action.PerformParallelGetAllRequests) VoldemortException(voldemort.VoldemortException)

Example 12 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class ThreadPoolRoutedStore method getAll.

@Override
public Map<ByteArray, List<Versioned<byte[]>>> getAll(Iterable<ByteArray> keys, Map<ByteArray, byte[]> transforms) throws VoldemortException {
    StoreUtils.assertValidKeys(keys);
    Map<ByteArray, List<Versioned<byte[]>>> result = StoreUtils.newEmptyHashMap(keys);
    // Keys for each node needed to satisfy storeDef.getPreferredReads() if
    // no failures.
    Map<Node, List<ByteArray>> nodeToKeysMap = Maps.newHashMap();
    // Keep track of nodes per key that might be needed if there are
    // failures during getAll
    Map<ByteArray, List<Node>> keyToExtraNodesMap = Maps.newHashMap();
    for (ByteArray key : keys) {
        List<Node> availableNodes = availableNodes(routingStrategy.routeRequest(key.get()));
        // quickly fail if there aren't enough nodes to meet the requirement
        checkRequiredReads(availableNodes);
        int preferredReads = storeDef.getPreferredReads();
        List<Node> preferredNodes = Lists.newArrayListWithCapacity(preferredReads);
        List<Node> extraNodes = Lists.newArrayListWithCapacity(3);
        for (Node node : availableNodes) {
            if (preferredNodes.size() < preferredReads)
                preferredNodes.add(node);
            else
                extraNodes.add(node);
        }
        for (Node node : preferredNodes) {
            List<ByteArray> nodeKeys = nodeToKeysMap.get(node);
            if (nodeKeys == null) {
                nodeKeys = Lists.newArrayList();
                nodeToKeysMap.put(node, nodeKeys);
            }
            nodeKeys.add(key);
        }
        if (!extraNodes.isEmpty()) {
            List<Node> nodes = keyToExtraNodesMap.get(key);
            if (nodes == null)
                keyToExtraNodesMap.put(key, extraNodes);
            else
                nodes.addAll(extraNodes);
        }
    }
    List<Callable<GetAllResult>> callables = Lists.newArrayList();
    for (Map.Entry<Node, List<ByteArray>> entry : nodeToKeysMap.entrySet()) {
        final Node node = entry.getKey();
        final Collection<ByteArray> nodeKeys = entry.getValue();
        if (failureDetector.isAvailable(node))
            callables.add(new GetAllCallable(node, nodeKeys, transforms));
    }
    // A list of thrown exceptions, indicating the number of failures
    List<Throwable> failures = new CopyOnWriteArrayList<Throwable>();
    List<NodeValue<ByteArray, byte[]>> nodeValues = Lists.newArrayList();
    Map<ByteArray, MutableInt> keyToSuccessCount = Maps.newHashMap();
    for (ByteArray key : keys) keyToSuccessCount.put(key, new MutableInt(0));
    List<Future<GetAllResult>> futures;
    long timeoutMs = timeoutConfig.getOperationTimeout(VoldemortOpCode.GET_ALL_OP_CODE);
    try {
        // TODO What to do about timeouts? They should be longer as getAll
        // is likely to
        // take longer. At the moment, it's just timeoutMs * 3, but should
        // this be based on the number of the keys?
        futures = executor.invokeAll(callables, timeoutMs * 3, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        throw new InsufficientOperationalNodesException("getAll operation interrupted.", e);
    }
    for (Future<GetAllResult> f : futures) {
        if (f.isCancelled()) {
            logger.warn("Get operation timed out after " + timeoutMs + " ms.");
            continue;
        }
        try {
            GetAllResult getResult = f.get();
            if (getResult.exception != null) {
                if (getResult.exception instanceof VoldemortApplicationException) {
                    throw (VoldemortException) getResult.exception;
                }
                failures.add(getResult.exception);
                continue;
            }
            for (ByteArray key : getResult.callable.nodeKeys) {
                List<Versioned<byte[]>> retrieved = getResult.retrieved.get(key);
                MutableInt successCount = keyToSuccessCount.get(key);
                successCount.increment();
                /*
                     * retrieved can be null if there are no values for the key
                     * provided
                     */
                if (retrieved != null) {
                    List<Versioned<byte[]>> existing = result.get(key);
                    if (existing == null)
                        result.put(key, Lists.newArrayList(retrieved));
                    else
                        existing.addAll(retrieved);
                }
            }
            nodeValues.addAll(getResult.nodeValues);
        } catch (InterruptedException e) {
            throw new InsufficientOperationalNodesException("getAll operation interrupted.", e);
        } catch (ExecutionException e) {
            // should never happen
            if (e.getCause() instanceof Error)
                throw (Error) e.getCause();
            else
                logger.error(e.getMessage(), e);
        }
    }
    for (ByteArray key : keys) {
        MutableInt successCountWrapper = keyToSuccessCount.get(key);
        int successCount = successCountWrapper.intValue();
        if (successCount < storeDef.getPreferredReads()) {
            List<Node> extraNodes = keyToExtraNodesMap.get(key);
            if (extraNodes != null) {
                for (Node node : extraNodes) {
                    long startNs = System.nanoTime();
                    try {
                        List<Versioned<byte[]>> values = innerStores.get(node.getId()).get(key, transforms == null ? null : transforms.get(key));
                        fillRepairReadsValues(nodeValues, key, node, values);
                        List<Versioned<byte[]>> versioneds = result.get(key);
                        if (versioneds == null)
                            result.put(key, Lists.newArrayList(values));
                        else
                            versioneds.addAll(values);
                        recordSuccess(node, startNs);
                        if (++successCount >= storeDef.getPreferredReads())
                            break;
                    } catch (UnreachableStoreException e) {
                        failures.add(e);
                        recordException(node, startNs, e);
                    } catch (VoldemortApplicationException e) {
                        throw e;
                    } catch (Exception e) {
                        logger.warn("Error in GET_ALL on node " + node.getId() + "(" + node.getHost() + ")", e);
                        failures.add(e);
                    }
                }
            }
        }
        successCountWrapper.setValue(successCount);
    }
    repairReads(nodeValues, repairReads && (transforms == null || transforms.size() == 0));
    for (Map.Entry<ByteArray, MutableInt> mapEntry : keyToSuccessCount.entrySet()) {
        int successCount = mapEntry.getValue().intValue();
        if (successCount < storeDef.getRequiredReads())
            throw new InsufficientOperationalNodesException(this.storeDef.getRequiredReads() + " reads required, but " + successCount + " succeeded.", failures);
    }
    return result;
}
Also used : Versioned(voldemort.versioning.Versioned) Node(voldemort.cluster.Node) VoldemortException(voldemort.VoldemortException) Callable(java.util.concurrent.Callable) ByteArray(voldemort.utils.ByteArray) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) UnreachableStoreException(voldemort.store.UnreachableStoreException) ExecutionException(java.util.concurrent.ExecutionException) VoldemortApplicationException(voldemort.VoldemortApplicationException) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) VoldemortException(voldemort.VoldemortException) VoldemortApplicationException(voldemort.VoldemortApplicationException) UnreachableStoreException(voldemort.store.UnreachableStoreException) ExecutionException(java.util.concurrent.ExecutionException) MutableInt(org.apache.commons.lang.mutable.MutableInt) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) Future(java.util.concurrent.Future) Map(java.util.Map) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 13 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class ThreadPoolRoutedStore method delete.

@Override
public boolean delete(final ByteArray key, final Version version) throws VoldemortException {
    StoreUtils.assertValidKey(key);
    final List<Node> nodes = availableNodes(routingStrategy.routeRequest(key.get()));
    // quickly fail if there aren't enough live nodes to meet the
    // requirements
    final int numNodes = nodes.size();
    if (numNodes < this.storeDef.getRequiredWrites())
        throw new InsufficientOperationalNodesException("Only " + numNodes + " nodes in preference list, but " + this.storeDef.getRequiredWrites() + " writes required.");
    // A count of the number of successful operations
    final AtomicInteger successes = new AtomicInteger(0);
    final AtomicBoolean deletedSomething = new AtomicBoolean(false);
    // A list of thrown exceptions, indicating the number of failures
    final List<Exception> failures = new CopyOnWriteArrayList<Exception>();
    // A semaphore indicating the number of completed operations
    // Once inititialized all permits are acquired, after that
    // permits are released when an operation is completed.
    // semaphore.acquire(n) waits for n operations to complete
    final Semaphore semaphore = new Semaphore(0, false);
    // Add the operations to the pool
    for (final Node node : nodes) {
        this.executor.execute(new Runnable() {

            @Override
            public void run() {
                long startNs = System.nanoTime();
                try {
                    boolean deleted = innerStores.get(node.getId()).delete(key, version);
                    successes.incrementAndGet();
                    deletedSomething.compareAndSet(false, deleted);
                    recordSuccess(node, startNs);
                } catch (UnreachableStoreException e) {
                    failures.add(e);
                    recordException(node, startNs, e);
                } catch (VoldemortApplicationException e) {
                    throw e;
                } catch (Exception e) {
                    failures.add(e);
                    logger.warn("Error in DELETE on node " + node.getId() + "(" + node.getHost() + ")", e);
                } finally {
                    // signal that the operation is complete
                    semaphore.release();
                }
            }
        });
    }
    int attempts = Math.min(storeDef.getPreferredWrites(), numNodes);
    if (this.storeDef.getPreferredWrites() <= 0) {
        return true;
    } else {
        for (int i = 0; i < numNodes; i++) {
            try {
                long timeoutMs = timeoutConfig.getOperationTimeout(VoldemortOpCode.DELETE_OP_CODE);
                boolean acquired = semaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
                if (!acquired)
                    logger.warn("Delete operation timed out waiting for operation " + i + " to complete after waiting " + timeoutMs + " ms.");
                // completed, were they successful?
                if (successes.get() >= attempts)
                    return deletedSomething.get();
            } catch (InterruptedException e) {
                throw new InsufficientOperationalNodesException("Delete operation interrupted!", e);
            }
        }
    }
    // number
    if (successes.get() < storeDef.getRequiredWrites())
        throw new InsufficientOperationalNodesException(this.storeDef.getRequiredWrites() + " deletes required, but " + successes.get() + " succeeded.", failures);
    else
        return deletedSomething.get();
}
Also used : VoldemortApplicationException(voldemort.VoldemortApplicationException) Node(voldemort.cluster.Node) Semaphore(java.util.concurrent.Semaphore) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) VoldemortException(voldemort.VoldemortException) VoldemortApplicationException(voldemort.VoldemortApplicationException) UnreachableStoreException(voldemort.store.UnreachableStoreException) ExecutionException(java.util.concurrent.ExecutionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) UnreachableStoreException(voldemort.store.UnreachableStoreException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 14 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class ThreadPoolRoutedStore method get.

/*
     * 1. Attempt preferredReads, and then wait for these to complete 2. If we
     * got all the reads we wanted, then we are done. 3. If not then continue
     * serially attempting to read from each node until we get preferredReads or
     * run out of nodes. 4. If we have multiple results do a read repair 5. If
     * we have at least requiredReads return. Otherwise throw an exception.
     */
private <R> List<R> get(final ByteArray key, final byte[] transforms, StoreOp<R> fetcher, Function<List<GetResult<R>>, Void> preReturnProcedure) throws VoldemortException {
    StoreUtils.assertValidKey(key);
    final List<Node> nodes = availableNodes(routingStrategy.routeRequest(key.get()));
    // quickly fail if there aren't enough nodes to meet the requirement
    checkRequiredReads(nodes);
    final List<GetResult<R>> retrieved = Lists.newArrayList();
    // A count of the number of successful operations
    int successes = 0;
    // A list of thrown exceptions, indicating the number of failures
    final List<Throwable> failures = new CopyOnWriteArrayList<Throwable>();
    // Do the preferred number of reads in parallel
    int attempts = Math.min(this.storeDef.getPreferredReads(), nodes.size());
    int nodeIndex = 0;
    List<Callable<GetResult<R>>> callables = Lists.newArrayListWithCapacity(attempts);
    for (; nodeIndex < attempts; nodeIndex++) {
        final Node node = nodes.get(nodeIndex);
        callables.add(new GetCallable<R>(node, key, transforms, fetcher));
    }
    List<Future<GetResult<R>>> futures;
    long timeoutMs = (fetcher == VERSION_OP) ? timeoutConfig.getOperationTimeout(VoldemortOpCode.GET_VERSION_OP_CODE) : timeoutConfig.getOperationTimeout(VoldemortOpCode.GET_OP_CODE);
    try {
        futures = executor.invokeAll(callables, timeoutMs, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        throw new InsufficientOperationalNodesException("Get operation interrupted!", e);
    }
    for (Future<GetResult<R>> f : futures) {
        if (f.isCancelled()) {
            logger.warn("Get operation timed out after " + timeoutMs + " ms.");
            continue;
        }
        try {
            GetResult<R> getResult = f.get();
            if (getResult.exception != null) {
                if (getResult.exception instanceof VoldemortApplicationException) {
                    throw (VoldemortException) getResult.exception;
                }
                failures.add(getResult.exception);
                continue;
            }
            ++successes;
            retrieved.add(getResult);
        } catch (InterruptedException e) {
            throw new InsufficientOperationalNodesException("Get operation interrupted!", e);
        } catch (ExecutionException e) {
            // part should never happen.
            if (e.getCause() instanceof Error)
                throw (Error) e.getCause();
            else
                logger.error(e.getMessage(), e);
        }
    }
    // reads to make up for these.
    while (successes < this.storeDef.getPreferredReads() && nodeIndex < nodes.size()) {
        Node node = nodes.get(nodeIndex);
        long startNs = System.nanoTime();
        try {
            retrieved.add(new GetResult<R>(node, key, fetcher.execute(innerStores.get(node.getId()), key, transforms), null));
            ++successes;
            recordSuccess(node, startNs);
        } catch (UnreachableStoreException e) {
            failures.add(e);
            recordException(node, startNs, e);
        } catch (VoldemortApplicationException e) {
            throw e;
        } catch (Exception e) {
            logger.warn("Error in GET on node " + node.getId() + "(" + node.getHost() + ")", e);
            failures.add(e);
        }
        nodeIndex++;
    }
    if (logger.isTraceEnabled())
        logger.trace("GET retrieved the following node values: " + formatNodeValues(retrieved));
    if (preReturnProcedure != null)
        preReturnProcedure.apply(retrieved);
    if (successes >= this.storeDef.getRequiredReads()) {
        List<R> result = Lists.newArrayListWithExpectedSize(retrieved.size());
        for (GetResult<R> getResult : retrieved) result.addAll(getResult.retrieved);
        return result;
    } else
        throw new InsufficientOperationalNodesException(this.storeDef.getRequiredReads() + " reads required, but " + successes + " succeeded.", failures);
}
Also used : Node(voldemort.cluster.Node) VoldemortException(voldemort.VoldemortException) Callable(java.util.concurrent.Callable) UnreachableStoreException(voldemort.store.UnreachableStoreException) ExecutionException(java.util.concurrent.ExecutionException) VoldemortApplicationException(voldemort.VoldemortApplicationException) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) VoldemortException(voldemort.VoldemortException) VoldemortApplicationException(voldemort.VoldemortApplicationException) UnreachableStoreException(voldemort.store.UnreachableStoreException) ExecutionException(java.util.concurrent.ExecutionException) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) Future(java.util.concurrent.Future) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 15 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class RocksDbStorageEngine method truncate.

@Override
public void truncate() {
    try {
        rocksDB.dropColumnFamily(storeHandle);
        storeHandle.dispose();
        storeHandle = rocksDB.createColumnFamily(new ColumnFamilyDescriptor(getName().getBytes(), storeOptions));
    } catch (RocksDBException e) {
        throw new VoldemortException("Failed to truncate DB", e);
    }
}
Also used : RocksDBException(org.rocksdb.RocksDBException) ColumnFamilyDescriptor(org.rocksdb.ColumnFamilyDescriptor) VoldemortException(voldemort.VoldemortException)

Aggregations

VoldemortException (voldemort.VoldemortException)247 IOException (java.io.IOException)63 ByteArray (voldemort.utils.ByteArray)52 File (java.io.File)46 Node (voldemort.cluster.Node)42 StoreDefinition (voldemort.store.StoreDefinition)39 Versioned (voldemort.versioning.Versioned)38 ArrayList (java.util.ArrayList)34 Test (org.junit.Test)30 ObsoleteVersionException (voldemort.versioning.ObsoleteVersionException)26 List (java.util.List)21 HashMap (java.util.HashMap)20 Cluster (voldemort.cluster.Cluster)20 VectorClock (voldemort.versioning.VectorClock)16 NoSuchCapabilityException (voldemort.store.NoSuchCapabilityException)15 ReadOnlyStorageEngine (voldemort.store.readonly.ReadOnlyStorageEngine)14 ExecutionException (java.util.concurrent.ExecutionException)13 StoreDefinitionsMapper (voldemort.xml.StoreDefinitionsMapper)13 Map (java.util.Map)12 Path (org.apache.hadoop.fs.Path)12