Search in sources :

Example 26 with LiveInstance

use of org.apache.helix.model.LiveInstance in project helix by apache.

the class ZKHelixAdmin method resetPartition.

@Override
public void resetPartition(String clusterName, String instanceName, String resourceName, List<String> partitionNames) {
    HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(_zkClient));
    Builder keyBuilder = accessor.keyBuilder();
    // check the instance is alive
    LiveInstance liveInstance = accessor.getProperty(keyBuilder.liveInstance(instanceName));
    if (liveInstance == null) {
        throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because " + instanceName + " is not alive");
    }
    // check resource group exists
    IdealState idealState = accessor.getProperty(keyBuilder.idealStates(resourceName));
    if (idealState == null) {
        throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because " + resourceName + " is not added");
    }
    // check partition exists in resource group
    Set<String> resetPartitionNames = new HashSet<String>(partitionNames);
    if (idealState.getRebalanceMode() == RebalanceMode.CUSTOMIZED) {
        Set<String> partitions = new HashSet<String>(idealState.getRecord().getMapFields().keySet());
        if (!partitions.containsAll(resetPartitionNames)) {
            throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because not all " + partitionNames + " exist");
        }
    } else {
        Set<String> partitions = new HashSet<String>(idealState.getRecord().getListFields().keySet());
        if (!partitions.containsAll(resetPartitionNames)) {
            throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because not all " + partitionNames + " exist");
        }
    }
    // check partition is in ERROR state
    String sessionId = liveInstance.getSessionId();
    CurrentState curState = accessor.getProperty(keyBuilder.currentState(instanceName, sessionId, resourceName));
    for (String partitionName : resetPartitionNames) {
        if (!curState.getState(partitionName).equals(HelixDefinedState.ERROR.toString())) {
            throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because not all " + partitionNames + " are in ERROR state");
        }
    }
    // check stateModelDef exists and get initial state
    String stateModelDef = idealState.getStateModelDefRef();
    StateModelDefinition stateModel = accessor.getProperty(keyBuilder.stateModelDef(stateModelDef));
    if (stateModel == null) {
        throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because " + stateModelDef + " is NOT found");
    }
    // check there is no pending messages for the partitions exist
    List<Message> messages = accessor.getChildValues(keyBuilder.messages(instanceName));
    for (Message message : messages) {
        if (!MessageType.STATE_TRANSITION.name().equalsIgnoreCase(message.getMsgType()) || !sessionId.equals(message.getTgtSessionId()) || !resourceName.equals(message.getResourceName()) || !resetPartitionNames.contains(message.getPartitionName())) {
            continue;
        }
        throw new HelixException("Can't reset state for " + resourceName + "/" + partitionNames + " on " + instanceName + ", because a pending message exists: " + message);
    }
    String adminName = null;
    try {
        adminName = InetAddress.getLocalHost().getCanonicalHostName() + "-ADMIN";
    } catch (UnknownHostException e) {
        // can ignore it
        logger.info("Unable to get host name. Will set it to UNKNOWN, mostly ignorable", e);
        adminName = "UNKNOWN";
    }
    List<Message> resetMessages = new ArrayList<Message>();
    List<PropertyKey> messageKeys = new ArrayList<PropertyKey>();
    for (String partitionName : resetPartitionNames) {
        // send ERROR to initialState message
        String msgId = UUID.randomUUID().toString();
        Message message = new Message(MessageType.STATE_TRANSITION, msgId);
        message.setSrcName(adminName);
        message.setTgtName(instanceName);
        message.setMsgState(MessageState.NEW);
        message.setPartitionName(partitionName);
        message.setResourceName(resourceName);
        message.setTgtSessionId(sessionId);
        message.setStateModelDef(stateModelDef);
        message.setFromState(HelixDefinedState.ERROR.toString());
        message.setToState(stateModel.getInitialState());
        message.setStateModelFactoryName(idealState.getStateModelFactoryName());
        if (idealState.getResourceGroupName() != null) {
            message.setResourceGroupName(idealState.getResourceGroupName());
        }
        if (idealState.getInstanceGroupTag() != null) {
            message.setResourceTag(idealState.getInstanceGroupTag());
        }
        resetMessages.add(message);
        messageKeys.add(keyBuilder.message(instanceName, message.getId()));
    }
    accessor.setChildren(messageKeys, resetMessages);
}
Also used : Message(org.apache.helix.model.Message) UnknownHostException(java.net.UnknownHostException) Builder(org.apache.helix.PropertyKey.Builder) PropertyPathBuilder(org.apache.helix.PropertyPathBuilder) ArrayList(java.util.ArrayList) IdealState(org.apache.helix.model.IdealState) HelixException(org.apache.helix.HelixException) HelixDataAccessor(org.apache.helix.HelixDataAccessor) LiveInstance(org.apache.helix.model.LiveInstance) StateModelDefinition(org.apache.helix.model.StateModelDefinition) CurrentState(org.apache.helix.model.CurrentState) ZNRecord(org.apache.helix.ZNRecord) PropertyKey(org.apache.helix.PropertyKey) HashSet(java.util.HashSet)

