【问题标题】:Initial ElasticSearch Bulk Index/Insert /Upload is really slow, How do I increase the speed?初始 ElasticSearch Bulk Index/Insert /Upload 真的很慢,如何提高速度?
【发布时间】:2018-08-12 06:13:38
【问题描述】:

我正在尝试将大约 700 万个文档上传到 ES 6.3,并且我遇到了批量上传速度慢到爬行大约 100 万个文档的问题(我在索引中没有此之前的文档) .

我有一个 16GB 的 3 节点 ES 设置,8GB JVM 设置,1 个索引,5 个分片。 我已关闭刷新(“-1”),将副本设置为 0,将索引缓冲区大小增加到 30%。

在我的上传方面,我有 22 个线程,每个批量插入请求运行 150 个文档。这只是一个使用 Postgresql、ActiveRecord、Net/HTTP(用于网络调用)和使用 ES Bulk API(无 gem)的基本 ruby​​ 脚本。

对于我的所有节点和上传机器,CPU、内存、SSD 磁盘 IO 都很低。

我已经能够获得大约每分钟 30k-40k 的插入,但这对我来说似乎真的很慢,因为其他人已经能够做到每秒 2k-3k。我的文档确实有嵌套的 json,但它们对我来说似乎不是很大(有没有办法检查单个大小的文档或平均值?)。

我希望能够在 12 到 24 小时内批量上传这些文档,看起来 ES 应该可以处理,但是一旦达到 100 万,它似乎就会慢下来。

我对 ES 还很陌生,因此我们将不胜感激。我知道这似乎是已经被问过的问题,但我已经尝试了几乎所有我能找到的东西,并且想知道为什么我的上传速度会变慢。

我还检查了日志,只看到一些关于映射字段无法更改的错误,但没有关于内存溢出或类似情况的错误。

ES 6.3 很棒,但我也发现 API 已更改为 6,并且不再支持人们使用的设置。

我认为我在与原始数据库的活动连接处发现了一个瓶颈,并增加了连接池,这有所帮助,但在大约 100 万条记录时仍然缓慢爬行,但在大约 8 小时的运行后达到了 200 万条记录。

p>

我还在一台大机器上做了一个实验,用来运行上传作业,运行 80 个线程,每个线程上传 1000 个文档。我做了一些计算,发现我的文档每个文档大约 7-10k,因此每个批量索引上传 7-10MB。这使文档数量更快地达到 1M,但是一旦到达那里,一切都会变慢。机器统计数据仍然很低。我确实每隔 5 分钟左右在作业的日志上看到线程的输出,大约在同一时间看到 ES 计数发生变化。

ES 机器的 CPU 和内存仍然很低。 IO 约为 3.85MB,网络带宽为 55MB,然后降至 20MB 左右。

任何帮助将不胜感激。不确定我是否应该尝试 ES gem,并使用可能保持连接打开的批量插入,或者尝试完全不同的插入。

【问题讨论】:

  • 我忘了提到除了索引更改之外,ES 安装来自 apt-get es repo。除了将 ES 置于生产模式所需的步骤(运行 ES 网站清单)之外,我还没有真正进行任何自定义更改。
  • 原始文档在哪个数据库中?
  • 文档原本在 Postgresql 中。我已经开始分析该数据库,并注意到一旦您使用大约 100 万的偏移量,查询就会开始花费很长时间。我有多个索引,但我猜我需要一个这个特定的查询,或者升级数据库硬件。

标签: ruby multithreading elasticsearch activerecord bulkinsert


【解决方案1】:

ES 6.3 很棒,但我还发现 API 已更改为 6,并且不再支持人们使用的设置。

您能否举例说明 6.0 和 6.3 之间的重大更改对您来说是个问题?我们真的在努力避免这些,但我真的想不起任何事情。

我已经开始分析该数据库,并注意到一旦您使用大约 100 万的偏移量,查询就会开始花费很长时间。

深度分页在性能方面很糟糕。有一篇很棒的博文no-offset,它解释了

  • 为什么不好:要获得 1,000 到 1,010 的结果,您对前 1,010 条记录进行排序,丢弃 1,000 条,然后发送 10 条。分页越深,成本越高
  • 如何避免:为您的条目设置一个唯一的顺序(例如,按 ID 或结合日期和 ID,但绝对是绝对的)并添加从何处开始的条件。例如,按 ID 排序,获取前 10 个条目,并保留第 10 个条目的 ID 以供下一次迭代。再次按 ID 排序,但条件是 ID 必须大于上一次运行中的最后一个,并获取接下来的 10 个条目并再次记住最后一个 ID。重复直到完成。

通常,通过您的设置,插入超过 100 万条记录应该不会有问题。我会先查看获取数据的部分。

【讨论】:

  • Xeraa:使用 LIMIT 和 OFFSET 从 Postgresql 中提取数据是问题所在。我在大约 200 万行处运行了一个限制和偏移查询,即使在清理并添加另一个索引并删除 2 个索引之后,查询也持续了很长时间(5 分钟左右)。我使用 > 操作符和 FETCH FIRST 1000 ROWS ONLY 运行了相同的查询,它花费了大约 300 毫秒。基本上,当使用 LIMIT 和 OFFSET 时,我的上传脚本一直在等待 Postgresql 完成对大表的 SELECT 查询。我将重新编码脚本以使用 NO-OFFSET 方式遍历初始上传的记录。
  • 因此,在进行大量谷歌搜索并找到其他人的设置时,出现的大部分内容都是将您的性能设置设置为类似于 [gist.github.com/reyjrar/4364063]。我猜这是 ElasticSearch 5.x 及以下版本,但在 6.x 中很难找到相同的设置,并注意到它们从 yml 文件转移到了 API。
  • 很好用。我只是在复制配置时要小心——通常它们弊大于利,因为它们用于特定的设置(工作负载、硬件……) / 是旧 Elasticsearch 版本的改进,但现在正好相反 / 。 .. 从默认值开始,然后在必要时进行设置;尽管批量、刷新和复制对于您的场景来说绝对是不错的设置。
  • 是的,我并没有试图复制其他人的配置,而是很好地参考了什么是优化上传的好策略,然后将其设置回优化搜索。一旦你深入研究 ES 文档,我意识到大部分内容都在那里。很高兴看到其他人的配置,但看看我所做的是否是正确的策略。希望这篇文章也对其他人有所帮助。
猜你喜欢
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多