Search in sources :

Example 66 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class VoldemortNativeRequestHandler method isCompleteRequest.

/**
     * This is pretty ugly. We end up mimicking the request logic here, so this
     * needs to stay in sync with handleRequest.
     */
@Override
public boolean isCompleteRequest(final ByteBuffer buffer) throws VoldemortException {
    DataInputStream inputStream = new DataInputStream(new ByteBufferBackedInputStream(buffer));
    try {
        byte opCode = inputStream.readByte();
        // Store Name
        inputStream.readUTF();
        // Store routing type
        getRoutingType(inputStream);
        switch(opCode) {
            case VoldemortOpCode.GET_VERSION_OP_CODE:
                if (!GetVersionRequestHandler.isCompleteRequest(inputStream, buffer))
                    return false;
                break;
            case VoldemortOpCode.GET_OP_CODE:
                if (!GetRequestHandler.isCompleteRequest(inputStream, buffer, protocolVersion))
                    return false;
                break;
            case VoldemortOpCode.GET_ALL_OP_CODE:
                if (!GetAllRequestHandler.isCompleteRequest(inputStream, buffer, protocolVersion))
                    return false;
                break;
            case VoldemortOpCode.PUT_OP_CODE:
                {
                    if (!PutRequestHandler.isCompleteRequest(inputStream, buffer, protocolVersion))
                        return false;
                    break;
                }
            case VoldemortOpCode.DELETE_OP_CODE:
                {
                    if (!DeleteRequestHandler.isCompleteRequest(inputStream, buffer))
                        return false;
                    break;
                }
            default:
                throw new VoldemortException(" Unrecognized Voldemort OpCode " + opCode);
        }
        // data, there is something wrong.
        if (buffer.hasRemaining()) {
            logger.info("Probably a client bug, Discarding additional bytes in isCompleteRequest. Opcode: " + opCode + ", remaining bytes: " + buffer.remaining());
        }
        return true;
    } catch (IOException e) {
        // throws an InvalidArgumentException.
        if (logger.isDebugEnabled())
            logger.debug("Probable partial read occurred causing exception", e);
        return false;
    }
}
Also used : IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) VoldemortException(voldemort.VoldemortException) ByteBufferBackedInputStream(voldemort.common.nio.ByteBufferBackedInputStream)

Example 67 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class VoldemortNativeRequestHandler method handleRequest.

@Override
public StreamRequestHandler handleRequest(final DataInputStream inputStream, final DataOutputStream outputStream, final ByteBufferContainer outputContainer) throws IOException {
    long startTimeMs = -1;
    long startTimeNs = -1;
    if (logger.isDebugEnabled()) {
        startTimeMs = System.currentTimeMillis();
        startTimeNs = System.nanoTime();
    }
    byte opCode = inputStream.readByte();
    String storeName = inputStream.readUTF();
    RequestRoutingType routingType = getRoutingType(inputStream);
    Store<ByteArray, byte[], byte[]> store = getStore(storeName, routingType);
    if (store == null) {
        clearBuffer(outputContainer);
        writeException(outputStream, new VoldemortException("No store named: '" + storeName + "'."));
        return null;
    }
    ClientRequestHandler requestHandler = getClientRequestHandler(opCode, store);
    try {
        requestHandler.parseRequest(inputStream);
        requestHandler.processRequest();
    } catch (VoldemortException e) {
        // they are harmless and indicates normal mode of operation.
        if (!(e instanceof ObsoleteVersionException)) {
            logger.error("Store: " + storeName + ". Error: " + e.getMessage());
        }
        clearBuffer(outputContainer);
        writeException(outputStream, e);
        return null;
    }
    // We are done with Input, clear the buffers
    clearBuffer(outputContainer);
    int size = requestHandler.getResponseSize();
    if (outputContainer != null) {
        outputContainer.growBuffer(size);
    }
    requestHandler.writeResponse(outputStream);
    outputStream.flush();
    if (logger.isDebugEnabled()) {
        String debugPrefix = "OpCode: " + opCode + ", started at: " + startTimeMs + ", handlerRef: " + System.identityHashCode(inputStream) + ", Elapsed : " + (System.nanoTime() - startTimeNs) + " ns, ";
        logger.debug(debugPrefix + requestHandler.getDebugMessage());
    }
    return null;
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) RequestRoutingType(voldemort.server.RequestRoutingType) ByteArray(voldemort.utils.ByteArray) VoldemortException(voldemort.VoldemortException)

Example 68 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class Rebalancer method swapROStores.

/**
     * Goes through all the RO Stores in the plan and swaps it
     * 
     * @param swappedStoreNames Names of stores already swapped
     * @param useSwappedStoreNames Swap only the previously swapped stores (
     *        Happens during error )
     */