Example 27 with LiveInstance

use of org.apache.helix.model.LiveInstance in project helix by apache.

the class ZKHelixManager method isLeader.

@Override
public boolean isLeader() {
    if (_instanceType != InstanceType.CONTROLLER && _instanceType != InstanceType.CONTROLLER_PARTICIPANT) {
        return false;
    }
    if (!isConnected()) {
        return false;
    }
    try {
        LiveInstance leader = _dataAccessor.getProperty(_keyBuilder.controllerLeader());
        if (leader != null) {
            String leaderName = leader.getInstanceName();
            String sessionId = leader.getSessionId();
            if (leaderName != null && leaderName.equals(_instanceName) && sessionId != null && sessionId.equals(_sessionId)) {
                return true;
            }
        }
    } catch (Exception e) {
    // log
    }
    return false;
}
Also used : LiveInstance(org.apache.helix.model.LiveInstance) UnknownHostException(java.net.UnknownHostException) JMException(javax.management.JMException)

Example 28 with LiveInstance

use of org.apache.helix.model.LiveInstance in project helix by apache.

the class DefaultMessagingService method generateMessage.

public Map<InstanceType, List<Message>> generateMessage(final Criteria recipientCriteria, final Message message) {
    Map<InstanceType, List<Message>> messagesToSendMap = new HashMap<InstanceType, List<Message>>();
    InstanceType instanceType = recipientCriteria.getRecipientInstanceType();
    if (instanceType == InstanceType.CONTROLLER) {
        List<Message> messages = generateMessagesForController(message);
        messagesToSendMap.put(InstanceType.CONTROLLER, messages);
    // _dataAccessor.setControllerProperty(PropertyType.MESSAGES,
    // newMessage.getRecord(), CreateMode.PERSISTENT);
    } else if (instanceType == InstanceType.PARTICIPANT) {
        List<Message> messages = new ArrayList<Message>();
        List<Map<String, String>> matchedList = _evaluator.evaluateCriteria(recipientCriteria, _manager);
        if (!matchedList.isEmpty()) {
            Map<String, String> sessionIdMap = new HashMap<String, String>();
            if (recipientCriteria.isSessionSpecific()) {
                HelixDataAccessor accessor = _manager.getHelixDataAccessor();
                Builder keyBuilder = accessor.keyBuilder();
                List<LiveInstance> liveInstances = accessor.getChildValues(keyBuilder.liveInstances());
                for (LiveInstance liveInstance : liveInstances) {
                    sessionIdMap.put(liveInstance.getInstanceName(), liveInstance.getSessionId());
                }
            }
            for (Map<String, String> map : matchedList) {
                String id = UUID.randomUUID().toString();
                Message newMessage = new Message(message.getRecord(), id);
                String srcInstanceName = _manager.getInstanceName();
                String tgtInstanceName = map.get("instanceName");
                // Don't send message to self
                if (recipientCriteria.isSelfExcluded() && srcInstanceName.equalsIgnoreCase(tgtInstanceName)) {
                    continue;
                }
                newMessage.setSrcName(srcInstanceName);
                newMessage.setTgtName(tgtInstanceName);
                newMessage.setResourceName(map.get("resourceName"));
                newMessage.setPartitionName(map.get("partitionName"));
                if (recipientCriteria.isSessionSpecific()) {
                    newMessage.setTgtSessionId(sessionIdMap.get(tgtInstanceName));
                }
                messages.add(newMessage);
            }
            messagesToSendMap.put(InstanceType.PARTICIPANT, messages);
        }
    }
    return messagesToSendMap;
}
Also used : Message(org.apache.helix.model.Message) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConfigScopeBuilder(org.apache.helix.model.builder.ConfigScopeBuilder) Builder(org.apache.helix.PropertyKey.Builder) HelixDataAccessor(org.apache.helix.HelixDataAccessor) LiveInstance(org.apache.helix.model.LiveInstance) ArrayList(java.util.ArrayList) List(java.util.List) InstanceType(org.apache.helix.InstanceType) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 29 with LiveInstance

