Search in sources :

Example 1 with StageComparator

use of com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator in project otter by alibaba.

the class ArbitrateViewServiceImpl method listProcesses.

public List<ProcessStat> listProcesses(Long channelId, Long pipelineId) {
    List<ProcessStat> processStats = new ArrayList<ProcessStat>();
    String processRoot = ManagePathUtils.getProcessRoot(channelId, pipelineId);
    IZkConnection connection = zookeeper.getConnection();
    // zkclient会将获取stat信息和正常的操作分开,使用原生的zk进行优化
    ZooKeeper orginZk = ((ZooKeeperx) connection).getZookeeper();
    // 获取所有的process列表
    List<String> processNodes = zookeeper.getChildren(processRoot);
    List<Long> processIds = new ArrayList<Long>();
    for (String processNode : processNodes) {
        processIds.add(ManagePathUtils.getProcessId(processNode));
    }
    Collections.sort(processIds);
    for (int i = 0; i < processIds.size(); i++) {
        Long processId = processIds.get(i);
        // 当前的process可能会有变化
        ProcessStat processStat = new ProcessStat();
        processStat.setPipelineId(pipelineId);
        processStat.setProcessId(processId);
        List<StageStat> stageStats = new ArrayList<StageStat>();
        processStat.setStageStats(stageStats);
        try {
            String processPath = ManagePathUtils.getProcess(channelId, pipelineId, processId);
            Stat zkProcessStat = new Stat();
            List<String> stages = orginZk.getChildren(processPath, false, zkProcessStat);
            Collections.sort(stages, new StageComparator());
            StageStat prev = null;
            for (String stage : stages) {
                // 循环每个process下的stage
                String stagePath = processPath + "/" + stage;
                Stat zkStat = new Stat();
                StageStat stageStat = new StageStat();
                stageStat.setPipelineId(pipelineId);
                stageStat.setProcessId(processId);
                byte[] bytes = orginZk.getData(stagePath, false, zkStat);
                if (bytes != null && bytes.length > 0) {
                    // 特殊处理zookeeper里的data信息,manager没有对应node中PipeKey的对象,所以导致反序列化会失败,需要特殊处理,删除'@'符号
                    String json = StringUtils.remove(new String(bytes, "UTF-8"), '@');
                    EtlEventData data = JsonUtils.unmarshalFromString(json, EtlEventData.class);
                    stageStat.setNumber(data.getNumber());
                    stageStat.setSize(data.getSize());
                    Map exts = new HashMap();
                    if (!CollectionUtils.isEmpty(data.getExts())) {
                        exts.putAll(data.getExts());
                    }
                    exts.put("currNid", data.getCurrNid());
                    exts.put("nextNid", data.getNextNid());
                    exts.put("desc", data.getDesc());
                    stageStat.setExts(exts);
                }
                if (prev != null) {
                    // 对应的start时间为上一个节点的结束时间
                    stageStat.setStartTime(prev.getEndTime());
                } else {
                    // process的最后修改时间,select
                    stageStat.setStartTime(zkProcessStat.getMtime());
                // await成功后会设置USED标志位
                }
                stageStat.setEndTime(zkStat.getMtime());
                if (ArbitrateConstants.NODE_SELECTED.equals(stage)) {
                    stageStat.setStage(StageType.SELECT);
                } else if (ArbitrateConstants.NODE_EXTRACTED.equals(stage)) {
                    stageStat.setStage(StageType.EXTRACT);
                } else if (ArbitrateConstants.NODE_TRANSFORMED.equals(stage)) {
                    stageStat.setStage(StageType.TRANSFORM);
                // } else if
                // (ArbitrateConstants.NODE_LOADED.equals(stage)) {
                // stageStat.setStage(StageType.LOAD);
                }
                prev = stageStat;
                stageStats.add(stageStat);
            }
            // 添加一个当前正在处理的
            StageStat currentStageStat = new StageStat();
            currentStageStat.setPipelineId(pipelineId);
            currentStageStat.setProcessId(processId);
            if (prev == null) {
                byte[] bytes = orginZk.getData(processPath, false, zkProcessStat);
                if (bytes == null || bytes.length == 0) {
                    // 直接认为未使用,忽略之
                    continue;
                }
                ProcessNodeEventData nodeData = JsonUtils.unmarshalFromByte(bytes, ProcessNodeEventData.class);
                if (nodeData.getStatus().isUnUsed()) {
                    // 跳过该process
                    continue;
                } else {
                    // select操作
                    currentStageStat.setStage(StageType.SELECT);
                    currentStageStat.setStartTime(zkProcessStat.getMtime());
                }
            } else {
                // 判断上一个节点,确定当前的stage
                StageType stage = prev.getStage();
                if (stage.isSelect()) {
                    currentStageStat.setStage(StageType.EXTRACT);
                } else if (stage.isExtract()) {
                    currentStageStat.setStage(StageType.TRANSFORM);
                } else if (stage.isTransform()) {
                    currentStageStat.setStage(StageType.LOAD);
                } else if (stage.isLoad()) {
                    // 已经是最后一个节点了
                    continue;
                }
                // 开始时间为上一个节点的结束时间
                currentStageStat.setStartTime(prev.getEndTime());
            }
            if (currentStageStat.getStage().isLoad()) {
                // load必须为第一个process节点
                if (i == 0) {
                    stageStats.add(currentStageStat);
                }
            } else {
                // 其他情况都添加
                stageStats.add(currentStageStat);
            }
        } catch (NoNodeException e) {
        // ignore
        } catch (KeeperException e) {
            throw new ArbitrateException(e);
        } catch (InterruptedException e) {
        // ignore
        } catch (UnsupportedEncodingException e) {
        // ignore
        }
        processStats.add(processStat);
    }
    return processStats;
}
Also used : NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProcessStat(com.alibaba.otter.shared.common.model.statistics.stage.ProcessStat) Stat(org.apache.zookeeper.data.Stat) StageStat(com.alibaba.otter.shared.common.model.statistics.stage.StageStat) StageType(com.alibaba.otter.shared.common.model.config.enums.StageType) ZooKeeperx(com.alibaba.otter.shared.common.utils.zookeeper.ZooKeeperx) ProcessNodeEventData(com.alibaba.otter.shared.arbitrate.model.ProcessNodeEventData) StageComparator(com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator) IZkConnection(org.I0Itec.zkclient.IZkConnection) UnsupportedEncodingException(java.io.UnsupportedEncodingException) EtlEventData(com.alibaba.otter.shared.arbitrate.model.EtlEventData) ZooKeeper(org.apache.zookeeper.ZooKeeper) ProcessStat(com.alibaba.otter.shared.common.model.statistics.stage.ProcessStat) ArbitrateException(com.alibaba.otter.shared.arbitrate.exception.ArbitrateException) StageStat(com.alibaba.otter.shared.common.model.statistics.stage.StageStat) HashMap(java.util.HashMap) Map(java.util.Map) KeeperException(org.apache.zookeeper.KeeperException)

