elasticsearch bulk-Indizierung wird langsamer über die Zeit mit konstanter Anzahl von Indizes und Dokumenten

Erlebe ich, dass bulk-Indizierung Leistung mit Hilfe der .NETTO NEST client und ElasticSearch degradiert im Laufe der Zeit mit einer Konstanten Menge von Indizes und Anzahl der Dokumente.

Laufen wir ElasticSearch Version: 0.19.11, JVM: 23.5-b02auf einen m1.große Amazon-Instanz mit Ubuntu Server 12.04.1 LTS 64 bit und Sun-Java-7. Es gibt nichts anderes läuft diese Instanz außer dem, was kommt, zusammen mit Ubuntu installieren.

Amazon M1 Large Instance: von http://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 ist eingestellt auf 4g und ES_MIN_MEM eingestellt ist 2g

Jeden Abend/index reindex ~15000 Dokumente mit NEST in unserem .NET-Anwendung. Zu jedem gegebenen Zeitpunkt gibt es nur einen index mit <= 15000 Dokumente.

wenn der server zuerst installiert wurde, die Indizierung und die Suche war schnell für die ersten paar Tage, dann wird die Indizierung gestartet langsamer und langsamer. die bulk-Indizierung Indizes 100 Dokumente zu einer Zeit, und nach einer Weile würde es dauern, bis zu 15s für eine bulk-operation zu beenden. danach haben wir begonnen, um zu sehen, eine Menge von der folgenden Ausnahme-und die Indizierung von Schleifen zum Stillstand.

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) : 

Den builk Indizierung-Implementierung sieht wie folgt aus

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();
    }
}

Neustart des elasticsearch-daemon scheint nicht zu keinen Unterschied machen, überhaupt, aber das löschen der index-und re-Indizierung alles tut. Aber nach ein paar Tagen hätten wir die gleichen slow-Indizierung problem.

Ich gerade gelöscht, die index und zusätzlich eine Optimierung nach der re-Aktivierung des refresh-Intervall nach jeder bulk-index-operation in der Hoffnung, dass diese halten könnte, der index von der Verschlechterung.

...
...
finally
{
    EnableRefreshInterval();
    elasticClient.Optimize("products");
}

Mache ich etwas schrecklich falsch hier?

  • 15000 sollten breeze sowohl für NEST und Elasticsearch, was ist die tatsächliche Anzahl der Dokumente und index-Größe nach ein paar Tagen?
  • Wie haben Sie auf, da diese Frage mit der ES-Konfiguration? Ich bemerkte eine Sache, dass hier definitiv Bedürfnissen ansprechen; Sie haben max und min ES-heap-Speicher, um andere Werte. Sie sollte gleich sein, irgendwo zwischen 50 und 60% der gesamte Speicher dem system zur Verfügung. Ich habe derzeit bulk-index-batchs von 100.000 Dokumente in jeder minute ein backfill-app mit NEST als der client, so dass 15,000 sollte trivial sein. Du bist auch auf einem sehr alten version von ES - es ist schon einige große Verbesserungen seit 19.11 (derzeit 0.20.4)
Schreibe einen Kommentar