Search in sources :

Example 6 with PartitionStateMap

use of org.apache.helix.controller.common.PartitionStateMap in project helix by apache.

the class TestStateTransitionPrirority method updateCurrentStateForPartitionLevelPriority.

private void updateCurrentStateForPartitionLevelPriority(List<String> partitionPriority, CurrentStateOutput currentStateOutput, String resourceName, Map<String, Map<String, String>> bestPossibleMap) {
    IntermediateStateOutput output = event.getAttribute(AttributeName.INTERMEDIATE_STATE.name());
    PartitionStateMap partitionStateMap = output.getPartitionStateMap(resourceName);
    for (Partition partition : partitionStateMap.getStateMap().keySet()) {
        Map<String, String> instanceStateMap = bestPossibleMap.get(partition.getPartitionName());
        if (partitionStateMap.getPartitionMap(partition).equals(instanceStateMap) && !partitionPriority.contains(partition.getPartitionName())) {
            partitionPriority.add(partition.getPartitionName());
            for (String instanceName : instanceStateMap.keySet()) {
                currentStateOutput.setCurrentState(resourceName, partition, instanceName, instanceStateMap.get(instanceName));
            }
            break;
        }
    }
}
Also used : PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap) Partition(org.apache.helix.model.Partition)

Example 7 with PartitionStateMap

use of org.apache.helix.controller.common.PartitionStateMap in project helix by apache.

the class IntermediateStateCalcStage method compute.

private IntermediateStateOutput compute(ClusterEvent event, Map<String, Resource> resourceMap, CurrentStateOutput currentStateOutput, BestPossibleStateOutput bestPossibleStateOutput) {
    // for each resource
    // get the best possible state and current state
    // try to bring immediate state close to best possible state until
    // the possible pending state transition numbers reach the set throttle number.
    IntermediateStateOutput output = new IntermediateStateOutput();
    ClusterDataCache dataCache = event.getAttribute(AttributeName.ClusterDataCache.name());
    StateTransitionThrottleController throttleController = new StateTransitionThrottleController(resourceMap.keySet(), dataCache.getClusterConfig(), dataCache.getLiveInstances().keySet());
    // Resource level prioritization with numerical sortable field.
    // If no value has been set, it will be treated as lowest priority.
    List<ResourcePriority> prioritizedResourceList = new ArrayList<ResourcePriority>();
    for (String resourceName : resourceMap.keySet()) {
        prioritizedResourceList.add(new ResourcePriority(resourceName, Integer.MIN_VALUE));
    }
    // Not have resource level prioritization if user did not set the field name
    if (dataCache.getClusterConfig().getResourcePriorityField() != null) {
        String priorityField = dataCache.getClusterConfig().getResourcePriorityField();
        for (ResourcePriority resourcePriority : prioritizedResourceList) {
            String resourceName = resourcePriority.getResourceName();
            // Try to fetch it from ideal state. Otherwise will treated as lowest priority
            if (dataCache.getResourceConfig(resourceName) != null && dataCache.getResourceConfig(resourceName).getSimpleConfig(priorityField) != null) {
                resourcePriority.setPriority(dataCache.getResourceConfig(resourceName).getSimpleConfig(priorityField));
            } else if (dataCache.getIdealState(resourceName) != null && dataCache.getIdealState(resourceName).getRecord().getSimpleField(priorityField) != null) {
                resourcePriority.setPriority(dataCache.getIdealState(resourceName).getRecord().getSimpleField(priorityField));
            }
        }
        Collections.sort(prioritizedResourceList, new ResourcePriortiyComparator());
    }
    // Update cluster status monitor mbean
    ClusterStatusMonitor clusterStatusMonitor = event.getAttribute(AttributeName.clusterStatusMonitor.name());
    for (ResourcePriority resourcePriority : prioritizedResourceList) {
        String resourceName = resourcePriority.getResourceName();
        Resource resource = resourceMap.get(resourceName);
        IdealState idealState = dataCache.getIdealState(resourceName);
        if (idealState == null) {
            // if ideal state is deleted, use an empty one
            logger.info("resource:" + resourceName + " does not exist anymore");
            idealState = new IdealState(resourceName);
            idealState.setStateModelDefRef(resource.getStateModelDefRef());
        }
        PartitionStateMap intermediatePartitionStateMap = computeIntermediatePartitionState(dataCache, clusterStatusMonitor, idealState, resourceMap.get(resourceName), currentStateOutput, bestPossibleStateOutput.getPartitionStateMap(resourceName), bestPossibleStateOutput.getPreferenceLists(resourceName), throttleController);
        output.setState(resourceName, intermediatePartitionStateMap);
    }
    return output;
}
Also used : PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap) ClusterStatusMonitor(org.apache.helix.monitoring.mbeans.ClusterStatusMonitor)

