maxWarmingSearchers: SOLR-91

git-svn-id: https://svn.apache.org/repos/asf/incubator/solr/trunk@495753 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2007-01-12 22:00:08 +00:00
parent 5f57b25a51
commit 6e43239634
3 changed files with 27 additions and 9 deletions

View File

@ -42,6 +42,11 @@ New Features
* PatternReplaceFilter - applies a Pattern to each token in the * PatternReplaceFilter - applies a Pattern to each token in the
stream, replacing match occurances with a specified replacement. stream, replacing match occurances with a specified replacement.
(hossman) (hossman)
3. SOLR-91: allow configuration of a limit of the number of searchers
that can be warming in the background. This can be used to avoid
out-of-memory errors, or contention caused by more and more searchers
warming in the background. An error is thrown if the limit specified
by maxWarmingSearchers in solrconfig.xml is exceeded. (yonik)
Changes in runtime behavior Changes in runtime behavior
1. Highlighting using DisMax will only pick up terms from the main 1. Highlighting using DisMax will only pick up terms from the main

View File

@ -215,6 +215,11 @@
warming. --> warming. -->
<useColdSearcher>false</useColdSearcher> <useColdSearcher>false</useColdSearcher>
<!-- Maximum number of searchers that may be warming in the background
concurrently. An error is returned if this limit is exceeded. Recommend
1-2 for read-only slaves, higher for masters w/o cache warming. -->
<maxWarmingSearchers>4</maxWarmingSearchers>
</query> </query>

View File

@ -182,7 +182,7 @@ public final class SolrCore {
core = this; // set singleton core = this; // set singleton
if (dataDir ==null) { if (dataDir ==null) {
dataDir =SolrConfig.config.get("dataDir",Config.getInstanceDir()+"data"); dataDir = SolrConfig.config.get("dataDir",Config.getInstanceDir()+"data");
} }
log.info("Opening new SolrCore at " + Config.getInstanceDir() + ", dataDir="+dataDir); log.info("Opening new SolrCore at " + Config.getInstanceDir() + ", dataDir="+dataDir);
@ -195,6 +195,8 @@ public final class SolrCore {
this.dataDir = dataDir; this.dataDir = dataDir;
this.index_path = dataDir + "/" + "index"; this.index_path = dataDir + "/" + "index";
this.maxWarmingSearchers = SolrConfig.config.getInt("query/maxWarmingSearchers",Integer.MAX_VALUE);
parseListeners(); parseListeners();
initIndex(); initIndex();
@ -252,6 +254,7 @@ public final class SolrCore {
final ExecutorService searcherExecutor = Executors.newSingleThreadExecutor(); final ExecutorService searcherExecutor = Executors.newSingleThreadExecutor();
private int onDeckSearchers; // number of searchers preparing private int onDeckSearchers; // number of searchers preparing
private Object searcherLock = new Object(); // the sync object for the searcher private Object searcherLock = new Object(); // the sync object for the searcher
private final int maxWarmingSearchers; // max number of on-deck searchers allowed
public RefCounted<SolrIndexSearcher> getSearcher() { public RefCounted<SolrIndexSearcher> getSearcher() {
@ -337,20 +340,25 @@ public final class SolrCore {
// first: increment count to signal other threads that we are // first: increment count to signal other threads that we are
// opening a new searcher. // opening a new searcher.
onDeckSearchers++; onDeckSearchers++;
if (onDeckSearchers < 1) {
// should never happen... just a sanity check
log.severe("ERROR!!! onDeckSearchers is " + onDeckSearchers);
onDeckSearchers=1; // reset
} else if (onDeckSearchers > maxWarmingSearchers) {
onDeckSearchers--;
String msg="Error opening new searcher. exceeded limit of maxWarmingSearchers="+maxWarmingSearchers + ", try again later.";
log.warning(msg);
// HTTP 503==service unavailable, or 409==Conflict
throw new SolrException(503,msg,true);
} else if (onDeckSearchers > 1) {
log.info("PERFORMANCE WARNING: Overlapping onDeckSearchers=" + onDeckSearchers);
}
} }
// open the index synchronously // open the index synchronously
// if this fails, we need to decrement onDeckSearchers again. // if this fails, we need to decrement onDeckSearchers again.
SolrIndexSearcher tmp; SolrIndexSearcher tmp;
try { try {
if (onDeckSearchers < 1) {
// should never happen... just a sanity check
log.severe("ERROR!!! onDeckSearchers is " + onDeckSearchers);
// reset to 1 (don't bother synchronizing)
onDeckSearchers=1;
} else if (onDeckSearchers > 1) {
log.info("PERFORMANCE WARNING: Overlapping onDeckSearchers=" + onDeckSearchers);
}
tmp = new SolrIndexSearcher(schema, "main", index_path, true); tmp = new SolrIndexSearcher(schema, "main", index_path, true);
} catch (Throwable th) { } catch (Throwable th) {
synchronized(searcherLock) { synchronized(searcherLock) {