随着索引和文档数量恒定,elasticsearch 批量索引会随着时间的推移而变慢

2024-05-02

我遇到了使用 .NET NEST 客户端和 ElasticSearch 进行批量索引的性能随着时间的推移、索引数量和文档数量恒定而降低的情况。

我们正在奔跑ElasticSearch Version: 0.19.11, JVM: 23.5-b02在具有 Ubuntu Server 12.04.1 LTS 64 位和 Sun Java 7 的 m1.large Amazon 实例上。除了 Ubuntu 安装附带的内容之外,该实例上没有运行任何其他内容。

Amazon M1 大型实例: from http://aws.amazon.com/ec2/instance-types/ 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 设置为 4g,ES_MIN_MEM 设置为 2g

每天晚上,我们在 .NET 应用程序中使用 NEST 索引/重新索引约 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();
    }
}

重新启动elasticsearch守护进程似乎没有任何区别,但删除索引并重新索引所有内容却会产生任何影响。但几天后我们就会遇到同样的索引速度慢的问题。

我刚刚删除了索引,并在每次批量索引操作后重新启用刷新间隔后添加了优化,希望这可以防止索引降级。

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

我在这里做错了什么吗?


抱歉 - 刚刚开始写另一条很长的评论,我想我会把它全部放在答案中,以防它对其他人有利......

ES_HEAP_SIZE

我在这里注意到的第一件事是,您说您将 elasticsearch 的最大和最小堆值设置为不同的值。这些应该是相同的。在configuration/init.d脚本中应该有一个可以设置的EX_HEAP_SIZE。请务必仅设置此值(而不是最小值和最大值),因为它将把最小值和最大值设置为您想要的相同值。如果你不这样做,当你开始需要更多内存时,JVM 将阻止 java 进程 -看看这篇很棒的文章 https://github.com/blog/1397-recent-code-search-outages最近 github 发生了一次中断(引用如下):

设置 ES_HEAP_SIZE 环境变量,以便 JVM 对最小和最大内存使用相同的值。将 JVM 配置为具有不同的最小值和最大值意味着每次 JVM 需要额外的内存(达到最大值)时,它都会阻止 Java 进程分配内存。与旧的 Java 版本相结合,这解释了当我们的节点向公共搜索开放时,当引入更高的负载和连续的内存分配时,我们的节点会表现出停顿。 Elasticsearch 团队建议设置为系统 RAM 的 50%。

还请查看这篇很棒的文章 http://asquera.de/opensource/2012/11/25/elasticsearch-pre-flight-checklist/从战壕中获取更多的 elasticsearch 配置。

锁定内存以停止交换

根据我的研究,我发现您还应该锁定 java 进程可用的内存量,以避免内存交换。我不是这个领域的专家,但我被告知这也会降低性能。您可以在elasticsearch.yml 配置文件中找到bootstrap.mlockall。

Upgrades

Elasticsearch 还是很新的。计划相当频繁地升级,因为您所在版本 (0.19.11) 和当前版本 (0.20.4) 之间引入的错误修复非常重要。请参阅ES site http://www.elasticsearch.org/download/了解详情。你使用的是 Java 7,这绝对是正确的选择,我开始使用 Java 6,很快意识到它还不够好,特别是对于批量插入。

Plugins

最后,对于遇到类似问题的任何其他人,请安装一个像样的插件,以概述您的节点和 JVM。我建议bigdesk https://github.com/lukas-vlcek/bigdesk- 运行bigdesk,然后使用一些批量插入来点击elasticsearch,并注意奇怪的堆内存模式、大量线程等,一切都在那里!

希望有人觉得这很有用!

干杯, 詹姆士

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

随着索引和文档数量恒定,elasticsearch 批量索引会随着时间的推移而变慢 的相关文章