Example 8 with PartitionStateMap

use of org.apache.helix.controller.common.PartitionStateMap in project helix by apache.

the class IntermediateStateCalcStage method validateMaxPartitionsPerInstance.

private void validateMaxPartitionsPerInstance(ClusterEvent event, ClusterDataCache cache, IntermediateStateOutput intermediateStateOutput, int maxPartitionPerInstance) {
    Map<String, PartitionStateMap> resourceStatesMap = intermediateStateOutput.getResourceStatesMap();
    Map<String, Integer> instancePartitionCounts = new HashMap<>();
    for (String resource : resourceStatesMap.keySet()) {
        IdealState idealState = cache.getIdealState(resource);
        if (idealState != null && idealState.getStateModelDefRef().equals(BuiltInStateModelDefinitions.Task.name())) {
            // ignore task here. Task has its own throttling logic
            continue;
        }
        PartitionStateMap partitionStateMap = resourceStatesMap.get(resource);
        Map<Partition, Map<String, String>> stateMaps = partitionStateMap.getStateMap();
        for (Partition p : stateMaps.keySet()) {
            Map<String, String> stateMap = stateMaps.get(p);
            for (String instance : stateMap.keySet()) {
                // ignore replica to be dropped.
                String state = stateMap.get(instance);
                if (state.equals(HelixDefinedState.DROPPED.name())) {
                    continue;
                }
                if (!instancePartitionCounts.containsKey(instance)) {
                    instancePartitionCounts.put(instance, 0);
                }
                int partitionCount = instancePartitionCounts.get(instance);
                partitionCount++;
                if (partitionCount > maxPartitionPerInstance) {
                    HelixManager manager = event.getAttribute(AttributeName.helixmanager.name());
                    String errMsg = String.format("Partition count to be assigned to instance %s is greater than %d. Stop rebalance and pause the cluster %s", instance, maxPartitionPerInstance, cache.getClusterName());
                    if (manager != null) {
                        manager.getClusterManagmentTool().enableMaintenanceMode(manager.getClusterName(), true, errMsg);
                    } else {
                        logger.error("Failed to pause cluster, HelixManager is not set!");
                    }
                    throw new HelixException(errMsg);
                }
                instancePartitionCounts.put(instance, partitionCount);
            }
        }
    }
}
Also used : HelixManager(org.apache.helix.HelixManager) PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap) HelixException(org.apache.helix.HelixException) PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap)

Example 9 with PartitionStateMap

use of org.apache.helix.controller.common.PartitionStateMap in project helix by apache.

the class PersistAssignmentStage method process.

