package com.alibaba.doris.dataserver.migrator.task; import java.util.Iterator; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.doris.common.data.Pair; import com.alibaba.doris.dataserver.migrator.task.migrate.ExitPair; import com.alibaba.doris.dataserver.store.ClosableIterator; import com.alibaba.doris.dataserver.store.Storage; /** * 读取数据的线程,由于多个线程同时读取数据会造成严重的锁冲突,<br> * 因此将读数据转移到专门的数据读取线程来执行。 * * @author ajun Email:jack.yuj@alibaba-inc.com */ public class ReadDataThread implements Callable<Integer> { public ReadDataThread(Storage storage, List<Integer> vnodeList, BlockingQueue<Pair> dataQueue, int consumerThreadNum) { this.storage = storage; this.vnodeList = vnodeList; this.dataQueue = dataQueue; this.consumerThreadNum = consumerThreadNum; } public Integer call() throws Exception { Iterator<Pair> pairItor = storage.iterator(vnodeList); int nRecords = 0; ClosableIterator<Pair> closablePairItor = (ClosableIterator<Pair>) pairItor; if (null != closablePairItor) { try { while (isRunning && closablePairItor.hasNext()) { nRecords++; dataQueue.put(closablePairItor.next()); } } catch (Exception e) { logger.error("ReadDataThread", e); } finally { closablePairItor.close(); } } notifyExitConsumerThread(); return nRecords; } /** * 通知所有迁移数据线程,终止迁移; */ private void notifyExitConsumerThread() { for (int i = 0; i < consumerThreadNum; i++) { try { dataQueue.put(new ExitPair()); } catch (InterruptedException e) { logger.error("notifyExitConsumerThread", e); } } } /** * 通知读数据线程,终止并退出读数据线程; */ public void stopReadThread() { int dataQueueSize = dataQueue.size(); if (dataQueueSize > 0) { logger.error("The migration queue is not empty after all mitration task have finished; Cleaning the queue. Queue size:" + dataQueueSize); dataQueue.clear(); } isRunning = false; } private List<Integer> vnodeList; private Storage storage; private BlockingQueue<Pair> dataQueue; private volatile boolean isRunning = true; private int consumerThreadNum; protected Logger logger = LoggerFactory.getLogger(ReadDataThread.class); }