private void swapROStores(List<String> swappedStoreNames, boolean useSwappedStoreNames) {
    try {
        for (StoreDefinition storeDef : metadataStore.getStoreDefList()) {
            // Only pick up the RO stores
            if (storeDef.getType().compareTo(ReadOnlyStorageConfiguration.TYPE_NAME) == 0) {
                if (useSwappedStoreNames && !swappedStoreNames.contains(storeDef.getName())) {
                    continue;
                }
                ReadOnlyStorageEngine engine = (ReadOnlyStorageEngine) storeRepository.getStorageEngine(storeDef.getName());
                if (engine == null) {
                    throw new VoldemortException("Could not find storage engine for " + storeDef.getName() + " to swap ");
                }
                logger.info("Swapping RO store " + storeDef.getName());
                // Time to swap this store - Could have used admin client,
                // but why incur the overhead?
                engine.swapFiles(engine.getCurrentDirPath());
                // Add to list of stores already swapped
                if (!useSwappedStoreNames)
                    swappedStoreNames.add(storeDef.getName());
            }
        }
    } catch (Exception e) {
        logger.error("Error while swapping RO store");
        throw new VoldemortException(e);
    }
}
Also used : StoreDefinition(voldemort.store.StoreDefinition) ReadOnlyStorageEngine(voldemort.store.readonly.ReadOnlyStorageEngine) VoldemortException(voldemort.VoldemortException) VoldemortException(voldemort.VoldemortException)

Example 69 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class Rebalancer method rebalanceStateChange.

/**
     * Support four different stages <br>
     * For normal operation:
     * 
     * <pre>
     * | swapRO | changeClusterMetadata | changeRebalanceState | Order |
     * | f | t | t | rebalance -> cluster  | 
     * | f | f | t | rebalance |
     * | t | t | f | cluster -> swap |
     * | t | t | t | rebalance -> cluster -> swap|
     * </pre>
     * 
     * In general we need to do [ cluster change -> swap -> rebalance state
     * change ]
     * 
     * NOTE: The update of the cluster metadata and the rebalancer state is not
     * "atomic". Ergo, there could theoretically be a race where a client picks
     * up new cluster metadata sends a request based on that, but the proxy
     * bridges have not been setup and we either miss a proxy put or return a
     * null for get/getalls
     * 
     * TODO:refactor The rollback logic here is too convoluted. Specifically,
     * the independent updates to each key could be split up into their own
     * methods.
     * 
     * @param cluster Cluster metadata to change
     * @param rebalanceTaskInfo List of rebalance partitions info
     * @param swapRO Boolean to indicate swapping of RO store
     * @param changeClusterAndStoresMetadata Boolean to indicate a change of
     *        cluster metadata
     * @param changeRebalanceState Boolean to indicate a change in rebalance
     *        state
     * @param rollback Boolean to indicate that we are rolling back or not
     */
