Java Code Examples for org.apache.helix.model.IdealState#isValid()

The following examples show how to use org.apache.helix.model.IdealState#isValid() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ZKHelixAdmin.java    From helix with Apache License 2.0 5 votes vote down vote up
@Override
public Map<String, Boolean> validateResourcesForWagedRebalance(String clusterName,
    List<String> resourceNames) {
  // Null checks
  if (clusterName == null || clusterName.isEmpty()) {
    throw new HelixException("Cluster name is invalid!");
  }
  if (resourceNames == null || resourceNames.isEmpty()) {
    throw new HelixException("Resource name list is invalid!");
  }

  // Ensure that all instances are valid
  HelixDataAccessor accessor =
      new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<>(_zkClient));
  PropertyKey.Builder keyBuilder = accessor.keyBuilder();
  List<String> instances = accessor.getChildNames(keyBuilder.instanceConfigs());
  if (validateInstancesForWagedRebalance(clusterName, instances).containsValue(false)) {
    throw new HelixException(String
        .format("Instance capacities haven't been configured properly for cluster %s",
            clusterName));
  }

  Map<String, Boolean> result = new HashMap<>();
  ClusterConfig clusterConfig = _configAccessor.getClusterConfig(clusterName);
  for (String resourceName : resourceNames) {
    IdealState idealState = getResourceIdealState(clusterName, resourceName);
    if (idealState == null || !idealState.isValid()) {
      result.put(resourceName, false);
      continue;
    }
    ResourceConfig resourceConfig = _configAccessor.getResourceConfig(clusterName, resourceName);
    result.put(resourceName,
        validateWeightForResourceConfig(clusterConfig, resourceConfig, idealState));
  }
  return result;
}
 
Example 2
Source File: ZKHelixAdmin.java    From helix with Apache License 2.0 4 votes vote down vote up
@Override
public boolean addResourceWithWeight(String clusterName, IdealState idealState,
    ResourceConfig resourceConfig) {
  // Null checks
  if (clusterName == null || clusterName.isEmpty()) {
    throw new HelixException("Cluster name is null or empty!");
  }
  if (idealState == null || !idealState.isValid()) {
    throw new HelixException("IdealState is null or invalid!");
  }
  if (resourceConfig == null || !resourceConfig.isValid()) {
    // TODO This might be okay because of default weight?
    throw new HelixException("ResourceConfig is null or invalid!");
  }

  // Make sure IdealState and ResourceConfig are for the same resource
  if (!idealState.getResourceName().equals(resourceConfig.getResourceName())) {
    throw new HelixException("Resource names in IdealState and ResourceConfig are different!");
  }

  // Order in which a resource should be added:
  // 1. Validate the weights in ResourceConfig against ClusterConfig
  // Check that all capacity keys in ClusterConfig are set up in every partition in ResourceConfig field
  if (!validateWeightForResourceConfig(_configAccessor.getClusterConfig(clusterName),
      resourceConfig, idealState)) {
    throw new HelixException(String
        .format("Could not add resource %s with weight! Failed to validate the ResourceConfig!",
            idealState.getResourceName()));
  }

  // 2. Add the resourceConfig to ZK
  _configAccessor
      .setResourceConfig(clusterName, resourceConfig.getResourceName(), resourceConfig);

  // 3. Add the idealState to ZK
  setResourceIdealState(clusterName, idealState.getResourceName(), idealState);

  // 4. rebalance the resource
  rebalance(clusterName, idealState.getResourceName(), Integer.parseInt(idealState.getReplicas()),
      idealState.getResourceName(), idealState.getInstanceGroupTag());

  return true;
}
 
Example 3
Source File: IdealStateBuilder.java    From helix with Apache License 2.0 4 votes vote down vote up
/**
 * @return
 */
public IdealState build() {
  IdealState idealstate = new IdealState(_record);
  idealstate.setNumPartitions(numPartitions);
  idealstate.setStateModelDefRef(stateModel);
  idealstate.setStateModelFactoryName(stateModelFactoryName);
  idealstate.setRebalanceMode(rebalancerMode);
  idealstate.setReplicas("" + numReplica);

  if (minActiveReplica >= 0) {
    idealstate.setMinActiveReplicas(minActiveReplica);
  }

  if (rebalancerClassName != null) {
    idealstate.setRebalancerClassName(rebalancerClassName);
  }

  if (rebalanceStrategy != null) {
    idealstate.setRebalanceStrategy(rebalanceStrategy);
  }

  if (maxPartitionsPerNode > 0) {
    idealstate.setMaxPartitionsPerInstance(maxPartitionsPerNode);
  }

  if (disableExternalView != null) {
    idealstate.setDisableExternalView(disableExternalView);
  }

  if (enableGroupRouting != null) {
    idealstate.enableGroupRouting(enableGroupRouting);
  }

  if (resourceGroupName != null) {
    idealstate.setResourceGroupName(resourceGroupName);
  }

  if (resourceType != null) {
    idealstate.setResourceType(resourceType);
  }

  if (rebalanceDelayInMs >= 0) {
    idealstate.setRebalanceDelay(rebalanceDelayInMs);
  }

  if (delayRebalanceEnabled != null) {
    idealstate.setDelayRebalanceEnabled(delayRebalanceEnabled);
  }

  if (!idealstate.isValid()) {
    throw new HelixException("invalid ideal-state: " + idealstate);
  }
  return idealstate;
}
 
