Search in sources :

Example 1 with RebalanceTaskInfo

use of voldemort.client.rebalance.RebalanceTaskInfo in project voldemort by voldemort.

the class RebalancerState method toJsonString.

public String toJsonString() {
    List<Map<String, Object>> maps = Lists.newLinkedList();
    for (RebalanceTaskInfo rebalanceTaskInfo : stealInfoMap.values()) maps.add(rebalanceTaskInfo.asMap());
    StringWriter stringWriter = new StringWriter();
    new JsonWriter(stringWriter).write(maps);
    stringWriter.flush();
    return stringWriter.toString();
}
Also used : StringWriter(java.io.StringWriter) Map(java.util.Map) JsonWriter(voldemort.serialization.json.JsonWriter) RebalanceTaskInfo(voldemort.client.rebalance.RebalanceTaskInfo)

Example 2 with RebalanceTaskInfo

use of voldemort.client.rebalance.RebalanceTaskInfo in project voldemort by voldemort.

the class RebalancerState method toString.

@Override
public String toString() {
    StringBuilder sb = new StringBuilder("RebalancerState(operations: ");
    sb.append("\n");
    for (RebalanceTaskInfo info : getAll()) {
        sb.append(info);
        sb.append("\n");
    }
    sb.append(")");
    return sb.toString();
}
Also used : RebalanceTaskInfo(voldemort.client.rebalance.RebalanceTaskInfo)

Example 3 with RebalanceTaskInfo

use of voldemort.client.rebalance.RebalanceTaskInfo in project voldemort by voldemort.

the class AdminServiceRequestHandler method handleRebalanceStateChange.

public VAdminProto.RebalanceStateChangeResponse handleRebalanceStateChange(VAdminProto.RebalanceStateChangeRequest request) {
    VAdminProto.RebalanceStateChangeResponse.Builder response = VAdminProto.RebalanceStateChangeResponse.newBuilder();
    synchronized (rebalancer) {
        try {
            // Retrieve all values first
            List<RebalanceTaskInfo> rebalanceTaskInfo = Lists.newArrayList();
            for (RebalanceTaskInfoMap map : request.getRebalanceTaskListList()) {
                rebalanceTaskInfo.add(ProtoUtils.decodeRebalanceTaskInfoMap(map));
            }
            Cluster cluster = new ClusterMapper().readCluster(new StringReader(request.getClusterString()));
            List<StoreDefinition> storeDefs = new StoreDefinitionsMapper().readStoreList(new StringReader(request.getStoresString()));
            boolean swapRO = request.getSwapRo();
            boolean changeClusterMetadata = request.getChangeClusterMetadata();
            boolean changeRebalanceState = request.getChangeRebalanceState();
            boolean rollback = request.getRollback();
            rebalancer.rebalanceStateChange(cluster, storeDefs, rebalanceTaskInfo, swapRO, changeClusterMetadata, changeRebalanceState, rollback);
        } catch (VoldemortException e) {
            response.setError(ProtoUtils.encodeError(errorCodeMapper, e));
            logger.error("handleRebalanceStateChange failed for request(" + request.toString() + ")", e);
        }
    }
    return response.build();
}
Also used : RebalanceTaskInfoMap(voldemort.client.protocol.pb.VAdminProto.RebalanceTaskInfoMap) StoreDefinitionsMapper(voldemort.xml.StoreDefinitionsMapper) Cluster(voldemort.cluster.Cluster) ClusterMapper(voldemort.xml.ClusterMapper) VoldemortException(voldemort.VoldemortException) StoreDefinition(voldemort.store.StoreDefinition) StringReader(java.io.StringReader) RebalanceTaskInfo(voldemort.client.rebalance.RebalanceTaskInfo)

Example 4 with RebalanceTaskInfo

use of voldemort.client.rebalance.RebalanceTaskInfo in project voldemort by voldemort.

the class AdminServiceRequestHandler method handleDeleteStoreRebalanceState.

private VAdminProto.DeleteStoreRebalanceStateResponse handleDeleteStoreRebalanceState(VAdminProto.DeleteStoreRebalanceStateRequest request) {
    VAdminProto.DeleteStoreRebalanceStateResponse.Builder response = VAdminProto.DeleteStoreRebalanceStateResponse.newBuilder();
    synchronized (rebalancer) {
        try {
            int nodeId = request.getNodeId();
            String storeName = request.getStoreName();
            logger.info("Removing rebalancing state for donor node " + nodeId + " and store " + storeName + " from stealer node " + metadataStore.getNodeId());
            RebalanceTaskInfo info = metadataStore.getRebalancerState().find(nodeId);
            if (info == null) {
                throw new VoldemortException("Could not find state for donor node " + nodeId);
            }
            List<Integer> partitionIds = info.getPartitionIds(storeName);
            if (partitionIds.size() == 0) {
                throw new VoldemortException("Could not find state for donor node " + nodeId + " and store " + storeName);
            }
            info.removeStore(storeName);
            logger.info("Removed rebalancing state for donor node " + nodeId + " and store " + storeName + " from stealer node " + metadataStore.getNodeId());
            if (info.getPartitionStores().isEmpty()) {
                metadataStore.deleteRebalancingState(info);
                logger.info("Removed entire rebalancing state for donor node " + nodeId + " from stealer node " + metadataStore.getNodeId());
            }
        } catch (VoldemortException e) {
            response.setError(ProtoUtils.encodeError(errorCodeMapper, e));
            logger.error("handleDeleteStoreRebalanceState failed for request(" + request.toString() + ")", e);
        }
    }
    return response.build();
}
Also used : VoldemortException(voldemort.VoldemortException) RebalanceTaskInfo(voldemort.client.rebalance.RebalanceTaskInfo)

Example 5 with RebalanceTaskInfo

use of voldemort.client.rebalance.RebalanceTaskInfo 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)

Aggregations

RebalanceTaskInfo (voldemort.client.rebalance.RebalanceTaskInfo)12 VoldemortException (voldemort.VoldemortException)5 List (java.util.List)3 StringReader (java.io.StringReader)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 Cluster (voldemort.cluster.Cluster)2 StoreDefinition (voldemort.store.StoreDefinition)2 StoreDefinitionsMapper (voldemort.xml.StoreDefinitionsMapper)2 File (java.io.File)1 StringWriter (java.io.StringWriter)1 Before (org.junit.Before)1 Test (org.junit.Test)1 ClientConfig (voldemort.client.ClientConfig)1 SocketStoreClientFactory (voldemort.client.SocketStoreClientFactory)1 RebalanceTaskInfoMap (voldemort.client.protocol.pb.VAdminProto.RebalanceTaskInfoMap)1 RebalanceBatchPlan (voldemort.client.rebalance.RebalanceBatchPlan)1 RoutingStrategy (voldemort.routing.RoutingStrategy)1 RoutingStrategyFactory (voldemort.routing.RoutingStrategyFactory)1 SerializerDefinition (voldemort.serialization.SerializerDefinition)1