use of org.apache.helix.model.LiveInstance in project helix by apache.

the class DistributedLeaderElection method tryUpdateController.

private boolean tryUpdateController(HelixManager manager) {
    HelixDataAccessor accessor = manager.getHelixDataAccessor();
    Builder keyBuilder = accessor.keyBuilder();
    LiveInstance leader = new LiveInstance(manager.getInstanceName());
    try {
        leader.setLiveInstance(ManagementFactory.getRuntimeMXBean().getName());
        leader.setSessionId(manager.getSessionId());
        leader.setHelixVersion(manager.getVersion());
        boolean success = accessor.createControllerLeader(leader);
        if (success) {
            return true;
        } else {
            LOG.info("Unable to become leader probably because some other controller becames the leader");
        }
    } catch (Exception e) {
        LOG.error("Exception when trying to updating leader record in cluster:" + manager.getClusterName() + ". Need to check again whether leader node has been created or not", e);
    }
    leader = accessor.getProperty(keyBuilder.controllerLeader());
    if (leader != null) {
        String leaderSessionId = leader.getSessionId();
        LOG.info("Leader exists for cluster: " + manager.getClusterName() + ", currentLeader: " + leader.getInstanceName() + ", leaderSessionId: " + leaderSessionId);
        if (leaderSessionId != null && leaderSessionId.equals(manager.getSessionId())) {
            return true;
        }
    }
    return false;
}
Also used : HelixDataAccessor(org.apache.helix.HelixDataAccessor) LiveInstance(org.apache.helix.model.LiveInstance) Builder(org.apache.helix.PropertyKey.Builder)

Example 30 with LiveInstance

use of org.apache.helix.model.LiveInstance in project helix by apache.

the class ParticipantManager method createLiveInstance.