Example 2 with StageComparator

use of com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator in project otter by alibaba.

the class StageMonitor method initProcessStage.

/**
     * 处理指定的processId变化,返回结果true代表需要继续监听,false代表不需要监视
     */
private boolean initProcessStage(Long processId, List<String> currentStages) {
    Collections.sort(currentStages, new StageComparator());
    if (logger.isDebugEnabled()) {
        logger.debug("pipeline[{}] processId[{}] with stage{}", new Object[] { getPipelineId(), processId, currentStages });
    }
    // 更新下stage数据
    this.currentStages.put(processId, currentStages);
    // 通知stage变化
    stageChanged(processId, currentStages);
    // 2.1 判断是否存在了loaded节点,此节点为最后一个节点
    if (currentStages.contains(ArbitrateConstants.NODE_TRANSFORMED)) {
        // 不需要监听了
        return true;
    } else {
        // 其他的状态需要监听
        return false;
    }
}
Also used : StageComparator(com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator)

Example 3 with StageComparator

use of com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator in project otter by alibaba.

the class StageMonitor method syncStage.

// /**
// * 监听process的新增/删除变化,触发process列表的更新
// */
// private void syncStage() {
// // 1. 根据pipelineId构造对应的path
// String path = null;
// try {
// path = StagePathUtils.getProcessRoot(getPipelineId());
// // 2. 监听当前的process列表的变化
// List<String> currentProcesses = zookeeper.getChildren(path, new AsyncWatcher() {
//
// public void asyncProcess(WatchedEvent event) {
// MDC.put(ArbitrateConstants.splitPipelineLogFileKey, String.valueOf(getPipelineId()));
// if (isStop()) {
// return;
// }
//
// // 出现session expired/connection losscase下,会触发所有的watcher响应,同时老的watcher会继续保留,所以会导致出现多次watcher响应
// boolean dataChanged = event.getType() == EventType.NodeDataChanged
// || event.getType() == EventType.NodeDeleted
// || event.getType() == EventType.NodeCreated
// || event.getType() == EventType.NodeChildrenChanged;
// if (dataChanged) {
// syncStage(); // 继续监听
// // initStage(); // 重新更新
// }
// }
// });
//
// // 3. 循环处理每个process
// List<Long> processIds = new ArrayList<Long>();
// for (String process : currentProcesses) {
// processIds.add(StagePathUtils.getProcessId(process));
// }
//
// Collections.sort(processIds); // 排序一下
// // 判断一下当前processIds和当前内存中的记录是否有差异,如果有差异立马触发一下
// if (!currentProcessIds.equals(processIds)) {
// initStage(); // 立马触发一下
// }
// } catch (KeeperException e) {
// syncStage(); // 继续监听
// } catch (InterruptedException e) {
// // ignore
// }
// }
/**
     * 监听指定的processId节点的变化
     */
