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-b02na 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?

questionAnswers(2)

yourAnswerToTheQuestion