mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 10:25:15 +00:00
Internal: Remove the query parser cache.
The original goal of this cache was to avoid parsing the same query several times in case several shards are held on the same node. While this might sound like a good idea, this would only help when parsing the query takes non-negligible time compared to actually running the query, which should not be the case.
This commit is contained in:
parent
87cf1452d5
commit
9d890c472b
@ -101,8 +101,6 @@ public class TransportClearIndicesCacheAction extends TransportBroadcastOperatio
|
||||
IndexService service = indicesService.indexService(request.shardId().getIndex());
|
||||
if (service != null) {
|
||||
IndexShard shard = service.shard(request.shardId().id());
|
||||
// we always clear the query cache
|
||||
service.cache().queryParserCache().clear();
|
||||
boolean clearedAtLeastOne = false;
|
||||
if (request.filterCache()) {
|
||||
clearedAtLeastOne = true;
|
||||
|
@ -20,18 +20,12 @@
|
||||
package org.elasticsearch.index.cache;
|
||||
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||
import org.elasticsearch.cluster.ClusterService;
|
||||
import org.elasticsearch.cluster.ClusterStateListener;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.AbstractIndexComponent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
|
||||
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCache;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
|
||||
import java.io.Closeable;
|
||||
@ -40,30 +34,18 @@ import java.io.IOException;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class IndexCache extends AbstractIndexComponent implements Closeable, ClusterStateListener {
|
||||
public class IndexCache extends AbstractIndexComponent implements Closeable {
|
||||
|
||||
private final FilterCache filterCache;
|
||||
private final QueryParserCache queryParserCache;
|
||||
private final BitsetFilterCache bitsetFilterCache;
|
||||
|
||||
private ClusterService clusterService;
|
||||
|
||||
@Inject
|
||||
public IndexCache(Index index, @IndexSettings Settings indexSettings, FilterCache filterCache, QueryParserCache queryParserCache, BitsetFilterCache bitsetFilterCache) {
|
||||
public IndexCache(Index index, @IndexSettings Settings indexSettings, FilterCache filterCache, BitsetFilterCache bitsetFilterCache) {
|
||||
super(index, indexSettings);
|
||||
this.filterCache = filterCache;
|
||||
this.queryParserCache = queryParserCache;
|
||||
this.bitsetFilterCache = bitsetFilterCache;
|
||||
}
|
||||
|
||||
@Inject(optional = true)
|
||||
public void setClusterService(@Nullable ClusterService clusterService) {
|
||||
this.clusterService = clusterService;
|
||||
if (clusterService != null) {
|
||||
clusterService.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public FilterCache filter() {
|
||||
return filterCache;
|
||||
}
|
||||
@ -75,29 +57,14 @@ public class IndexCache extends AbstractIndexComponent implements Closeable, Clu
|
||||
return bitsetFilterCache;
|
||||
}
|
||||
|
||||
public QueryParserCache queryParserCache() {
|
||||
return this.queryParserCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
IOUtils.close(filterCache, queryParserCache, bitsetFilterCache);
|
||||
if (clusterService != null) {
|
||||
clusterService.remove(this);
|
||||
}
|
||||
IOUtils.close(filterCache, bitsetFilterCache);
|
||||
}
|
||||
|
||||
public void clear(String reason) {
|
||||
filterCache.clear(reason);
|
||||
queryParserCache.clear();
|
||||
bitsetFilterCache.clear(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clusterChanged(ClusterChangedEvent event) {
|
||||
// clear the query parser cache if the metadata (mappings) changed...
|
||||
if (event.metaDataChanged()) {
|
||||
queryParserCache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.cache.bitset.BitsetFilterCacheModule;
|
||||
import org.elasticsearch.index.cache.filter.FilterCacheModule;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCacheModule;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -39,7 +38,6 @@ public class IndexCacheModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
new FilterCacheModule(settings).configure(binder());
|
||||
new QueryParserCacheModule(settings).configure(binder());
|
||||
new BitsetFilterCacheModule(settings).configure(binder());
|
||||
|
||||
bind(IndexCache.class).asEagerSingleton();
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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.elasticsearch.index.cache.query.parser;
|
||||
|
||||
import org.apache.lucene.queryparser.classic.QueryParserSettings;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.index.IndexComponent;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* The main benefit of the query parser cache is to not parse the same query string on different shards.
|
||||
* Less about long running query strings.
|
||||
*/
|
||||
public interface QueryParserCache extends IndexComponent, Closeable {
|
||||
|
||||
Query get(QueryParserSettings queryString);
|
||||
|
||||
void put(QueryParserSettings queryString, Query query);
|
||||
|
||||
void clear();
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.elasticsearch.index.cache.query.parser;
|
||||
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.inject.Scopes;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.cache.query.parser.resident.ResidentQueryParserCache;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class QueryParserCacheModule extends AbstractModule {
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
public QueryParserCacheModule(Settings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(QueryParserCache.class)
|
||||
.to(settings.getAsClass("index.cache.query.parser.type", ResidentQueryParserCache.class, "org.elasticsearch.index.cache.query.parser.", "QueryParserCache"))
|
||||
.in(Scopes.SINGLETON);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.elasticsearch.index.cache.query.parser.none;
|
||||
|
||||
import org.apache.lucene.queryparser.classic.QueryParserSettings;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.AbstractIndexComponent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCache;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class NoneQueryParserCache extends AbstractIndexComponent implements QueryParserCache {
|
||||
|
||||
@Inject
|
||||
public NoneQueryParserCache(Index index, @IndexSettings Settings indexSettings) {
|
||||
super(index, indexSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query get(QueryParserSettings queryString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(QueryParserSettings queryString, Query query) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws ElasticsearchException {
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* 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.elasticsearch.index.cache.query.parser.resident;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import org.apache.lucene.queryparser.classic.QueryParserSettings;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.index.AbstractIndexComponent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCache;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* A small (by default) query parser cache mainly to not parse the same query string several times
|
||||
* if several shards exists on the same node.
|
||||
*/
|
||||
public class ResidentQueryParserCache extends AbstractIndexComponent implements QueryParserCache {
|
||||
|
||||
private final Cache<QueryParserSettings, Query> cache;
|
||||
|
||||
private volatile int maxSize;
|
||||
private volatile TimeValue expire;
|
||||
|
||||
@Inject
|
||||
public ResidentQueryParserCache(Index index, @IndexSettings Settings indexSettings) {
|
||||
super(index, indexSettings);
|
||||
|
||||
this.maxSize = indexSettings.getAsInt("index.cache.query.parser.resident.max_size", 100);
|
||||
this.expire = indexSettings.getAsTime("index.cache.query.parser.resident.expire", null);
|
||||
logger.debug("using [resident] query cache with max_size [{}], expire [{}]", maxSize, expire);
|
||||
|
||||
CacheBuilder cacheBuilder = CacheBuilder.newBuilder().maximumSize(maxSize);
|
||||
if (expire != null) {
|
||||
cacheBuilder.expireAfterAccess(expire.nanos(), TimeUnit.NANOSECONDS);
|
||||
}
|
||||
|
||||
this.cache = cacheBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query get(QueryParserSettings queryString) {
|
||||
Query value = cache.getIfPresent(queryString);
|
||||
if (value != null) {
|
||||
return value.clone();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(QueryParserSettings queryString, Query query) {
|
||||
if (queryString.isCacheable()) {
|
||||
cache.put(queryString, query);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws ElasticsearchException {
|
||||
cache.invalidateAll();
|
||||
}
|
||||
}
|
@ -46,14 +46,13 @@ import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.mapper.ContentPath;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMappers;
|
||||
import org.elasticsearch.index.mapper.Mapper;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.MapperBuilders;
|
||||
import org.elasticsearch.index.mapper.ContentPath;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
||||
import org.elasticsearch.index.query.support.NestedScope;
|
||||
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
|
||||
@ -64,7 +63,12 @@ import org.elasticsearch.search.internal.SearchContext;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -182,10 +186,6 @@ public class QueryParseContext {
|
||||
return indexQueryParser.similarityService != null ? indexQueryParser.similarityService.similarity() : null;
|
||||
}
|
||||
|
||||
public QueryParserCache queryParserCache() {
|
||||
return indexQueryParser.indexCache.queryParserCache();
|
||||
}
|
||||
|
||||
public String defaultField() {
|
||||
return indexQueryParser.defaultField();
|
||||
}
|
||||
|
@ -219,18 +219,11 @@ public class QueryStringQueryParser implements QueryParser {
|
||||
}
|
||||
|
||||
qpSettings.queryTypes(parseContext.queryTypes());
|
||||
Query query = parseContext.queryParserCache().get(qpSettings);
|
||||
if (query != null) {
|
||||
if (queryName != null) {
|
||||
parseContext.addNamedQuery(queryName, query);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
MapperQueryParser queryParser = parseContext.queryParser(qpSettings);
|
||||
|
||||
try {
|
||||
query = queryParser.parse(qpSettings.queryString());
|
||||
Query query = queryParser.parse(qpSettings.queryString());
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
@ -241,7 +234,6 @@ public class QueryStringQueryParser implements QueryParser {
|
||||
if (query instanceof BooleanQuery) {
|
||||
Queries.applyMinimumShouldMatch((BooleanQuery) query, qpSettings.minimumShouldMatch());
|
||||
}
|
||||
parseContext.queryParserCache().put(qpSettings, query);
|
||||
if (queryName != null) {
|
||||
parseContext.addNamedQuery(queryName, query);
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.elasticsearch.index.cache.query.parser.resident;
|
||||
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.queryparser.classic.QueryParserSettings;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ResidentQueryParserCacheTest extends ElasticsearchTestCase {
|
||||
|
||||
@Test
|
||||
public void testCaching() throws Exception {
|
||||
ResidentQueryParserCache cache = new ResidentQueryParserCache(new Index("test"), ImmutableSettings.EMPTY);
|
||||
QueryParserSettings key = new QueryParserSettings();
|
||||
key.queryString("abc");
|
||||
key.defaultField("a");
|
||||
key.boost(2.0f);
|
||||
|
||||
Query query = new TermQuery(new Term("a", "abc"));
|
||||
cache.put(key, query);
|
||||
|
||||
assertThat(cache.get(key), not(sameInstance(query)));
|
||||
assertThat(cache.get(key), equalTo(query));
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user