Skip to content

Commit 17e9940

Browse files
authored
Carry over version map size to prevent excessive resizing (#27516)
Today we create a new concurrent hash map everytime we refresh the internal reader. Under defaults this isn't much of a deal but once the refresh interval is set to `-1` these maps grow quite large and it can have a significant impact on indexing throughput. Under low memory situations this can cause up to 2x slowdown. This change carries over the map size as the initial capacity wich will be auto-adjusted once indexing stops. Closes #20498
1 parent c6724ab commit 17e9940

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

core/src/main/java/org/elasticsearch/common/util/concurrent/ConcurrentCollections.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,14 @@ public abstract class ConcurrentCollections {
4343
* Creates a new CHM with an aggressive concurrency level, aimed at high concurrent update rate long living maps.
4444
*/
4545
public static <K, V> ConcurrentMap<K, V> newConcurrentMapWithAggressiveConcurrency() {
46-
return new ConcurrentHashMap<>(16, 0.75f, aggressiveConcurrencyLevel);
46+
return newConcurrentMapWithAggressiveConcurrency(16);
47+
}
48+
49+
/**
50+
* Creates a new CHM with an aggressive concurrency level, aimed at high concurrent update rate long living maps.
51+
*/
52+
public static <K, V> ConcurrentMap<K, V> newConcurrentMapWithAggressiveConcurrency(int initalCapacity) {
53+
return new ConcurrentHashMap<>(initalCapacity, 0.75f, aggressiveConcurrencyLevel);
4754
}
4855

4956
public static <K, V> ConcurrentMap<K, V> newConcurrentMap() {

core/src/main/java/org/elasticsearch/index/engine/LiveVersionMap.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public void beforeRefresh() throws IOException {
102102
// map. While reopen is running, any lookup will first
103103
// try this new map, then fallback to old, then to the
104104
// current searcher:
105-
maps = new Maps(ConcurrentCollections.<BytesRef,VersionValue>newConcurrentMapWithAggressiveConcurrency(), maps.current);
105+
maps = new Maps(ConcurrentCollections.newConcurrentMapWithAggressiveConcurrency(maps.current.size()), maps.current);
106106

107107
// This is not 100% correct, since concurrent indexing ops can change these counters in between our execution of the previous
108108
// line and this one, but that should be minor, and the error won't accumulate over time:
@@ -117,7 +117,7 @@ public void afterRefresh(boolean didRefresh) throws IOException {
117117
// case. This is because we assign new maps (in beforeRefresh) slightly before Lucene actually flushes any segments for the
118118
// reopen, and so any concurrent indexing requests can still sneak in a few additions to that current map that are in fact reflected
119119
// in the previous reader. We don't touch tombstones here: they expire on their own index.gc_deletes timeframe:
120-
maps = new Maps(maps.current, ConcurrentCollections.<BytesRef,VersionValue>newConcurrentMapWithAggressiveConcurrency());
120+
maps = new Maps(maps.current, Collections.emptyMap());
121121
}
122122

123123
/** Returns the live version (add or delete) for this uid. */

0 commit comments

Comments
 (0)