package com.alibaba.doris.admin.service.common.migrate; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.alibaba.doris.admin.core.AdminServiceLocator; import com.alibaba.doris.admin.monitor.MonitorEnum; import com.alibaba.doris.admin.monitor.SystemLogMonitor; import com.alibaba.doris.admin.service.AdminNodeService; import com.alibaba.doris.admin.service.common.migrate.manager.MigrateManager; import com.alibaba.doris.admin.service.common.migrate.status.MigrateStatus; import com.alibaba.doris.admin.service.common.migrate.status.MigrateStatusCallback; import com.alibaba.doris.admin.service.common.migrate.status.MigrateStatusMonitorThread; import com.alibaba.doris.admin.service.common.node.NodesManager; import com.alibaba.doris.admin.service.common.route.DorisConfigServiceException; import com.alibaba.doris.admin.service.common.route.RouteConfigProcessor; import com.alibaba.doris.common.MonitorWarnConstants; /** * 迁移线程基类 * * @author frank */ public abstract class MigrateThread extends Thread implements MigrateStatusCallback { private static final Log log = LogFactory.getLog(MigrateThread.class); protected boolean isGoOn = true; protected static final int sleepTime = 1000; protected MigrateStatusMonitorThread monitorThread; protected List<MigrateStatus> statusList = new ArrayList<MigrateStatus>(); protected String migrateKey; protected boolean needMigrate = true; // 某些情况(扩容迁移源为null)不需要迁移数据,直接更新节点状态 protected AdminNodeService nodeService = AdminServiceLocator.getAdminNodeService(); public abstract List<String> getMigeratingNodePhysicalIdList(); public boolean redo() { return sendMigerateCommand(); } public void run() { if (needMigrate) { if (!basicCommand()) { this.over(); return; } monitorThread = new MigrateStatusMonitorThread(statusList, this); monitorThread.start(); while (isGoOn) { try { sleep(sleepTime); } catch (InterruptedException e) { log.error("", e); } } } else { updateStoreNode(); NodesManager.getInstance().reLoadNodes(); if (log.isDebugEnabled()) { log.debug("Don't need migrate, but need refresh route. "); } try { RouteConfigProcessor.getInstance().refresh();//不是必须的 } catch (DorisConfigServiceException e) { SystemLogMonitor.error(MonitorEnum.ROUTER, MonitorWarnConstants.RE_GEN_ROUTE_FAILED, e); log.error("ERROR IN REFRESH CONFIG TABLE."); } } } public synchronized void over() { if (monitorThread != null) { monitorThread.over();// 不是多余 } // 从迁移管理器移除迁移线程 MigrateManager.getInstance().removeMigerateThread(migrateKey); isGoOn = false; } /** * 发送迁移命令,并更新NodeManager<br> * * @return 命令是否成功发送:扩容的时候,只要有一个成功就算成功,恢复的时候,全部成功才算成功 */ protected boolean basicCommand() { boolean result = sendMigerateCommand(); MigrateManager.getInstance().addMigerateThread(migrateKey, this); return result; } protected abstract boolean sendMigerateCommand(); public void finishAll() { // 关闭监控线程,尽早关闭,否则可能会再callback finishAll monitorThread.over(); if (log.isInfoEnabled()) { log.info("migerate in " + migrateKey + " finished."); } updateStoreNode(); NodesManager.getInstance().reLoadNodes(); // 刷新配置实例 try { RouteConfigProcessor.getInstance().refresh(); } catch (DorisConfigServiceException e) { log.error("ERROR IN REFRESH CONFIG TABLE. NOT FINIS MIGRATE."); SystemLogMonitor.error(MonitorEnum.ROUTER, MonitorWarnConstants.RE_GEN_ROUTE_FAILED, e); } sendMigerateFinishCommand(); // 自我终结 this.over(); } /** * 更新失效节点状态 */ protected abstract void updateStoreNode(); /** * 通知迁移节点迁移结束 */ protected abstract void sendMigerateFinishCommand(); }