public VAdminProto.AsyncOperationStatusResponse handleRebalanceNode( VAdminProto.InitiateRebalanceNodeRequest request) { VAdminProto.AsyncOperationStatusResponse.Builder response = VAdminProto.AsyncOperationStatusResponse.newBuilder(); try { if (!voldemortConfig.isEnableRebalanceService()) throw new VoldemortException( "Rebalance service is not enabled for node:" + metadataStore.getNodeId()); RebalancePartitionsInfo rebalanceStealInfo = new RebalancePartitionsInfo( request.getStealerId(), request.getDonorId(), request.getPartitionsList(), request.getDeletePartitionsList(), request.getUnbalancedStoreList(), request.getAttempt()); int requestId = rebalancer.rebalanceLocalNode(rebalanceStealInfo); response .setRequestId(requestId) .setDescription(rebalanceStealInfo.toString()) .setStatus("started") .setComplete(false); } catch (VoldemortException e) { response.setError(ProtoUtils.encodeError(errorCodeMapper, e)); logger.error("handleRebalanceNode failed for request(" + request.toString() + ")", e); } return response.build(); }
@Override public void operate() throws Exception { adminClient = RebalanceUtils.createTempAdminClient( voldemortConfig, metadataStore.getCluster(), voldemortConfig.getMaxParallelStoresRebalancing(), 1); final List<Exception> failures = new ArrayList<Exception>(); try { for (final String storeName : ImmutableList.copyOf(stealInfo.getUnbalancedStoreList())) { executors.submit( new Runnable() { public void run() { try { boolean isReadOnlyStore = metadataStore .getStoreDef(storeName) .getType() .compareTo(ReadOnlyStorageConfiguration.TYPE_NAME) == 0; logger.info(getHeader(stealInfo) + "Working on store " + storeName); rebalanceStore(storeName, adminClient, stealInfo, isReadOnlyStore); // We finished the store, delete it stealInfo.removeStore(storeName); logger.info(getHeader(stealInfo) + "Completed working on store " + storeName); } catch (Exception e) { logger.error( getHeader(stealInfo) + "Error while rebalancing for store " + storeName + " - " + e.getMessage(), e); failures.add(e); } } }); } waitForShutdown(); // If empty, clean state List<String> unbalancedStores = Lists.newArrayList(stealInfo.getUnbalancedStoreList()); if (unbalancedStores.isEmpty()) { logger.info( getHeader(stealInfo) + "Rebalance of " + stealInfo + " completed successfully."); updateStatus( getHeader(stealInfo) + "Rebalance of " + stealInfo + " completed successfully."); metadataStore.deleteRebalancingState(stealInfo); } else { throw new VoldemortRebalancingException( getHeader(stealInfo) + "Failed to rebalance task " + stealInfo, failures); } } finally { // free the permit in all cases. logger.info( getHeader(stealInfo) + "Releasing permit for donor node " + stealInfo.getDonorId()); rebalancer.releaseRebalancingPermit(stealInfo.getDonorId()); adminClient.stop(); adminClient = null; } }