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();
}
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();
}
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();
}
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();
}
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;
}
}
Aggregations