public void rebalanceStateChange(Cluster cluster, List<StoreDefinition> storeDefs, List<RebalanceTaskInfo> rebalanceTaskInfo, boolean swapRO, boolean changeClusterAndStoresMetadata, boolean changeRebalanceState, boolean rollback) {
    Cluster currentCluster = metadataStore.getCluster();
    List<StoreDefinition> currentStoreDefs = metadataStore.getStoreDefList();
    logger.info("Server doing rebalance state change with options [ cluster metadata change - " + changeClusterAndStoresMetadata + " ], [ changing rebalancing state - " + changeRebalanceState + " ], [ changing swapping RO - " + swapRO + " ], [ rollback - " + rollback + " ]");
    // Variables to track what has completed
    List<RebalanceTaskInfo> completedRebalanceTaskInfo = Lists.newArrayList();
    List<String> swappedStoreNames = Lists.newArrayList();
    boolean completedClusterAndStoresChange = false;
    boolean completedRebalanceSourceClusterChange = false;
    Cluster previousRebalancingSourceCluster = null;
    List<StoreDefinition> previousRebalancingSourceStores = null;
    try {
        // CHANGE REBALANCING STATE
        if (changeRebalanceState) {
            try {
                previousRebalancingSourceCluster = metadataStore.getRebalancingSourceCluster();
                previousRebalancingSourceStores = metadataStore.getRebalancingSourceStores();
                if (!rollback) {
                    // Save up the current cluster and stores def for
                    // Redirecting store
                    changeClusterAndStores(MetadataStore.REBALANCING_SOURCE_CLUSTER_XML, currentCluster, // for Redirecting store
                    MetadataStore.REBALANCING_SOURCE_STORES_XML, currentStoreDefs);
                    completedRebalanceSourceClusterChange = true;
                    for (RebalanceTaskInfo info : rebalanceTaskInfo) {
                        metadataStore.addRebalancingState(info);
                        completedRebalanceTaskInfo.add(info);
                    }
                } else {
                    // Reset the rebalancing source cluster back to null
                    changeClusterAndStores(MetadataStore.REBALANCING_SOURCE_CLUSTER_XML, null, // stores back to null
                    MetadataStore.REBALANCING_SOURCE_STORES_XML, null);
                    completedRebalanceSourceClusterChange = true;
                    for (RebalanceTaskInfo info : rebalanceTaskInfo) {
                        metadataStore.deleteRebalancingState(info);
                        completedRebalanceTaskInfo.add(info);
                    }
                }
            } catch (Exception e) {
                throw new VoldemortException(e);
            }
        }
        // CHANGE CLUSTER METADATA AND STORE METADATA
        if (changeClusterAndStoresMetadata) {
            logger.info("Switching cluster metadata from " + currentCluster + " to " + cluster);
            logger.info("Switching stores metadata from " + currentStoreDefs + " to " + storeDefs);
            changeClusterAndStores(MetadataStore.CLUSTER_KEY, cluster, MetadataStore.STORES_KEY, storeDefs);
            completedClusterAndStoresChange = true;
        }
        // SWAP RO DATA FOR ALL STORES
        if (swapRO) {
            swapROStores(swappedStoreNames, false);
        }
    } catch (VoldemortException e) {
        logger.error("Got exception while changing state, now rolling back changes", e);
        // ROLLBACK CLUSTER AND STORES CHANGE
        if (completedClusterAndStoresChange) {
            try {
                logger.info("Rolling back cluster.xml to " + currentCluster);
                logger.info("Rolling back stores.xml to " + currentStoreDefs);
                changeClusterAndStores(MetadataStore.CLUSTER_KEY, currentCluster, MetadataStore.STORES_KEY, currentStoreDefs);
            } catch (Exception exception) {
                logger.error("Error while rolling back cluster metadata to " + currentCluster + " Stores metadata to " + currentStoreDefs, exception);
            }
        }
        // SWAP RO DATA FOR ALL COMPLETED STORES
        if (swappedStoreNames.size() > 0) {
            try {
                swapROStores(swappedStoreNames, true);
            } catch (Exception exception) {
                logger.error("Error while swapping back to old state ", exception);
            }
        }
        // CHANGE BACK ALL REBALANCING STATES FOR COMPLETED ONES
        if (completedRebalanceTaskInfo.size() > 0) {
            if (!rollback) {
                for (RebalanceTaskInfo info : completedRebalanceTaskInfo) {
                    try {
                        metadataStore.deleteRebalancingState(info);
                    } catch (Exception exception) {
                        logger.error("Error while deleting back rebalance info during error rollback " + info, exception);
                    }
                }
            } else {
                for (RebalanceTaskInfo info : completedRebalanceTaskInfo) {
                    try {
                        metadataStore.addRebalancingState(info);
                    } catch (Exception exception) {
                        logger.error("Error while adding back rebalance info during error rollback " + info, exception);
                    }
                }
            }
        }
        // REBALANCING_SOURCE_STORES_XML
        if (completedRebalanceSourceClusterChange) {
            logger.info("Reverting the REBALANCING_SOURCE_CLUSTER_XML back to " + previousRebalancingSourceCluster);
            logger.info("Reverting the REBALANCING_SOURCE_STORES_XML back to " + previousRebalancingSourceStores);
            changeClusterAndStores(MetadataStore.REBALANCING_SOURCE_CLUSTER_XML, previousRebalancingSourceCluster, MetadataStore.REBALANCING_SOURCE_STORES_XML, previousRebalancingSourceStores);
        }
        throw e;
    }
}
Also used : StoreDefinition(voldemort.store.StoreDefinition) Cluster(voldemort.cluster.Cluster) VoldemortException(voldemort.VoldemortException) RebalanceTaskInfo(voldemort.client.rebalance.RebalanceTaskInfo) VoldemortException(voldemort.VoldemortException)

Example 70 with VoldemortException

use of voldemort.VoldemortException in project voldemort by voldemort.

the class Rebalancer method rebalanceNode.

/**
     * This function is responsible for starting the actual async rebalance
     * operation. This is run if this node is the stealer node
     * 
     * <br>
     * 
     * We also assume that the check that this server is in rebalancing state
     * has been done at a higher level
     * 
     * @param stealInfo Partition info to steal
     * @return Returns a id identifying the async operation
     */
public int rebalanceNode(final RebalanceTaskInfo stealInfo) {
    final RebalanceTaskInfo info = metadataStore.getRebalancerState().find(stealInfo.getDonorId());
    // Do we have the plan in the state?
    if (info == null) {
        throw new VoldemortException("Could not find plan " + stealInfo + " in the server state on " + metadataStore.getNodeId());
    } else if (!info.equals(stealInfo)) {
        // If we do have the plan, is it the same
        throw new VoldemortException("The plan in server state " + info + " is not the same as the process passed " + stealInfo);
    } else if (!acquireRebalancingPermit(stealInfo.getDonorId())) {
        // Both are same, now try to acquire a lock for the donor node
        throw new AlreadyRebalancingException("Node " + metadataStore.getNodeId() + " is already rebalancing from donor " + info.getDonorId() + " with info " + info);
    }
    // Acquired lock successfully, start rebalancing...
    int requestId = asyncService.getUniqueRequestId();
    // Why do we pass 'info' instead of 'stealInfo'? So that we can change
    // the state as the stores finish rebalance
    asyncService.submitOperation(requestId, new StealerBasedRebalanceAsyncOperation(this, voldemortConfig, metadataStore, requestId, info));
    return requestId;
}
Also used : StealerBasedRebalanceAsyncOperation(voldemort.server.rebalance.async.StealerBasedRebalanceAsyncOperation) VoldemortException(voldemort.VoldemortException) RebalanceTaskInfo(voldemort.client.rebalance.RebalanceTaskInfo)

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