Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move to use serial merge schedule by default
Today, we use ConcurrentMergeScheduler, and this can be painful since it is concurrent on a shard level, with a max of 3 threads doing concurrent merges. If there are several shards being indexed, then there will be a minor explosion of threads trying to do merges, all being throttled by our merge throttling. Moving to serial merge scheduler will still maintain concurrency of merges across shards, as we have the merge thread pool that schedules those merges. It will just be a serial one on a specific shard. Also, on serial merge scheduler, we now have a limit of how many merges it will do at one go, so it will let other shards get their fair chance of merging. We use the pending merges on IW to check if merges are needed or not for it. Note, that if a merge is happening, it will not block due to a sync on the maybeMerge call at indexing (flush) time, since we wrap our merge scheduler with the EnabledMergeScheduler, where maybeMerge is not activated during indexing, only with explicit calls to IW#maybeMerge (see Merges). closes #5447
- Loading branch information
Showing
6 changed files
with
97 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/test/java/org/apache/lucene/TrackingSerialMergeSchedulerTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Licensed to Elasticsearch under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
package org.apache.lucene; | ||
|
||
import org.apache.lucene.analysis.MockAnalyzer; | ||
import org.apache.lucene.document.Document; | ||
import org.apache.lucene.document.Field; | ||
import org.apache.lucene.document.StringField; | ||
import org.apache.lucene.index.IndexWriter; | ||
import org.apache.lucene.index.IndexWriterConfig; | ||
import org.apache.lucene.index.TieredMergePolicy; | ||
import org.apache.lucene.index.TrackingSerialMergeScheduler; | ||
import org.apache.lucene.store.Directory; | ||
import org.elasticsearch.common.logging.Loggers; | ||
import org.elasticsearch.index.merge.EnableMergeScheduler; | ||
import org.elasticsearch.index.merge.Merges; | ||
import org.elasticsearch.test.ElasticsearchLuceneTestCase; | ||
import org.junit.Test; | ||
|
||
/** | ||
*/ | ||
public class TrackingSerialMergeSchedulerTests extends ElasticsearchLuceneTestCase { | ||
|
||
@Test | ||
public void testMaxMergeAtOnce() throws Exception { | ||
Directory dir = newDirectory(); | ||
IndexWriterConfig iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); | ||
// create a tracking merge scheduler, but enabled one, so we can control when it merges | ||
EnableMergeScheduler mergeScheduler = new EnableMergeScheduler(new TrackingSerialMergeScheduler(Loggers.getLogger(getTestClass()), 2)); | ||
iwc.setMergeScheduler(mergeScheduler); | ||
TieredMergePolicy mergePolicy = new TieredMergePolicy(); | ||
mergePolicy.setMaxMergeAtOnceExplicit(3); | ||
mergePolicy.setMaxMergeAtOnce(3); | ||
iwc.setMergePolicy(mergePolicy); | ||
IndexWriter iw = new IndexWriter(dir, iwc); | ||
// create 20 segments | ||
for (int i = 0; i < 20; i++) { | ||
Document doc = new Document(); | ||
doc.add(new StringField("id", Integer.toString(i), Field.Store.NO)); | ||
iw.addDocument(doc); | ||
iw.commit(); // create a segment, no merge will happen, its disabled | ||
} | ||
// based on the merge policy maxMerge, and the fact that we allow only for 2 merges to run | ||
// per maybeMerge in our configuration of the serial merge scheduler, the we expect to need | ||
// 4 merge runs to work out through the pending merges | ||
for (int i = 0; i < 4; i++) { | ||
assertTrue(iw.hasPendingMerges()); | ||
Merges.maybeMerge(iw); | ||
assertTrue(iw.hasPendingMerges()); | ||
} | ||
Merges.maybeMerge(iw); | ||
assertFalse(iw.hasPendingMerges()); | ||
|
||
iw.close(false); | ||
dir.close(); | ||
} | ||
} |