private void syncStage(final Long processId) {
    // 1. 根据pipelineId + processId构造对应的path
    String path = null;
    try {
        path = StagePathUtils.getProcess(getPipelineId(), processId);
        // 2. 监听当前的process列表的变化
        IZkConnection connection = zookeeper.getConnection();
        // zkclient包装的是一个持久化的zk,分布式lock只需要一次性的watcher,需要调用原始的zk链接进行操作
        ZooKeeper orginZk = ((ZooKeeperx) connection).getZookeeper();
        List<String> currentStages = orginZk.getChildren(path, new AsyncWatcher() {

            public void asyncProcess(WatchedEvent event) {
                MDC.put(ArbitrateConstants.splitPipelineLogFileKey, String.valueOf(getPipelineId()));
                if (isStop()) {
                    return;
                }
                if (event.getType() == EventType.NodeDeleted) {
                    // 触发下节点删除
                    processTermined(processId);
                    return;
                }
                // 出现session expired/connection losscase下,会触发所有的watcher响应,同时老的watcher会继续保留,所以会导致出现多次watcher响应
                boolean dataChanged = event.getType() == EventType.NodeDataChanged || event.getType() == EventType.NodeDeleted || event.getType() == EventType.NodeCreated || event.getType() == EventType.NodeChildrenChanged;
                if (dataChanged) {
                    // boolean reply = initStage(processId);
                    // if (reply == false) {// 出现过load后就不需要再监听变化,剩下的就是节点的删除操作
                    syncStage(processId);
                // }
                }
            }
        });
        Collections.sort(currentStages, new StageComparator());
        List<String> lastStages = this.currentStages.get(processId);
        if (lastStages == null || !lastStages.equals(currentStages)) {
            // 存在差异,立马触发一下
            initProcessStage(processId);
        }
    } catch (NoNodeException e) {
        // 触发下节点删除
        processTermined(processId);
    } catch (KeeperException e) {
        syncStage(processId);
    } catch (InterruptedException e) {
    // ignore
    }
}
Also used : WatchedEvent(org.apache.zookeeper.WatchedEvent) StageComparator(com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator) ZooKeeper(org.apache.zookeeper.ZooKeeper) ZkNoNodeException(org.I0Itec.zkclient.exception.ZkNoNodeException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) IZkConnection(org.I0Itec.zkclient.IZkConnection) ZooKeeperx(com.alibaba.otter.shared.common.utils.zookeeper.ZooKeeperx) KeeperException(org.apache.zookeeper.KeeperException) AsyncWatcher(com.alibaba.otter.shared.arbitrate.impl.zookeeper.AsyncWatcher)