private void createLiveInstance() {
    String liveInstancePath = _keyBuilder.liveInstance(_instanceName).getPath();
    LiveInstance liveInstance = new LiveInstance(_instanceName);
    liveInstance.setSessionId(_sessionId);
    liveInstance.setHelixVersion(_manager.getVersion());
    liveInstance.setLiveInstance(ManagementFactory.getRuntimeMXBean().getName());
    // LiveInstanceInfoProvider liveInstanceInfoProvider = _manager._liveInstanceInfoProvider;
    if (_liveInstanceInfoProvider != null) {
        LOG.info("invoke liveInstanceInfoProvider");
        ZNRecord additionalLiveInstanceInfo = _liveInstanceInfoProvider.getAdditionalLiveInstanceInfo();
        if (additionalLiveInstanceInfo != null) {
            additionalLiveInstanceInfo.merge(liveInstance.getRecord());
            ZNRecord mergedLiveInstance = new ZNRecord(additionalLiveInstanceInfo, _instanceName);
            liveInstance = new LiveInstance(mergedLiveInstance);
            LOG.info("instanceName: " + _instanceName + ", mergedLiveInstance: " + liveInstance);
        }
    }
    boolean retry;
    do {
        retry = false;
        try {
            _zkclient.createEphemeral(liveInstancePath, liveInstance.getRecord());
            LOG.info("LiveInstance created, path: " + liveInstancePath + ", sessionId: " + liveInstance.getSessionId());
        } catch (ZkNodeExistsException e) {
            LOG.warn("found another instance with same instanceName: " + _instanceName + " in cluster " + _clusterName);
            Stat stat = new Stat();
            ZNRecord record = _zkclient.readData(liveInstancePath, stat, true);
            if (record == null) {
                /**
                 * live-instance is gone as we check it, retry create live-instance
                 */
                retry = true;
            } else {
                String ephemeralOwner = Long.toHexString(stat.getEphemeralOwner());
                if (ephemeralOwner.equals(_sessionId)) {
                    /**
                     * update sessionId field in live-instance if necessary
                     */
                    LiveInstance curLiveInstance = new LiveInstance(record);
                    if (!curLiveInstance.getSessionId().equals(_sessionId)) {
                        /**
                         * in last handle-new-session,
                         * live-instance is created by new zkconnection with stale session-id inside
                         * just update session-id field
                         */
                        LOG.info("overwriting session-id by ephemeralOwner: " + ephemeralOwner + ", old-sessionId: " + curLiveInstance.getSessionId() + ", new-sessionId: " + _sessionId);
                        curLiveInstance.setSessionId(_sessionId);
                        _zkclient.writeData(liveInstancePath, curLiveInstance.getRecord());
                    }
                } else {
                    /**
                     * wait for a while, in case previous helix-participant exits unexpectedly
                     * and its live-instance still hangs around until session timeout
                     */
                    try {
                        TimeUnit.MILLISECONDS.sleep(_sessionTimeout + 5000);
                    } catch (InterruptedException ex) {
                        LOG.warn("Sleep interrupted while waiting for previous live-instance to go away.", ex);
                    }
                    /**
                     * give a last try after exit while loop
                     */
                    retry = true;
                    break;
                }
            }
        }
    } while (retry);
    /**
     * give a last shot
     */
    if (retry) {
        try {
            _zkclient.createEphemeral(liveInstancePath, liveInstance.getRecord());
            LOG.info("LiveInstance created, path: " + liveInstancePath + ", sessionId: " + liveInstance.getSessionId());
        } catch (Exception e) {
            String errorMessage = "instance: " + _instanceName + " already has a live-instance in cluster " + _clusterName;
            LOG.error(errorMessage);
            throw new HelixException(errorMessage);
        }
    }
    ParticipantHistory history = getHistory();
    history.reportOnline(_sessionId, _manager.getVersion());
    persistHistory(history);
}
Also used : HelixException(org.apache.helix.HelixException) ZkNodeExistsException(org.I0Itec.zkclient.exception.ZkNodeExistsException) Stat(org.apache.zookeeper.data.Stat) LiveInstance(org.apache.helix.model.LiveInstance) ZNRecord(org.apache.helix.ZNRecord) HelixException(org.apache.helix.HelixException) ZkNodeExistsException(org.I0Itec.zkclient.exception.ZkNodeExistsException) ParticipantHistory(org.apache.helix.model.ParticipantHistory)

Aggregations

LiveInstance (org.apache.helix.model.LiveInstance)74 HelixDataAccessor (org.apache.helix.HelixDataAccessor)31 ZNRecord (org.apache.helix.ZNRecord)28 Builder (org.apache.helix.PropertyKey.Builder)25 Test (org.testng.annotations.Test)25 Date (java.util.Date)20 ZKHelixDataAccessor (org.apache.helix.manager.zk.ZKHelixDataAccessor)20 PropertyKey (org.apache.helix.PropertyKey)19 HashMap (java.util.HashMap)18 ArrayList (java.util.ArrayList)17 CurrentState (org.apache.helix.model.CurrentState)14 Message (org.apache.helix.model.Message)13 MockParticipantManager (org.apache.helix.integration.manager.MockParticipantManager)11 HelixManager (org.apache.helix.HelixManager)10 IdealState (org.apache.helix.model.IdealState)9 BestPossAndExtViewZkVerifier (org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier)9 HelixException (org.apache.helix.HelixException)8 InstanceConfig (org.apache.helix.model.InstanceConfig)7 ClusterStateVerifier (org.apache.helix.tools.ClusterStateVerifier)7 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)6