Indeksowanie masowe elasticsearch staje się z czasem wolniejsze dzięki stałej liczbie indeksów i dokumentów
Doświadczam tej dużej wydajności indeksowania przy użyciu klienta .NET NEST, a ElasticSearch z czasem ulega degradacji przy stałej liczbie indeksów i liczbie dokumentów.
BiegniemyElasticSearch Version: 0.19.11, JVM: 23.5-b02
na instancji m1.large Amazon z Ubuntu Server 12.04.1 LTS 64 bit i Sun Java 7. Na tej instancji nie ma nic innego, z wyjątkiem instalacji Ubuntu.
Amazon M1 Large Instance: zhttp://aws.amazon.com/ec2/instance-types/
7.5 GiB memory
4 EC2 Compute Units (2 virtual cores with 2 EC2 Compute Units each)
850 GB instance storage
64-bit platform
I/O Performance: High
EBS-Optimized Available: 500 Mbps
API name: m1.large
ES_MAX_MEM jest ustawione na 4g, a ES_MIN_MEM na 2g
Każdej nocy indeksujemy / reindeksujemy ~ 15000 dokumentów za pomocą NEST w naszej aplikacji .NET. W dowolnym momencie istnieje tylko jeden indeks z <= 15000 dokumentów.
Gdy serwer został zainstalowany po raz pierwszy, indeksowanie i wyszukiwanie były szybkie przez pierwsze kilka dni, a następnie indeksowanie zaczęło być wolniejsze i wolniejsze. indeksowanie zbiorcze indeksuje 100 dokumentów na raz i po pewnym czasie ich ukończenie zajęłoby 15 sekund. po tym zaczęliśmy dostrzegać wiele wyjątków, a indeksowanie zatrzymało się.
System.Net.WebException: The request was aborted: The request was canceled.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization) :
Implementacja indeksowania builk wygląda następująco
private ElasticClient GetElasticClient()
{
var setting = new ConnectionSettings(ConfigurationManager.AppSettings["elasticSearchHost"], 9200);
setting.SetDefaultIndex("products");
var elastic = new ElasticClient(setting);
return elastic;
}
private void DisableRefreshInterval()
{
var elasticClient = GetElasticClient();
var s = elasticClient.GetIndexSettings("products");
var settings = s != null && s.Settings != null ? s.Settings : new IndexSettings();
settings["refresh_interval"] = "-1";
var result = elasticClient.UpdateSettings(settings);
if (!result.OK)
_logger.Warn("unable to set refresh_interval to -1, {0}", result.ConnectionStatus == null || result.ConnectionStatus.Error == null ? "" : result.ConnectionStatus.Error.ExceptionMessage);
}
private void EnableRefreshInterval()
{
var elasticClient = GetElasticClient();
var s = elasticClient.GetIndexSettings("products");
var settings = s != null && s.Settings != null ? s.Settings : new IndexSettings();
settings["refresh_interval"] = "1s";
var result = elasticClient.UpdateSettings(settings);
if (!result.OK)
_logger.Warn("unable to set refresh_interval to 1s, {0}", result.ConnectionStatus == null || result.ConnectionStatus.Error == null ? "" : result.ConnectionStatus.Error.ExceptionMessage);
}
public void Index(IEnumerable<Product> products)
{
var enumerable = products as Product[] ?? products.ToArray();
var elasticClient = GetElasticClient();
try
{
DisableRefreshInterval();
_logger.Info("Indexing {0} products", enumerable.Count());
var status = elasticClient.IndexMany(enumerable as IEnumerable<Product>, "products");
if (status.Items != null)
_logger.Info("Done, Indexing {0} products, duration: {1}", status.Items.Count(), status.Took);
if (status.ConnectionStatus.Error != null)
{
_logger.Error(status.ConnectionStatus.Error.OriginalException);
}
}
catch(Exception ex)
{
_logger.Error(ex);
}
finally
{
EnableRefreshInterval();
}
}
Ponowne uruchomienie demona elasticsearch wydaje się nie robić żadnej różnicy, ale usunięcie indeksu i ponowne indeksowanie wszystkiego. Ale po kilku dniach będziemy mieli ten sam problem z wolnym indeksowaniem.
Właśnie usunąłem indeks i dodałem Optymalizację po ponownym włączeniu interwału odświeżania po każdej operacji indeksu zbiorczego w nadziei, że może to powstrzymać degradację indeksu.
...
...
finally
{
EnableRefreshInterval();
elasticClient.Optimize("products");
}
Czy robię tutaj coś strasznie złego?