随机推荐

  • 数据表:根据值更改单元格颜色

    我正在使用 DataTable 创建交互式表 我有 9 列 其中 5 列是值 我想根据每个单元格的具体情况更改其背景颜色 我开始尝试首先更改整个行的颜色 因为这似乎是一个更容易的任务 但我无法改变任何事情 我的代码如下
  • 为什么 ReadOnlySpan 不能用作泛型委托和泛型方法的类型参数?

    我明白为什么ReadOnlySpan不能用作泛型类的类型参数 ReadOnlySpan仅是堆栈 因此它不能用作字段类型 字段成员像其容器对象一样存在于堆中 但是返回值和参数始终只是堆栈 所以为什么ReadOnlySpan不能用作泛型委托和泛
  • 未处理的异常:SocketException:主机查找失败:(操作系统错误:没有与主机名关联的地址,errno = 7)

    我们已经在 Playstore 中发布了一个发行版本 并且运行得很好 但现在突然间 当我们尝试再次构建并运行代码时 因为我们想要添加新功能 它将不再与我们的后端通信 所以我使用错误作为关键字在网络上进行搜索 发现需要 INTERNET PE
  • 使用“adb devices”命令无法找到 Android 设备

    我正在开发Android申请于macOS我的应用程序在模拟器上运行良好 我想在设备上运行它 但是当我运行时adb devices我什么也没得到 localhost platform tools BF adb devices List of
  • 在react-native中将本地图像uri作为props传递

    我正在尝试将图像的 uri 作为 prop 传递 以便我可以在 React Native 上多次重复使用它 但是 当前的解决方案提示我 require 应该使用字符串文字 const ImageButton source gt
  • Twitter APi“代码”:215,“消息”:“错误的身份验证数据

    接收错误 code 215 message 错误的身份验证数据 in my page var dump page 我读到 Friends exist 不再适用于 1 1 版本 因此我需要使用 Friends lookup 来比较一个 Twi
  • Azure Pipelines 状态徽章未显示在 Markdown 中

    我已经为我的 github 存储库之一设置了 azure 管道 除了构建状态徽章之外 一切都工作正常 它没有正确显示 似乎无法加载图像 目前正在显示 Edit markdown 文件中使用的代码由 azure devops 自动生成 Bui
  • Oracle BLOB 与 VARCHAR

    我需要在表的一列中存储一个 大 SQL 查询 我想使用BLOB场地 需要明确的是 我想存储查询 而不是其结果 最好使用什么 BLOB or a VARCHAR 或者也许还有别的什么 另一种选择是 CLOB 对于文本数据 使用 CLOB 比使
  • git 存储库中的提交次数

    我的一个为期 5 个月的项目即将结束 作为毫无意义的统计数据的粉丝 我想知道自存储库启动以来已经进行了多少次提交 我怎样才能发现这一点 Notes 我知道没有one存储库 我只对本地版本感兴趣 这在颠覆中是微不足道的 因为修订标识符 似乎是
  • 回发后我的 JavaScript 函数在 ASP.NET 中不起作用

    我有共同的功能 我把它折叠起来CommonFunctions js在脚本文件夹中 我将它包含在我的主页上并在我的页面上使用它 当我在页面上进行任何回发时 我的功能不起作用 My CommonFunctions js function gf
  • 使用 List.Sort(Comparison Comparison 在 C# 中对列表进行排序

    我创建了一个类 如下所示 public class StringMatch public int line num public int num of words 我创建了一个列表 List
  • 共享 Google 地图或拍摄 Android 手机屏幕截图

    我正在使用 android google map api v2 开发 android 应用程序 到目前为止我已经取得了以下成绩 打开谷歌地图显示用户的位置 当他行走时 他可以在地图上添加标记 标记他经过的地方 他可以删除标记或拖动它们 我现
  • Kotlin:乐趣与 val

    Kotlin 支持计算属性但我不确定何时使用它们 假设我有一堂课 class Car val color String 并有这个返回的函数true如果汽车是白色的 fun isWhite car Car Boolean return car
  • 各种 Android 设备的应用程序背景大小

    我正在为所有 Android 设备的应用程序设计背景 我在想图像的大小 以像素为单位 是多少 从开发者网站我发现了以下等式 px dp dpi 160 那么 px 取决于两个变量 首先 dp 我们有 xlarge screens are a
  • Ember-cli:导入毯子.js 导致测试运行程序挂起

    我目前正在使用 ember cli 和 ember qUnit 进行测试 我还想将代码覆盖率结果添加到测试输出中 因此经过一些研究后 blanketjs 似乎是可行的方法 我使用以下方法安装了毯子 npm 安装毯子 并将毯子文件夹移至 em
  • 我可以使用 Google Maps API v3 操作 KML 吗?

    我正在 Google Maps API v3 中使用 KMLLayer 加载 KML 是否可以引用地图上的多边形并执行诸如更改颜色或透明度之类的操作 不 你不能那样做 因为 kmllayer 中没有像对象一样的多边形 来自谷歌文档 http
  • 排除“解析错误,意外的‘>’”错误[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我收到这个
  • SQS - 通过 ID 获取消息

    我是否可以使用 Amazon PHP SDK 根据消息 ID 从 SQS 队列获取消息 我是否必须获取队列中的所有消息 然后在服务器上对其进行过滤 我的服务器收到带有队列消息 ID 的 SNS 发起请求 我必须从来自 SQS 的消息数组中过
  • Swift 5 / Xcode 11 更新后模拟器在动画块处冻结

    我在 Xcode 11 中将项目更新为 Swift 5 现在程序在 iPhone 11 模拟器中的动画块处冻结 当我在动画之后设置断点时 它永远不会命中它 重新启动 Xcode 和模拟器并没有解决问题 如果我在设备上运行该程序 它可以正常工
  • 随着索引和文档数量恒定,elasticsearch 批量索引会随着时间的推移而变慢

    我遇到了使用 NET NEST 客户端和 ElasticSearch 进行批量索引的性能随着时间的推移 索引数量和文档数量恒定而降低的情况 我们正在奔跑ElasticSearch Version 0 19 11 JVM 23 5 b02在具