Skip to content

Commit bda9257

Browse files
tinder-xlijasontedor
authored andcommitted
Reduce synchronization on field data cache
The field data cache can come under heavy contention in cases when lots of search threads are hitting it for doc values. This commit reduces the amount of contention here by using a double-checked locking strategy to only lock when the cache needs to be initialized. Relates #27365
1 parent ea98113 commit bda9257

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,24 @@ public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType
110110
final String fieldName = fieldType.name();
111111
IndexFieldData.Builder builder = fieldType.fielddataBuilder();
112112

113-
IndexFieldDataCache cache;
114-
synchronized (this) {
115-
cache = fieldDataCaches.get(fieldName);
116-
if (cache == null) {
117-
String cacheType = indexSettings.getValue(INDEX_FIELDDATA_CACHE_KEY);
118-
if (FIELDDATA_CACHE_VALUE_NODE.equals(cacheType)) {
119-
cache = indicesFieldDataCache.buildIndexFieldDataCache(listener, index(), fieldName);
120-
} else if ("none".equals(cacheType)){
121-
cache = new IndexFieldDataCache.None();
122-
} else {
123-
throw new IllegalArgumentException("cache type not supported [" + cacheType + "] for field [" + fieldName + "]");
113+
IndexFieldDataCache cache = fieldDataCaches.get(fieldName);
114+
if (cache == null) {
115+
//for perf reason, only synchronize when cache is null
116+
synchronized (this) {
117+
cache = fieldDataCaches.get(fieldName);
118+
//double checked locking to make sure it is thread safe
119+
//especially when other threads calling clear() or clearField()
120+
if (cache == null) {
121+
String cacheType = indexSettings.getValue(INDEX_FIELDDATA_CACHE_KEY);
122+
if (FIELDDATA_CACHE_VALUE_NODE.equals(cacheType)) {
123+
cache = indicesFieldDataCache.buildIndexFieldDataCache(listener, index(), fieldName);
124+
} else if ("none".equals(cacheType)){
125+
cache = new IndexFieldDataCache.None();
126+
} else {
127+
throw new IllegalArgumentException("cache type not supported [" + cacheType + "] for field [" + fieldName + "]");
128+
}
129+
fieldDataCaches.put(fieldName, cache);
124130
}
125-
fieldDataCaches.put(fieldName, cache);
126131
}
127132
}
128133

0 commit comments

Comments
 (0)