- flush thread start
- When regionserver start, calls the method startServiceThread start some service threads, which
private void startServiceThreads() throws IOException { 。。。。其他代码省略。。。 this.cacheFlusher.start(uncaughtExceptionHandler); }
It is an example of the cacheFlusher MemStoreFlusher class from start as follows:
synchronized void start(UncaughtExceptionHandler eh) { ThreadFactory flusherThreadFactory = Threads.newDaemonThreadFactory( server.getServerName().toShortString() + "-MemStoreFlusher", eh); for (int i = 0; i < flushHandlers.length; i++) { flushHandlers[i] = new FlushHandler("MemStoreFlusher." + i); flusherThreadFactory.newThread(flushHandlers[i]); flushHandlers[i].start(); } }
It generates a corresponding number of threads according to the configuration flush flusher.handler.count. Then start method is called for each flush thread. We continue to look at flushHandler.
{class FlushHandler the extends HasThread Private @Override public void RUN () { // If the server does not normally STOP the while (server.isStopped ()!) { FlushQueueEntry fqe = null; the try { wakeupPending.set (to false); // the allow someone to Again up US Wake // queue blocking poll method, if there is no clog in this fqe = flushQueue.poll (threadWakeFrequency, TimeUnit.MILLISECONDS);
// if this is not flush, or a global flush request
@ wherein a is wakeupFlushThread flushQueueEntry IF (fqe == null || fqe the instanceof WakeupFlushThread) {
// if it exceeds the minimum threshold of the configuration of mem if (isAboveLowWaterMark ()) { lOG.debug ( "Flush thread woke up because memory above low water =" + TraditionalBinaryPrefix.long2String(globalMemStoreLimitLowMark, "", 1));
if (!flushOneForGlobalPressure()) { // Wasn't able to flush any region, but we're above low water mark // This is unlikely to happen, but might happen when closing the // entire server - another thread is flushing regions. We'll just // sleep a little bit to avoid spinning, and then pretend that // we flushed one, so anyone blocked will check again Thread.sleep(1000); wakeUpIfBlocking(); } // Enqueue another one of these tokens so we'll wake up again wakeupFlushThread(); } //即使阻塞超时后也会继续continue Continue; } // have flushQueue flushrequest, is performed flushRegion FlushRegionEntry FRE = (FlushRegionEntry) fqe; IF {(flushRegion (FRE)!) BREAK; } } the catch (InterruptedException EX) { Continue; } the catch (a ConcurrentModificationException EX) { continue; } catch (Exception ex) { LOG.error("Cache flusher failed for entry " + fqe, ex); IF (! server.checkFileSystem ()) { BREAK; } } }
executes // end memstoreflusher thread calls, generally STOP rs the synchronized (regionsInQueue) { regionsInQueue.clear (); flushQueue.clear (); } // Signal anyone waiting, so they see the close flag wakeUpIfBlocking(); LOG.info(getName() + " exiting"); } }
Before combing two variables of the logic introduces the MemStoreFlusher
// This variable is a BlockingQueue <FlushQueueEntry> type variable. // primarily stores the refresh request type FlushRegionEntry example, and a wake-up queue WakeupFlushThread instance object. Final BlockingQueue Private <FlushQueueEntry> = flushQueue new new a DelayQueue <FlushQueueEntry> (); // will also be added to the requst flushqueue is added to the regionsInQueue. Final the Map Private <HRegion, FlushRegionEntry> = regionsInQueue new new the HashMap <HRegion, FlushRegionEntry> ();
Now we look at is look at the logical method of FlusherHandler run, the code is not posted, in the above
- As long as rs not linked, there is no judge has been circulating flushrequest
- Be blocked by flushqueue.poll, should flushqueue is blocking queue, when the queue is empty blocks until the timeout.
- If not empty, take out a request, call MemStoreFlusher.flushRegion (fre)