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

The following examples show how to use org.apache.helix.model.IdealState#isEnabled() . 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: HelixBrokerStarter.java    From incubator-pinot with Apache License 2.0 6 votes vote down vote up
/**
 * Fetches the resources to monitor and registers the {@link org.apache.pinot.common.utils.ServiceStatus.ServiceStatusCallback}s
 */
private void registerServiceStatusHandler() {
  List<String> resourcesToMonitor = new ArrayList<>(1);
  IdealState brokerResourceIdealState =
      _helixAdmin.getResourceIdealState(_clusterName, Helix.BROKER_RESOURCE_INSTANCE);
  if (brokerResourceIdealState != null && brokerResourceIdealState.isEnabled()) {
    for (String partitionName : brokerResourceIdealState.getPartitionSet()) {
      if (brokerResourceIdealState.getInstanceSet(partitionName).contains(_brokerId)) {
        resourcesToMonitor.add(Helix.BROKER_RESOURCE_INSTANCE);
        break;
      }
    }
  }

  double minResourcePercentForStartup = _brokerConf.getDouble(Broker.CONFIG_OF_BROKER_MIN_RESOURCE_PERCENT_FOR_START,
      Broker.DEFAULT_BROKER_MIN_RESOURCE_PERCENT_FOR_START);

  LOGGER.info("Registering service status handler");
  ServiceStatus.setServiceStatusCallback(_brokerId, new ServiceStatus.MultipleCallbackServiceStatusCallback(
      ImmutableList.of(new ServiceStatus.IdealStateAndCurrentStateMatchServiceStatusCallback(_participantHelixManager,
              _clusterName, _brokerId, resourcesToMonitor, minResourcePercentForStartup),
          new ServiceStatus.IdealStateAndExternalViewMatchServiceStatusCallback(_participantHelixManager,
              _clusterName, _brokerId, resourcesToMonitor, minResourcePercentForStartup))));
}
 
Example 2
Source File: AbstractRebalancer.java    From helix with Apache License 2.0 5 votes vote down vote up
/**
 * Compute if an overwritten is necessary for the partition assignment in case that the proposed
 * assignment is not valid or empty.
 * @param stateModelDef
 * @param preferenceList
 * @param currentStateOutput
 * @param idealState
 * @param partition
 * @param monitoredResolver
 * @return An optional object which contains the assignment map if overwritten is necessary.
 * Otherwise return Optional.empty().
 */
protected Optional<Map<String, String>> computeStatesOverwriteForPartition(
    final StateModelDefinition stateModelDef, final List<String> preferenceList,
    final CurrentStateOutput currentStateOutput, IdealState idealState, final Partition partition,
    final MonitoredAbnormalResolver monitoredResolver) {
  String resourceName = idealState.getResourceName();
  Map<String, String> currentStateMap =
      currentStateOutput.getCurrentStateMap(resourceName, partition);

  // (1) If the partition is removed from IS or the IS is deleted.
  // Transit to DROPPED no matter the instance is disabled or not.
  if (preferenceList == null) {
    return Optional.of(computeBestPossibleMapForDroppedResource(currentStateMap));
  }

  // (2) If resource disabled altogether, transit to initial-state (e.g. OFFLINE) if it's not in ERROR.
  if (!idealState.isEnabled()) {
    return Optional.of(computeBestPossibleMapForDisabledResource(currentStateMap, stateModelDef));
  }

  // (3) If the current states are not valid, fix the invalid part first.
  if (!monitoredResolver
      .checkCurrentStates(currentStateOutput, resourceName, partition, stateModelDef)) {
    monitoredResolver.recordAbnormalState();
    Map<String, String> recoveryAssignment = monitoredResolver
        .computeRecoveryAssignment(currentStateOutput, resourceName, partition, stateModelDef,
            preferenceList);
    if (recoveryAssignment == null || !recoveryAssignment.keySet()
        .equals(currentStateMap.keySet())) {
      throw new HelixException(String.format(
          "Invalid recovery assignment %s since it changed the current partition placement %s",
          recoveryAssignment, currentStateMap));
    }
    monitoredResolver.recordRecoveryAttempt();
    return Optional.of(recoveryAssignment);
  }

  return Optional.empty();
}
 
Example 3
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 4
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;
}
 
Example 5
Source File: ServiceStatus.java    From incubator-pinot with Apache License 2.0 4 votes vote down vote up
private StatusDescriptionPair evaluateResourceStatus(String resourceName) {
  IdealState idealState = getResourceIdealState(resourceName);
  // If the resource has been removed or disabled, ignore it
  if (idealState == null || !idealState.isEnabled()) {
    return new StatusDescriptionPair(Status.GOOD, STATUS_DESCRIPTION_NONE);
  }

  T helixState = getState(resourceName);
  if (helixState == null) {
    return new StatusDescriptionPair(Status.STARTING, STATUS_DESCRIPTION_NO_HELIX_STATE);
  }

  // Check that all partitions that are supposed to be in any state other than OFFLINE have the same status in the
  // external view or went to ERROR state (which means that we tried to load the segments/resources but failed for
  // some reason)
  Map<String, String> partitionStateMap = getPartitionStateMap(helixState);
  for (String partitionName : idealState.getPartitionSet()) {
    String idealStateStatus = idealState.getInstanceStateMap(partitionName).get(_instanceName);

    // Skip this partition if it is not assigned to this instance or if the instance should be offline
    if (idealStateStatus == null || "OFFLINE".equals(idealStateStatus)) {
      continue;
    }

    // If the instance state is not ERROR and is not the same as what's expected from the ideal state, then it
    // hasn't finished starting up
    String currentStateStatus = partitionStateMap.get(partitionName);
    if (!idealStateStatus.equals(currentStateStatus)) {
      if ("ERROR".equals(currentStateStatus)) {
        LOGGER.error(String.format("Resource: %s, partition: %s is in ERROR state", resourceName, partitionName));
      } else {
        HelixProperty.Stat stat = helixState.getStat();
        String description = String
            .format("partition=%s, expected=%s, found=%s, creationTime=%d, modifiedTime=%d, version=%d",
                partitionName, idealStateStatus, currentStateStatus, stat != null ? stat.getCreationTime() : -1,
                stat != null ? stat.getModifiedTime() : -1, stat != null ? stat.getVersion() : -1);
        return new StatusDescriptionPair(Status.STARTING, description);
      }
    }
  }
  return new StatusDescriptionPair(Status.GOOD, STATUS_DESCRIPTION_NONE);
}