@Override
public void process(ClusterEvent event) throws Exception {
    ClusterDataCache cache = event.getAttribute(AttributeName.ClusterDataCache.name());
    ClusterConfig clusterConfig = cache.getClusterConfig();
    if (!clusterConfig.isPersistBestPossibleAssignment() && !clusterConfig.isPersistIntermediateAssignment()) {
        return;
    }
    BestPossibleStateOutput bestPossibleAssignment = event.getAttribute(AttributeName.BEST_POSSIBLE_STATE.name());
    HelixManager helixManager = event.getAttribute(AttributeName.helixmanager.name());
    HelixDataAccessor accessor = helixManager.getHelixDataAccessor();
    PropertyKey.Builder keyBuilder = accessor.keyBuilder();
    Map<String, Resource> resourceMap = event.getAttribute(AttributeName.RESOURCES.name());
    for (String resourceId : bestPossibleAssignment.resourceSet()) {
        Resource resource = resourceMap.get(resourceId);
        if (resource != null) {
            final IdealState idealState = cache.getIdealState(resourceId);
            if (idealState == null) {
                LOG.warn("IdealState not found for resource " + resourceId);
                continue;
            }
            IdealState.RebalanceMode mode = idealState.getRebalanceMode();
            if (!mode.equals(IdealState.RebalanceMode.SEMI_AUTO) && !mode.equals(IdealState.RebalanceMode.FULL_AUTO)) {
                // do not persist assignment for resource in neither semi or full auto.
                continue;
            }
            boolean needPersist = false;
            if (mode.equals(IdealState.RebalanceMode.FULL_AUTO)) {
                // persist preference list in ful-auto mode.
                Map<String, List<String>> newLists = bestPossibleAssignment.getPreferenceLists(resourceId);
                if (newLists != null && hasPreferenceListChanged(newLists, idealState)) {
                    idealState.setPreferenceLists(newLists);
                    needPersist = true;
                }
            }
            PartitionStateMap partitionStateMap = bestPossibleAssignment.getPartitionStateMap(resourceId);
            if (clusterConfig.isPersistIntermediateAssignment()) {
                IntermediateStateOutput intermediateAssignment = event.getAttribute(AttributeName.INTERMEDIATE_STATE.name());
                partitionStateMap = intermediateAssignment.getPartitionStateMap(resourceId);
            }
            // TODO: temporary solution for Espresso/Dbus backcompatible, should remove this.
            Map<Partition, Map<String, String>> assignmentToPersist = convertAssignmentPersisted(resource, idealState, partitionStateMap.getStateMap());
            if (assignmentToPersist != null && hasInstanceMapChanged(assignmentToPersist, idealState)) {
                for (Partition partition : assignmentToPersist.keySet()) {
                    Map<String, String> instanceMap = assignmentToPersist.get(partition);
                    idealState.setInstanceStateMap(partition.getPartitionName(), instanceMap);
                }
                needPersist = true;
            }
            if (needPersist) {
                // Update instead of set to ensure any intermediate changes that the controller does not update are kept.
                accessor.updateProperty(keyBuilder.idealStates(resourceId), new DataUpdater<ZNRecord>() {

                    @Override
                    public ZNRecord update(ZNRecord current) {
                        if (current != null) {
                            // Overwrite MapFields and ListFields items with the same key.
                            // Note that default merge will keep old values in the maps or lists unchanged, which is not desired.
                            current.getMapFields().clear();
                            current.getMapFields().putAll(idealState.getRecord().getMapFields());
                            current.getListFields().putAll(idealState.getRecord().getListFields());
                        }
                        return current;
                    }
                }, idealState);
            }
        }
    }
}
Also used : Partition(org.apache.helix.model.Partition) HelixManager(org.apache.helix.HelixManager) Resource(org.apache.helix.model.Resource) IdealState(org.apache.helix.model.IdealState) PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap) HelixDataAccessor(org.apache.helix.HelixDataAccessor) List(java.util.List) HashMap(java.util.HashMap) PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap) Map(java.util.Map) PropertyKey(org.apache.helix.PropertyKey) ZNRecord(org.apache.helix.ZNRecord) ClusterConfig(org.apache.helix.model.ClusterConfig)

Example 10 with PartitionStateMap

use of org.apache.helix.controller.common.PartitionStateMap in project helix by apache.

the class TargetExteralViewCalcStage method process.