Example 4 with StageComparator

use of com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator in project otter by alibaba.

the class NormalTerminProcess method doProcess.

private boolean doProcess(TerminEventData data, boolean retry) {
    Long pipelineId = data.getPipelineId();
    Long processId = data.getProcessId();
    List<String> currentStages = null;
    try {
        currentStages = zookeeper.getChildren(StagePathUtils.getProcess(pipelineId, processId));
        Collections.sort(currentStages, new StageComparator());
    } catch (ZkNoNodeException e) {
        // ignore,说明节点已经被删除了
        return false;
    } catch (ZkException e) {
        throw new ArbitrateException("Termin_process", e);
    }
    // s节点
    if (currentStages == null || currentStages.contains(ArbitrateConstants.NODE_SELECTED)) {
        try {
            boolean successed = zookeeper.delete(StagePathUtils.getSelectStage(pipelineId, processId));
            if (!successed) {
                processDeleteFailed();
            }
        } catch (ZkException e) {
            throw new ArbitrateException("Termin_process", e);
        }
    }
    // e节点
    if (currentStages == null || currentStages.contains(ArbitrateConstants.NODE_EXTRACTED)) {
        try {
            boolean successed = zookeeper.delete(StagePathUtils.getExtractStage(pipelineId, processId));
            if (!successed) {
                processDeleteFailed();
            }
        } catch (ZkException e) {
            throw new ArbitrateException("Termin_process", e);
        }
    }
    // t节点
    if (currentStages == null || currentStages.contains(ArbitrateConstants.NODE_TRANSFORMED)) {
        try {
            boolean successed = zookeeper.delete(StagePathUtils.getTransformStage(pipelineId, processId));
            if (!successed) {
                processDeleteFailed();
            }
        } catch (ZkException e) {
            throw new ArbitrateException("Termin_process", e);
        }
    }
    // 不过会有遗漏判断,比如并发时都是一个线程全删除成功
    return processDelete(data, CollectionUtils.isEmpty(currentStages), retry);
}
Also used : StageComparator(com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator) ZkNoNodeException(org.I0Itec.zkclient.exception.ZkNoNodeException) ZkException(org.I0Itec.zkclient.exception.ZkException) ArbitrateException(com.alibaba.otter.shared.arbitrate.exception.ArbitrateException)

Aggregations

StageComparator (com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator)4 ArbitrateException (com.alibaba.otter.shared.arbitrate.exception.ArbitrateException)2 ZooKeeperx (com.alibaba.otter.shared.common.utils.zookeeper.ZooKeeperx)2 IZkConnection (org.I0Itec.zkclient.IZkConnection)2 ZkNoNodeException (org.I0Itec.zkclient.exception.ZkNoNodeException)2 KeeperException (org.apache.zookeeper.KeeperException)2 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)2 ZooKeeper (org.apache.zookeeper.ZooKeeper)2 AsyncWatcher (com.alibaba.otter.shared.arbitrate.impl.zookeeper.AsyncWatcher)1 EtlEventData (com.alibaba.otter.shared.arbitrate.model.EtlEventData)1 ProcessNodeEventData (com.alibaba.otter.shared.arbitrate.model.ProcessNodeEventData)1 StageType (com.alibaba.otter.shared.common.model.config.enums.StageType)1 ProcessStat (com.alibaba.otter.shared.common.model.statistics.stage.ProcessStat)1 StageStat (com.alibaba.otter.shared.common.model.statistics.stage.StageStat)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ZkException (org.I0Itec.zkclient.exception.ZkException)1 WatchedEvent (org.apache.zookeeper.WatchedEvent)1