From 40a4030b553b38d946881a0e6e8f57e0cffbd133 Mon Sep 17 00:00:00 2001 From: sixcooler Date: Tue, 21 Jan 2014 17:04:22 +0100 Subject: [PATCH] configurable max-load values for YaCy-Threads: try lower values on smal systems like a Pi --- defaults/yacy.init | 9 +++++++++ htroot/PerformanceQueues_p.html | 2 ++ htroot/PerformanceQueues_p.java | 13 +++++++++---- htroot/PerformanceQueues_p.xml | 1 + .../net/yacy/kelondro/util/MemoryControl.java | 10 ++++++++++ .../kelondro/workflow/AbstractBusyThread.java | 11 +++++++++++ .../net/yacy/kelondro/workflow/BusyThread.java | 6 ++++++ .../kelondro/workflow/InstantBusyThread.java | 1 + source/net/yacy/search/Switchboard.java | 3 ++- .../net/yacy/search/SwitchboardConstants.java | 3 +++ source/net/yacy/server/serverSwitch.java | 18 +++++++++++++++--- 11 files changed, 69 insertions(+), 8 deletions(-) diff --git a/defaults/yacy.init b/defaults/yacy.init index f24c158ee..615c69f14 100644 --- a/defaults/yacy.init +++ b/defaults/yacy.init @@ -598,33 +598,42 @@ collection=user 20_dhtdistribution_idlesleep=30000 20_dhtdistribution_busysleep=15000 20_dhtdistribution_memprereq=12582912 +20_dhtdistribution_loadprereq=2.0 30_peerping_idlesleep=30000 30_peerping_busysleep=30000 30_peerping_memprereq=2097152 +30_peerping_loadprereq=2.0 40_peerseedcycle_idlesleep=1800000 40_peerseedcycle_busysleep=1200000 40_peerseedcycle_memprereq=4194304 +40_peerseedcycle_loadprereq=2.0 50_localcrawl_idlesleep=2000 50_localcrawl_busysleep=10 50_localcrawl_memprereq=12582912 +50_localcrawl_loadprereq=2.0 50_localcrawl_isPaused=false 60_remotecrawlloader_idlesleep=4000 60_remotecrawlloader_busysleep=800 60_remotecrawlloader_memprereq=12582912 +60_remotecrawlloader_loadprereq=2.0 60_remotecrawlloader_isPaused=false 62_remotetriggeredcrawl_idlesleep=2000 62_remotetriggeredcrawl_busysleep=200 62_remotetriggeredcrawl_memprereq=12582912 +62_remotetriggeredcrawl_loadprereq=2.0 62_remotetriggeredcrawl_isPaused=false 70_surrogates_idlesleep=10000 70_surrogates_busysleep=0 70_surrogates_memprereq=12582912 +70_surrogates_loadprereq=2.0 80_searchresult_idlesleep=10000 80_searchresult_busysleep=200 80_searchresult_memprereq=0 +80_searchresult_loadprereq=2.0 90_cleanup_idlesleep=300000 90_cleanup_busysleep=300000 90_cleanup_memprereq=0 +90_cleanup_loadprereq=3.0 # additional attributes: # performanceIO is a percent-value. a value of 10 means, that 10% of the busysleep time diff --git a/htroot/PerformanceQueues_p.html b/htroot/PerformanceQueues_p.html index afdbeb5d1..6cf5ce64d 100644 --- a/htroot/PerformanceQueues_p.html +++ b/htroot/PerformanceQueues_p.html @@ -29,6 +29,7 @@ Delay between
idle loops Delay between
busy loops Minimum of
Required Memory + Maximum of
System-Load Full Description #{table}# @@ -51,6 +52,7 @@ milliseconds milliseconds kbytes + load #[longdescr]##(recommendation)#::
recommended: #[value]# kbytes#(/recommendation)# #{/table}# diff --git a/htroot/PerformanceQueues_p.java b/htroot/PerformanceQueues_p.java index 58d555029..9de319a04 100644 --- a/htroot/PerformanceQueues_p.java +++ b/htroot/PerformanceQueues_p.java @@ -119,6 +119,7 @@ public class PerformanceQueues_p { // set templates for latest news from the threads long blocktime, sleeptime, exectime; long idlesleep, busysleep, memuse, memprereq; + double loadprereq; int queuesize; threads = sb.threadNames(); int c = 0; @@ -177,18 +178,21 @@ public class PerformanceQueues_p { idlesleep = sb.getConfigLong(threadName + "_idlesleep" , 1000); busysleep = sb.getConfigLong(threadName + "_busysleep", 100); memprereq = sb.getConfigLong(threadName + "_memprereq", 0); + loadprereq = sb.getConfigFloat(threadName + "_loadprereq", 9); if (setDelay && post != null) { // load with new values idlesleep = post.getLong(threadName + "_idlesleep", idlesleep); busysleep = post.getLong(threadName + "_busysleep", busysleep); memprereq = post.getLong(threadName + "_memprereq", memprereq) * 1024l; if (memprereq == 0) memprereq = sb.getConfigLong(threadName + "_memprereq", 0); + loadprereq = post.getDouble(threadName + "_loadprereq", loadprereq); + if (loadprereq == 0) loadprereq = sb.getConfigFloat(threadName + "_loadprereq", 9); // check values to prevent short-cut loops if (idlesleep < 1000) idlesleep = 1000; - if (threadName.equals("10_httpd")) { idlesleep = 0; busysleep = 0; memprereq = 0; } + if (threadName.equals("10_httpd")) { idlesleep = 0; busysleep = 0; memprereq = 0; loadprereq = 9; } - sb.setThreadPerformance(threadName, idlesleep, busysleep, memprereq); + sb.setThreadPerformance(threadName, idlesleep, busysleep, memprereq, loadprereq); idlesleep = sb.getConfigLong(threadName + "_idlesleep", idlesleep); busysleep = sb.getConfigLong(threadName + "_busysleep", busysleep); } @@ -205,14 +209,15 @@ public class PerformanceQueues_p { // check values to prevent short-cut loops if (idlesleep < 1000) idlesleep = 1000; - if (threadName.equals("10_httpd")) { idlesleep = 0; busysleep = 0; memprereq = 0; } + if (threadName.equals("10_httpd")) { idlesleep = 0; busysleep = 0; memprereq = 0; loadprereq = 9; } //if (threadName.equals(plasmaSwitchboardConstants.CRAWLJOB_LOCAL_CRAWL) && (busysleep < 50)) busysleep = 50; - sb.setThreadPerformance(threadName, idlesleep, busysleep, memprereq); + sb.setThreadPerformance(threadName, idlesleep, busysleep, memprereq, loadprereq); } } prop.put("table_" + c + "_idlesleep", idlesleep); prop.put("table_" + c + "_busysleep", busysleep); prop.put("table_" + c + "_memprereq", memprereq / 1024); + prop.put("table_" + c + "_loadprereq", loadprereq); // disallow setting of memprereq for indexer to prevent db from throwing OOMs // prop.put("table_" + c + "_disabled", /*(threadName.endsWith("_indexing")) ? 1 :*/ "0"); prop.put("table_" + c + "_disabled", threadName.equals("10_httpd") ? "1" : "0" ); // httpd hardcoded defaults diff --git a/htroot/PerformanceQueues_p.xml b/htroot/PerformanceQueues_p.xml index e7fc14d95..bef61d6d6 100644 --- a/htroot/PerformanceQueues_p.xml +++ b/htroot/PerformanceQueues_p.xml @@ -20,6 +20,7 @@ #[idlesleep]# #[busysleep]# #[memprereq]# + #[loadprereq]# recommended: #[value]##(/recommendation)#]]> #{/table}# diff --git a/source/net/yacy/kelondro/util/MemoryControl.java b/source/net/yacy/kelondro/util/MemoryControl.java index f3c9c0781..09b2c18dc 100644 --- a/source/net/yacy/kelondro/util/MemoryControl.java +++ b/source/net/yacy/kelondro/util/MemoryControl.java @@ -25,6 +25,8 @@ package net.yacy.kelondro.util; +import java.lang.management.ManagementFactory; + /** * Use this to get information about memory usage or try to free some memory */ @@ -174,6 +176,14 @@ public class MemoryControl { public static void setProperMbyte(final long mbyte) { getStrategy().setProperMbyte(mbyte); } + + /** + * get the system load within the last minute + * @return the system load or a negative number if the load is not available + */ + public static double load() { + return ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage(); + } /** * main diff --git a/source/net/yacy/kelondro/workflow/AbstractBusyThread.java b/source/net/yacy/kelondro/workflow/AbstractBusyThread.java index 298afa0ad..4b1fe7b01 100644 --- a/source/net/yacy/kelondro/workflow/AbstractBusyThread.java +++ b/source/net/yacy/kelondro/workflow/AbstractBusyThread.java @@ -37,6 +37,7 @@ public abstract class AbstractBusyThread extends AbstractThread implements BusyT private long startup = 0, intermission = 0, idlePause = 0, busyPause = 0; private long idletime = 0, memprereq = 0; private long idleCycles = 0, busyCycles = 0, outofmemoryCycles = 0; + private double loadprereq = 9; private boolean intermissionObedient = true; private final Object syncObject = new Object(); @@ -84,6 +85,11 @@ public abstract class AbstractBusyThread extends AbstractThread implements BusyT memprereq = freeBytes; } + public void setLoadPreReqisite(final double load) { + // sets minimum required amount of memory for the job execution + loadprereq = load; + } + public void setObeyIntermission(final boolean obey) { // defines if the thread should obey the intermission command intermissionObedient = obey; @@ -158,6 +164,11 @@ public abstract class AbstractBusyThread extends AbstractThread implements BusyT ratz(this.idlePause); idletime += System.currentTimeMillis() - timestamp; //} else if ((memnow = serverMemory.available()) > memprereq) try { + } else if (MemoryControl.load() > loadprereq) { + logSystem("Thread '" + this.getName() + "' runs high load cycle. current: " + MemoryControl.load() + " max.: " + loadprereq); + timestamp = System.currentTimeMillis(); + ratz(this.idlePause); + idletime += System.currentTimeMillis() - timestamp; } else if (MemoryControl.request(memprereq, false)) try { // do job timestamp = System.currentTimeMillis(); diff --git a/source/net/yacy/kelondro/workflow/BusyThread.java b/source/net/yacy/kelondro/workflow/BusyThread.java index 1b559c947..200f7bd79 100644 --- a/source/net/yacy/kelondro/workflow/BusyThread.java +++ b/source/net/yacy/kelondro/workflow/BusyThread.java @@ -64,6 +64,12 @@ public interface BusyThread extends WorkflowThread { * @param freeBytes */ public void setMemPreReqisite(long freeBytes); + + /** + * sets maximimum load for the job execution + * @param load + */ + public void setLoadPreReqisite(final double load); /** * defines if the thread should obey the intermission command diff --git a/source/net/yacy/kelondro/workflow/InstantBusyThread.java b/source/net/yacy/kelondro/workflow/InstantBusyThread.java index e8c3df3c5..846f5e669 100644 --- a/source/net/yacy/kelondro/workflow/InstantBusyThread.java +++ b/source/net/yacy/kelondro/workflow/InstantBusyThread.java @@ -165,6 +165,7 @@ public final class InstantBusyThread extends AbstractBusyThread implements BusyT thread.setIdleSleep(-1); thread.setBusySleep(-1); thread.setMemPreReqisite(0); + thread.setLoadPreReqisite(3); thread.start(); return thread; } diff --git a/source/net/yacy/search/Switchboard.java b/source/net/yacy/search/Switchboard.java index e05ca0fe0..aea45e0ca 100644 --- a/source/net/yacy/search/Switchboard.java +++ b/source/net/yacy/search/Switchboard.java @@ -1094,7 +1094,8 @@ public final class Switchboard extends serverSwitch { 60000, Long.parseLong(getConfig(SwitchboardConstants.INDEX_DIST_IDLESLEEP, "5000")), Long.parseLong(getConfig(SwitchboardConstants.INDEX_DIST_BUSYSLEEP, "0")), - Long.parseLong(getConfig(SwitchboardConstants.INDEX_DIST_MEMPREREQ, "1000000"))); + Long.parseLong(getConfig(SwitchboardConstants.INDEX_DIST_MEMPREREQ, "1000000")), + Double.parseDouble(getConfig(SwitchboardConstants.INDEX_DIST_LOADPREREQ, "9.0"))); // content control: initialize list sync thread deployThread( diff --git a/source/net/yacy/search/SwitchboardConstants.java b/source/net/yacy/search/SwitchboardConstants.java index cc1630879..ff6fb3908 100644 --- a/source/net/yacy/search/SwitchboardConstants.java +++ b/source/net/yacy/search/SwitchboardConstants.java @@ -62,6 +62,7 @@ public final class SwitchboardConstants { public static final String INDEX_DIST_METHOD_JOBCOUNT = null; public static final String INDEX_DIST_METHOD_FREEMEM = null; public static final String INDEX_DIST_MEMPREREQ = "20_dhtdistribution_memprereq"; + public static final String INDEX_DIST_LOADPREREQ = "20_dhtdistribution_loadprereq"; public static final String INDEX_DIST_IDLESLEEP = "20_dhtdistribution_idlesleep"; public static final String INDEX_DIST_BUSYSLEEP = "20_dhtdistribution_busysleep"; // 30_peerping @@ -132,6 +133,7 @@ public final class SwitchboardConstants { */ public static final String SURROGATES = "70_surrogates"; public static final String SURROGATES_MEMPREREQ = "70_surrogates_memprereq"; + public static final String SURROGATES_LOADPREREQ = "70_surrogates_loadprereq"; public static final String SURROGATES_IDLESLEEP = "70_surrogates_idlesleep"; public static final String SURROGATES_BUSYSLEEP = "70_surrogates_busysleep"; public static final String SURROGATES_METHOD_START = "surrogateProcess"; @@ -144,6 +146,7 @@ public final class SwitchboardConstants { */ public static final String SEARCHRESULT = "80_searchresult"; public static final String SEARCHRESULT_MEMPREREQ = "80_searchresult_memprereq"; + public static final String SEARCHRESULT_LOADPREREQ = "80_searchresult_loadprereq"; public static final String SEARCHRESULT_IDLESLEEP = "80_searchresult_idlesleep"; public static final String SEARCHRESULT_BUSYSLEEP = "80_searchresult_busysleep"; public static final String SEARCHRESULT_METHOD_START = "searchresultProcess"; diff --git a/source/net/yacy/server/serverSwitch.java b/source/net/yacy/server/serverSwitch.java index d682782e1..06c25db7d 100644 --- a/source/net/yacy/server/serverSwitch.java +++ b/source/net/yacy/server/serverSwitch.java @@ -344,7 +344,8 @@ public class serverSwitch startupDelay, Long.parseLong(getConfig(threadName + "_idlesleep", "100")), Long.parseLong(getConfig(threadName + "_busysleep", "1000")), - Long.parseLong(getConfig(threadName + "_memprereq", "1000000"))); + Long.parseLong(getConfig(threadName + "_memprereq", "1000000")), + Double.parseDouble(getConfig(threadName + "_loadprereq", "9.0"))); } public void deployThread( @@ -356,7 +357,8 @@ public class serverSwitch final long startupDelay, final long initialIdleSleep, final long initialBusySleep, - final long initialMemoryPreRequisite) { + final long initialMemoryPreRequisite, + final double initialLoadPreRequisite) { if ( newThread.isAlive() ) { throw new RuntimeException( "undeployed threads must not live; they are started as part of the deployment"); @@ -384,6 +386,13 @@ public class serverSwitch newThread.setMemPreReqisite(initialMemoryPreRequisite); setConfig(threadName + "_memprereq", initialMemoryPreRequisite); } + try { + final double load = Double.parseDouble(getConfig(threadName + "_loadprereq", "novalue")); + newThread.setLoadPreReqisite(load); + } catch (final NumberFormatException e ) { + newThread.setLoadPreReqisite(initialLoadPreRequisite); + setConfig(threadName + "_loadprereq", (float)initialLoadPreRequisite); + } newThread.setDescription(threadShortDescription, threadLongDescription, threadMonitorURL); this.workerThreads.put(threadName, newThread); // start the thread @@ -400,13 +409,16 @@ public class serverSwitch final String threadName, final long idleMillis, final long busyMillis, - final long memprereqBytes) { + final long memprereqBytes, + final double loadprereq) { final BusyThread thread = this.workerThreads.get(threadName); if ( thread != null ) { setConfig(threadName + "_idlesleep", thread.setIdleSleep(idleMillis)); setConfig(threadName + "_busysleep", thread.setBusySleep(busyMillis)); setConfig(threadName + "_memprereq", memprereqBytes); thread.setMemPreReqisite(memprereqBytes); + setConfig(threadName + "_loadprereq", (float)loadprereq); + thread.setLoadPreReqisite(loadprereq); } }