@Override
public void process(ClusterEvent event) throws Exception {
    ClusterDataCache cache = event.getAttribute(AttributeName.ClusterDataCache.name());
    ClusterConfig clusterConfig = cache.getClusterConfig();
    if (cache.isTaskCache() || !clusterConfig.isTargetExternalViewEnabled()) {
        return;
    }
    HelixManager helixManager = event.getAttribute(AttributeName.helixmanager.name());
    HelixDataAccessor accessor = helixManager.getHelixDataAccessor();
    if (!accessor.getBaseDataAccessor().exists(accessor.keyBuilder().targetExternalViews().getPath(), AccessOption.PERSISTENT)) {
        accessor.getBaseDataAccessor().create(accessor.keyBuilder().targetExternalViews().getPath(), null, AccessOption.PERSISTENT);
    }
    BestPossibleStateOutput bestPossibleAssignments = event.getAttribute(AttributeName.BEST_POSSIBLE_STATE.name());
    IntermediateStateOutput intermediateAssignments = event.getAttribute(AttributeName.INTERMEDIATE_STATE.name());
    Map<String, Resource> resourceMap = event.getAttribute(AttributeName.RESOURCES.name());
    List<PropertyKey> keys = new ArrayList<>();
    List<ExternalView> targetExternalViews = new ArrayList<>();
    for (String resourceName : bestPossibleAssignments.resourceSet()) {
        if (cache.getIdealState(resourceName) == null || cache.getIdealState(resourceName).isExternalViewDisabled()) {
            continue;
        }
        Resource resource = resourceMap.get(resourceName);
        if (resource != null) {
            PartitionStateMap partitionStateMap = intermediateAssignments.getPartitionStateMap(resourceName);
            Map<String, Map<String, String>> intermediateAssignment = convertToMapFields(partitionStateMap.getStateMap());
            Map<String, List<String>> preferenceLists = bestPossibleAssignments.getPreferenceLists(resourceName);
            boolean needPersist = false;
            ExternalView targetExternalView = cache.getTargetExternalView(resourceName);
            if (targetExternalView == null) {
                targetExternalView = new ExternalView(resourceName);
                targetExternalView.getRecord().getSimpleFields().putAll(cache.getIdealState(resourceName).getRecord().getSimpleFields());
                needPersist = true;
            }
            if (preferenceLists != null && !targetExternalView.getRecord().getListFields().equals(preferenceLists)) {
                targetExternalView.getRecord().setListFields(preferenceLists);
                needPersist = true;
            }
            if (intermediateAssignment != null && !targetExternalView.getRecord().getMapFields().equals(intermediateAssignment)) {
                targetExternalView.getRecord().setMapFields(intermediateAssignment);
                needPersist = true;
            }
            if (needPersist) {
                keys.add(accessor.keyBuilder().targetExternalView(resourceName));
                targetExternalViews.add(targetExternalView);
                cache.updateTargetExternalView(resourceName, targetExternalView);
            }
        }
    }
    accessor.setChildren(keys, targetExternalViews);
}
Also used : ExternalView(org.apache.helix.model.ExternalView) HelixManager(org.apache.helix.HelixManager) Resource(org.apache.helix.model.Resource) ArrayList(java.util.ArrayList) PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap) HelixDataAccessor(org.apache.helix.HelixDataAccessor) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) PartitionStateMap(org.apache.helix.controller.common.PartitionStateMap) Map(java.util.Map) PropertyKey(org.apache.helix.PropertyKey) ClusterConfig(org.apache.helix.model.ClusterConfig)

Aggregations

PartitionStateMap (org.apache.helix.controller.common.PartitionStateMap)10 Partition (org.apache.helix.model.Partition)6 HashMap (java.util.HashMap)3 Map (java.util.Map)3 HelixManager (org.apache.helix.HelixManager)3 PropertyKey (org.apache.helix.PropertyKey)3 List (java.util.List)2 HelixDataAccessor (org.apache.helix.HelixDataAccessor)2 ClusterConfig (org.apache.helix.model.ClusterConfig)2 ExternalView (org.apache.helix.model.ExternalView)2 IdealState (org.apache.helix.model.IdealState)2 Resource (org.apache.helix.model.Resource)2 ArrayList (java.util.ArrayList)1 HelixException (org.apache.helix.HelixException)1 ZNRecord (org.apache.helix.ZNRecord)1 RebalanceType (org.apache.helix.api.config.StateTransitionThrottleConfig.RebalanceType)1 BestPossibleStateOutput (org.apache.helix.controller.stages.BestPossibleStateOutput)1 ClusterDataCache (org.apache.helix.controller.stages.ClusterDataCache)1 CurrentStateOutput (org.apache.helix.controller.stages.CurrentStateOutput)1 StateModelDefinition (org.apache.helix.model.StateModelDefinition)1