当前位置: 首页 > 知识库问答 >
问题:

随着索引和文档数量的增加,elasticsearch批量索引的速度会变慢

宗政兴发
2023-03-14
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设置为4G,ES_MIN_MEM设置为2G

每天晚上,我们在。NET应用程序中使用NEST对15000个文档进行索引/重新索引。在任何给定时间,只有一个索引具有<=15000个文档。

当服务器第一次安装时,索引和搜索在最初的几天里是快速的,然后索引开始变得越来越慢。大容量索引一次索引100个文档,一段时间后,大容量操作最多需要15秒才能完成。之后,我们开始看到大量以下异常和索引研磨停止。

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) : 
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();
    }
}
...
...
finally
{
    EnableRefreshInterval();
    elasticClient.Optimize("products");
}

共有1个答案

封俊艾
2023-03-14

抱歉--我刚开始写另一篇相当长的评论,我想我应该把它都写在一个答案中,以防它对其他人有利...

ES_HEAP_SIZE

我在这里注意到的第一件事是,您说您将elasticsearch的max和min堆值设置为不同的值。这些应该是一样的。在configuration/init.d脚本中,应该有一个可以设置的EX_HEAP_SIZE。确保只设置这个值(而不是最小值和最大值),因为它将最小值和最大值设置为相同的值,这是您想要的。如果不这样做,JVM将在您开始需要更多内存时阻塞java进程--请参阅最近在github上发表的一篇关于中断的文章(这里引用了一段话):

升级

Elasticsearch还是相当新的。计划相当频繁地升级,因为在您所使用的版本(0.19.11)和当前版本(0.20.4)之间引入的bug修复非常重要。有关详细信息,请参阅ES站点。您使用的是Java7,这绝对是正确的方法,我从Java6开始,很快就意识到它不够好,尤其是对于批量插入。

插件

 类似资料:
  • 问题内容: 我正在尝试将JSON文件批量索引到新的Elasticsearch索引中,但无法这样做。我在JSON中有以下示例数据 我在用 当我尝试使用Elasticsearch的标准批量索引API时,出现此错误 任何人都可以帮助索引这种类型的JSON吗? 问题答案: 您需要做的是读取该JSON文件,然后使用端点期望的格式构建一个批量请求,即,一行用于命令,一行用于文档,并用换行符分隔…冲洗并重复以下

  • 问题内容: 我需要为索引中的所有文档添加一个新字段,而无需下拉文档并将其推回备份(这将需要大约一天的时间)。是否可以使用_BULK API实现此目的? 我还研究了update_by_query插件,似乎只需要将它们拉下并推回自己的位置即可。 问题答案: 是的,批量API支持更新,可以使用部分文档或脚本添加新字段。要遍历文档ID,请执行扫描并在将fields参数设置为空数组的情况下滚动。

  • ES5.5文档给出了一个大容量索引的明确示例: 但它也说 endpoint为/_bulk、/{index}/_bulk和{index}/{type}/_bulk。当提供了索引或索引/类型时,默认情况下将在未显式提供它们的批量项上使用它们。 但我不能让这一切奏效。 > 我尝试了/myindex/bulkendpoint,但元数据中没有指定类型。 我在指定了“_type”:“_default_”的情况

  • > 下载了。90.6,解压缩,将弹性搜索移动到/usr/share/elasticsearch(在centosx64 6.4上具有chmod 777-r权限),将集群重命名为somethingdupd,并启动服务器。 根据文档,我应该能够做到这一点。但它也什么也不做:

  • 我正在对ElasticSearch进行基准测试,以实现非常高的索引吞吐量。 我目前的目标是能够在几个小时内索引30亿(3,000,000,000)文档。为此,我目前有3台windows服务器机器,每台16GB内存和8个处理器。插入的文档有一个非常简单的映射,只包含少数数字非分析字段(被禁用)。 使用这个相对适中的钻机,我能够达到每秒大约120,000个索引请求(使用大桌子监控),我相信吞吐量可以进

  • 什么是站点索引量   站点中有多少页面可以作为搜索候选结果,就是一个网站的索引量。  站点内容页面需要经过搜索引擎的抓取和层层筛选后,方可在搜索结果中展现给用户。页面通过系统筛选,并被作为搜索候选结果的过程,即为建立索引。  目前site语法的数值是索引量估算值,比较不准。推荐站长们使用我们的新工具,同时我们也正在努力改进site语法。  如何使用百度索引量工具 第一步,注册并登录百度搜索资源平台