Example 4
Source File: InstanceValidationUtil.java    From helix with Apache License 2.0 4 votes vote down vote up
/**
 * Check instance is already in the stable state. Here stable means all the ideal state mapping
 * matches external view (view of current state).
 * It requires PERSIST_INTERMEDIATE_ASSIGNMENT turned on!
 * @param dataAccessor
 * @param instanceName
 * @return
 */
public static boolean isInstanceStable(HelixDataAccessor dataAccessor, String instanceName) {
  PropertyKey.Builder keyBuilder = dataAccessor.keyBuilder();
  ClusterConfig clusterConfig = dataAccessor.getProperty(keyBuilder.clusterConfig());
  if (clusterConfig == null) {
    throw new HelixException("Missing cluster config!");
  }
  if (!clusterConfig.isPersistIntermediateAssignment()) {
    throw new HelixException("isInstanceStable needs persist assignment on!");
  }

  List<String> idealStateNames = dataAccessor.getChildNames(keyBuilder.idealStates());
  for (String idealStateName : idealStateNames) {
    IdealState idealState = dataAccessor.getProperty(keyBuilder.idealStates(idealStateName));
    if (idealState == null || !idealState.isEnabled() || !idealState.isValid()
        || TaskConstants.STATE_MODEL_NAME.equals(idealState.getStateModelDefRef())) {
      continue;
    }

    ExternalView externalView = dataAccessor.getProperty(keyBuilder.externalView(idealStateName));
    if (externalView == null) {
      throw new HelixException(
          String.format("Resource %s does not have external view!", idealStateName));
    }
    for (String partition : idealState.getPartitionSet()) {
      Map<String, String> isPartitionMap = idealState.getInstanceStateMap(partition);
      if (isPartitionMap == null) {
        throw new HelixException(String
            .format("Partition %s of resource %s does not have an ideal state partition map",
                partition, idealStateName));
      }
      if (isPartitionMap.containsKey(instanceName)) {
        Map<String, String> evPartitionMap = externalView.getStateMap(partition);
        if (evPartitionMap == null) {
          throw new HelixException(String
              .format("Partition %s of resource %s does not have an external view partition map",
                  partition, idealStateName));
        }
        if (!evPartitionMap.containsKey(instanceName)
            || !evPartitionMap.get(instanceName).equals(isPartitionMap.get(instanceName))) {
          // only checks the state from IS matches EV. Return false when
          // 1. This partition not has current state on this instance
          // 2. The state does not match the state on ideal state
          return false;
        }
      }
    }
  }
  return true;
}
 
Example 5
Source File: InstanceValidationUtil.java    From helix with Apache License 2.0 4 votes vote down vote up
/**
 * Check if sibling nodes of the instance meet min active replicas constraint
 * Two instances are sibling of each other if they host the same partition
 * WARNING: The check uses ExternalView to reduce network traffic but suffer from accuracy
 * due to external view propagation latency
 *
 * TODO: Use in memory cache and query instance's currentStates
 *
 * @param dataAccessor
 * @param instanceName
 * @return
 */
public static boolean siblingNodesActiveReplicaCheck(HelixDataAccessor dataAccessor, String instanceName) {
  PropertyKey.Builder propertyKeyBuilder = dataAccessor.keyBuilder();
  List<String> resources = dataAccessor.getChildNames(propertyKeyBuilder.idealStates());

  for (String resourceName : resources) {
    IdealState idealState = dataAccessor.getProperty(propertyKeyBuilder.idealStates(resourceName));
    if (idealState == null || !idealState.isEnabled() || !idealState.isValid()
        || TaskConstants.STATE_MODEL_NAME.equals(idealState.getStateModelDefRef())) {
      continue;
    }
    ExternalView externalView =
        dataAccessor.getProperty(propertyKeyBuilder.externalView(resourceName));
    if (externalView == null) {
      throw new HelixException(
          String.format("Resource %s does not have external view!", resourceName));
    }
    // Get the minActiveReplicas constraint for the resource
    int minActiveReplicas = externalView.getMinActiveReplicas();
    if (minActiveReplicas == -1) {
      _logger.warn("Resource " + resourceName
          + " is missing minActiveReplica field. Skip the sibling check");
      continue;
    }
    String stateModeDef = externalView.getStateModelDefRef();
    StateModelDefinition stateModelDefinition =
        dataAccessor.getProperty(propertyKeyBuilder.stateModelDef(stateModeDef));
    Set<String> unhealthyStates = new HashSet<>(UNHEALTHY_STATES);
    if (stateModelDefinition != null) {
      unhealthyStates.add(stateModelDefinition.getInitialState());
    }
    for (String partition : externalView.getPartitionSet()) {
      Map<String, String> stateByInstanceMap = externalView.getStateMap(partition);
      // found the resource hosted on the instance
      if (stateByInstanceMap.containsKey(instanceName)) {
        int numHealthySiblings = 0;
        for (Map.Entry<String, String> entry : stateByInstanceMap.entrySet()) {
          if (!entry.getKey().equals(instanceName)
              && !unhealthyStates.contains(entry.getValue())) {
            numHealthySiblings++;
          }
        }
        if (numHealthySiblings < minActiveReplicas) {
          _logger.info(
              "Partition {} doesn't have enough active replicas in sibling nodes. NumHealthySiblings: {}, minActiveReplicas: {}",
              partition, numHealthySiblings, minActiveReplicas);
          return false;
        }
      }
    }
  }

  return true;
}