Skip to content

Commit e671e35

Browse files
Gankris96Ganesh Ramadurai
authored andcommitted
Add support for index level slice count setting
Signed-off-by: Ganesh Ramadurai <[email protected]>
1 parent b830d68 commit e671e35

File tree

4 files changed

+154
-1
lines changed

4 files changed

+154
-1
lines changed

server/src/main/java/org/opensearch/common/settings/IndexScopedSettings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
238238

239239
// Settings for concurrent segment search
240240
IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_SETTING,
241+
IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_MAX_SLICE_COUNT,
241242
IndexSettings.ALLOW_DERIVED_FIELDS,
242243

243244
// Settings for star tree index

server/src/main/java/org/opensearch/index/IndexSettings.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,15 @@ public static IndexMergePolicy fromString(String text) {
691691
Property.Dynamic
692692
);
693693

694+
public static final Setting<Integer> INDEX_CONCURRENT_SEGMENT_SEARCH_MAX_SLICE_COUNT = Setting.intSetting(
695+
"index.search.concurrent.max_slice_count",
696+
0,
697+
0,
698+
Property.Dynamic,
699+
Property.IndexScope
700+
);
701+
702+
694703
public static final Setting<Boolean> INDEX_DOC_ID_FUZZY_SET_ENABLED_SETTING = Setting.boolSetting(
695704
"index.optimize_doc_id_lookup.fuzzy_set.enabled",
696705
false,

server/src/main/java/org/opensearch/search/DefaultSearchContext.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,13 @@ public int getTargetMaxSliceCount() {
991991
if (shouldUseConcurrentSearch() == false) {
992992
throw new IllegalStateException("Target slice count should not be used when concurrent search is disabled");
993993
}
994-
return clusterService.getClusterSettings().get(SearchService.CONCURRENT_SEGMENT_SEARCH_TARGET_MAX_SLICE_COUNT_SETTING);
994+
995+
return indexService
996+
.getIndexSettings()
997+
.getSettings()
998+
.getAsInt(IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_MAX_SLICE_COUNT.getKey(),
999+
clusterService.getClusterSettings().get(SearchService.CONCURRENT_SEGMENT_SEARCH_TARGET_MAX_SLICE_COUNT_SETTING));
1000+
9951001
}
9961002

9971003
@Override

server/src/test/java/org/opensearch/search/SearchServiceTests.java

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.opensearch.action.support.IndicesOptions;
5555
import org.opensearch.action.support.PlainActionFuture;
5656
import org.opensearch.action.support.WriteRequest;
57+
import org.opensearch.cluster.service.ClusterService;
5758
import org.opensearch.common.UUIDs;
5859
import org.opensearch.common.settings.Settings;
5960
import org.opensearch.common.settings.SettingsException;
@@ -1413,6 +1414,142 @@ public void testConcurrentSegmentSearchSearchContext() throws IOException {
14131414
.get();
14141415
}
14151416

1417+
1418+
/**
1419+
* Tests that the slice count is calculated correctly when concurrent search is enabled
1420+
* If concurrent search enabled -
1421+
* pick index level slice count setting if index level setting is set
1422+
* else pick default cluster level slice count setting
1423+
* @throws IOException
1424+
*/
1425+
public void testConcurrentSegmentSearchSliceCount() throws IOException {
1426+
Boolean[][] scenarios = {
1427+
// cluster setting, index setting
1428+
{true, null, true},
1429+
{null, true, true},
1430+
{false, true, true},
1431+
{true, false, false},
1432+
{false, false, false},
1433+
};
1434+
1435+
String index = randomAlphaOfLengthBetween(5, 10).toLowerCase(Locale.ROOT);
1436+
IndexService indexService = createIndex(index);
1437+
final SearchService service = getInstanceFromNode(SearchService.class);
1438+
ClusterService clusterService = getInstanceFromNode(ClusterService.class);
1439+
ShardId shardId = new ShardId(indexService.index(), 0);
1440+
long nowInMillis = System.currentTimeMillis();
1441+
String clusterAlias = randomBoolean() ? null : randomAlphaOfLengthBetween(3, 10);
1442+
SearchRequest searchRequest = new SearchRequest();
1443+
searchRequest.allowPartialSearchResults(randomBoolean());
1444+
ShardSearchRequest request = new ShardSearchRequest(
1445+
OriginalIndices.NONE,
1446+
searchRequest,
1447+
shardId,
1448+
indexService.numberOfShards(),
1449+
AliasFilter.EMPTY,
1450+
1f,
1451+
nowInMillis,
1452+
clusterAlias,
1453+
Strings.EMPTY_ARRAY
1454+
);
1455+
1456+
1457+
for (Boolean[] scenario : scenarios) {
1458+
Boolean clusterSetting = scenario[0];
1459+
Boolean indexSetting = scenario[1];
1460+
boolean concurrentSearchEnabled = scenario[2];
1461+
1462+
1463+
if (clusterSetting == null) {
1464+
client().admin()
1465+
.cluster()
1466+
.prepareUpdateSettings()
1467+
.setTransientSettings(Settings.builder().putNull(SearchService.CLUSTER_CONCURRENT_SEGMENT_SEARCH_SETTING.getKey()))
1468+
.get();
1469+
} else {
1470+
client().admin()
1471+
.cluster()
1472+
.prepareUpdateSettings()
1473+
.setTransientSettings(
1474+
Settings.builder().put(SearchService.CLUSTER_CONCURRENT_SEGMENT_SEARCH_SETTING.getKey(), clusterSetting)
1475+
)
1476+
.get();
1477+
}
1478+
1479+
if (indexSetting == null) {
1480+
client().admin()
1481+
.indices()
1482+
.prepareUpdateSettings(index)
1483+
.setSettings(Settings.builder().putNull(IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_SETTING.getKey()))
1484+
.get();
1485+
} else {
1486+
client().admin()
1487+
.indices()
1488+
.prepareUpdateSettings(index)
1489+
.setSettings(Settings.builder().put(IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_SETTING.getKey(), indexSetting))
1490+
.get();
1491+
}
1492+
1493+
boolean updateIndexLevelSlice = randomBoolean();
1494+
int targetSliceCount = clusterService.getClusterSettings().get(SearchService.CONCURRENT_SEGMENT_SEARCH_TARGET_MAX_SLICE_COUNT_SETTING);
1495+
1496+
// update the index level slice count to random value that isnt the default value of 2 from tests.
1497+
if (updateIndexLevelSlice) {
1498+
targetSliceCount = randomIntBetween(3,8);
1499+
client().admin()
1500+
.indices()
1501+
.prepareUpdateSettings(index)
1502+
.setSettings(Settings.builder().put(IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_MAX_SLICE_COUNT.getKey(), targetSliceCount))
1503+
.get();
1504+
}
1505+
1506+
try (DefaultSearchContext searchContext = service.createSearchContext(request, new TimeValue(System.currentTimeMillis()))) {
1507+
assertEquals(
1508+
clusterSetting,
1509+
client().admin()
1510+
.cluster()
1511+
.prepareState()
1512+
.get()
1513+
.getState()
1514+
.getMetadata()
1515+
.transientSettings()
1516+
.getAsBoolean(SearchService.CLUSTER_CONCURRENT_SEGMENT_SEARCH_SETTING.getKey(), null)
1517+
);
1518+
assertEquals(
1519+
indexSetting == null ? null : indexSetting.toString(),
1520+
client().admin()
1521+
.indices()
1522+
.prepareGetSettings(index)
1523+
.get()
1524+
.getSetting(index, IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_SETTING.getKey())
1525+
);
1526+
searchContext.evaluateRequestShouldUseConcurrentSearch();
1527+
assertEquals(concurrentSearchEnabled, searchContext.shouldUseConcurrentSearch());
1528+
// verify executor nullability with concurrent search enabled/disabled
1529+
if (concurrentSearchEnabled) {
1530+
assertNotNull(searchContext.searcher().getExecutor());
1531+
assertEquals(targetSliceCount, searchContext.getTargetMaxSliceCount());
1532+
} else {
1533+
assertNull(searchContext.searcher().getExecutor());
1534+
}
1535+
}
1536+
1537+
// reset the setting for next iterations
1538+
client().admin()
1539+
.indices()
1540+
.prepareUpdateSettings(index)
1541+
.setSettings(Settings.builder().putNull(IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_MAX_SLICE_COUNT.getKey()))
1542+
.get();
1543+
}
1544+
// Cleanup
1545+
client().admin()
1546+
.cluster()
1547+
.prepareUpdateSettings()
1548+
.setTransientSettings(Settings.builder().putNull(SearchService.CLUSTER_CONCURRENT_SEGMENT_SEARCH_SETTING.getKey()))
1549+
.get();
1550+
1551+
}
1552+
14161553
/**
14171554
* Test that the Search Context for concurrent segment search enabled is set correctly at the time of construction.
14181555
* The same is used throughout the context object lifetime even if cluster setting changes before the request completion.

0 commit comments

Comments
 (0)