Amazon Elasticsearch - 并发批量请求

2024-02-25

当我通过一个批量请求向 ElasticSearch 添加 200 个文档时,速度非常快。

但我想知道是否有机会加快这一进程并发执行:20 个并发执行,每个并发执行 10 个文档。

我知道这效率不高,但也许有机会通过并发执行来加快进程?


较低的并发性更适合批量文档插入。某些并发性在某些情况下是有帮助的——It Depends™,我会详细介绍它——但并不是一个重大的或自动的胜利。

当涉及到 Elasticsearch 的写入性能时,有很多可以调整的地方。您应该检查一个非常快速的胜利:您的连接是否使用 HTTP keep-alive ?这将节省大量设置每个连接的 TCP 和 TLS 开销。仅仅这一改变就可以极大地提升性能,并且还可以为您的索引管道揭示一些有意义的架构注意事项。

所以检查一下,看看进展如何。从那里开始,我们应该从底部开始,然后向上努力。

磁盘上的索引是Lucene。 Lucene 是一个分段索引。这index这部分是您首先使用 Elasticsearch 的核心原因:可以在 O(log N) 时间内搜索排序术语的字典。这是超级快速和可扩展的。段部分是因为插入索引并不是特别快 - 根据您的实现,维护排序的成本为 O(log N) 或 O(N log N)。

所以 Lucene 的技巧是缓冲这些更新并附加一个新的段;本质上是迷你指数的集合。搜索一些相对较少数量的段仍然比每次更新时花费所有时间维护排序索引要快得多。随着时间的推移,Lucene 会照顾merging这些片段将它们保持在某个合理的大小范围内,并在此过程中删除已删除和覆盖的文档。

在 Elasticsearch 中,每个分片都是一个独特的 Lucene 索引。如果您的索引只有一个分片,那么拥有多个并发的批量更新流几乎没有什么好处。应用程序端的并发性可能会有一些好处,具体取决于索引管道收集和组装每批文档所需的时间。但在 Elasticsearch 方面,这只是一组缓冲区被写到一个又一个的段中。

分片使这变得更有趣。

Elasticsearch 的优势之一是能够分割跨多个分片的索引的数据。这有助于提高可用性,并有助于工作负载扩展到超出单个服务器的资源范围。

遗憾的是,并发性应该与索引所具有的主分片的数量相等或成比例,这并不那么简单。不过,作为一种粗略的启发式方法,这并不是一件可怕的事情。

您会看到,在内部,第一个处理请求的 Elasticsearch 节点会将批量请求转换为一系列单独的文档更新操作。每个文档更新都会发送到托管该文档所属分片的适当节点。响应由批量操作收集,以便它可以在响应中向客户端发送批量操作的摘要。

因此,此时,根据文档分片路由,在处理传入批量请求的过程中,某些分片可能比其他分片更繁忙。那有可能吗matter?我的直觉告诉我事实并非如此。这是可能的,但这将是不寻常的。

在我见过的大多数测试和分析中,以及根据我十多年使用 Lucene 的经验,索引的缓慢部分是将文档值转换为倒排索引格式。解析文本、将其分析为术语等可能非常复杂且成本高昂。只要批量请求具有足够的文档并且在分片之间分布得足够好,并发性就不会像在分片和段级别完成的工作饱和那样有意义。

在调整批量请求时,我的建议是这样的。

  • 使用 HTTP 保持活动状态。这不是可选的。 (您正在使用 TLS,对吧?)
  • 选择每个请求花费适当时间的批量大小。大概1秒左右,可能不会超过10秒。
  • 如果您愿意,可以测量每个批量请求花费的时间,并动态地增加和缩小您的批次。

持久队列可以释放很多功能。如果可以获取和组装文档并将它们插入到 Kafka 中,那么该过程可以并行运行以使数据库饱和并并行化任何文档的非规范化或准备。然后,一个不同的进程从队列中提取并向服务器发送请求,并且通过一些轻微的协调,您可以在不同阶段测试和调整不同的并发性。当队列有助于将集群暂时置于只读模式时,队列还可以让您暂停各种迁移和维护任务的更新。

我在整个答案中都避免了复制,因为我建议调整复制的原因只有一个。那就是当您批量创建不服务任何生产流量的索引时。在这种情况下,它可以帮助通过服务器群节省一些资源,以关闭对索引的所有复制,并在索引基本上完成数据加载后启用复制。

最后,如果您无论如何提高并发性会怎么样?有什么风险?某些工作负载不控制并发性,并且没有时间或资源在搜索引擎前面放置队列。在这种情况下,Elasticsearch 可以避免相当大量的并发。它有相当充足的线程池来处理并发文档更新。如果这些线程池已饱和,它将拒绝响应,并显示 HTTP 429 错误消息和有关超出队列深度的明确消息。这些可能会影响集群的稳定性,具体取决于可用资源和索引中的分片数量。但这些都是非常引人注目的问题。

底线:不,相对于 1 个包含 200 个文档的批量,20 个并发批量(每个包含 10 个文档)可能不会提高性能。如果您的批量操作速度很快,您应该增加它们的大小,直到它们运行一两秒,或者出现问题。使用保活。如果存在其他应用程序端开销,请将并发性增加到 2 倍或 3 倍,并根据经验进行测量。如果索引对于任务至关重要,请使用快速、持久的队列。

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

Amazon Elasticsearch - 并发批量请求 的相关文章

随机推荐

  • 为什么 Intellij 默认 getter/setter 模板会删除我的布尔“is”变量名前缀?

    我有一个实体 我将变量定义为布尔值 并使用 Intellij Idea Shortcuts 创建了 Getter 和 Setter 方法 private Boolean isForLaboratory false 创建后生成如下 publi
  • cosmosdb mongo api 不适用于某些命令

    我在用cosmosdb在天蓝色上我正在使用MongoDB API我有一个 要求 集合里面有一个 claims array 如果我使用这个命令 db getCollection requests find claims id 1002 它不适
  • clang vs gcc - 空通用 lambda 变量参数包

    我想我找到了另一个 clang 与 gcc lambda 和可调用对象之间的不一致 decltype l operator 应该等于C operator 但是如果通用 lambda 中的可变参数包留空 gcc 会拒绝编译 15 错误 与调用
  • Highcharts - 仅当直接悬停在点上时显示工具提示

    Highcharts 的默认体验似乎是距离光标最近的点 水平 处于悬停状态 这意味着当您到达行中下一个点的一半以上时 就会触发工具提示 我希望当我直接将鼠标悬停在一个点上时触发工具提示 然后保持活动状态 直到我将鼠标直接悬停在另一个点上 这
  • adb Push/Pull 的默认工作目录是什么以及如何更改它?

    我使用 adb 从 android sdcard 中提取了一个文件 它似乎转到了c documents and settings userName默认情况下 我不知道它是如何设置到这个文件夹的 因为这不是安装 adb 的地方 但可能与以下事
  • 如何在 Dropwizard 项目(Angular 7 前端)中创建并开始使用嵌入式 Apache Derby 数据库

    我正在阅读 Derby 文档并遵循所有说明 我已成功安装它 将其解压到我的 Linux 计算机并设置 DERBY HOME 路径 我有一个完整的 REST API 项目 带有 Angular 7 前端和 Dropwizard 后端 我在后端
  • 有没有办法在 numpy.hist 中返回相同长度的数组?

    我正在尝试在 python 中创建直方图 用一些自定义值对 y 轴值进行标准化 为此 我想这样做 import numpy as np import matplotlib pyplot as plt data np loadtxt foo
  • 惰性 var 属性初始化两次是否正常?

    当我使用房产时 我遇到过很奇怪的情况lazy关键词 我知道这个关键字表示属性的初始化将被推迟到实际使用变量为止 但是 它并没有像我预期的那样工作 它运行两次 class TestLazyViewController UIViewContro
  • 为什么 is 运算符在给定 null 时返回 false?

    在我看来 is运营商有点不一致 bool Test Returns false but should return true return null is string 人们期望null值属于任何引用 或可为空 类型 事实上 C 语言规范的
  • http_build_query() 点转换为下划线

    请检查以下数组 Array bunrey gt Array 0 gt 20130730181908615391000000 mt shasta gt Array 0 gt 20130708203742347410000000 1 gt 20
  • 如何使用 jQuery 检测 IE 8?

    我不仅需要检测浏览器类型 还需要使用 jQuery 检测浏览器版本 主要是我需要确定它是否是 IE 8 我不确定我是否做得正确 如果我做 if jQuery browser version gt 8 0 dosomething 我不确定它是
  • 在 python selenium webdriver 中发送密钥而不指定元素

    我有一个页面 其源代码不可用 但有一个输入框 光标在闪烁 我可以在文本框中写入一些内容而不找到该元素吗 我的意思是 发送键可以通过某种方式自动查找焦点输入框并在其中键入输入 我的代码显然不能工作 driver send keys testd
  • 使用意图上传图像

    我正在尝试为我的 Android 移动应用程序上传图像 对于从图库文件夹上传的图像 该代码运行良好 但是 如果我从 最近的图像 文档 下载 中选择任何图像 则图像路径不会被提取 无法上传图像 你能帮我解决这个问题吗 这是我的编码供您参考 p
  • 在谷歌中搜索单词并想使用java程序找到每个单词的命中

    我有30000个字典单词 我想在 Google 中搜索每个单词 并想使用 Java 程序找到每个单词的匹配项 是否可以 Look up
  • 如何在 EF Core 中放弃对上下文的更改

    我有一个巨大的 json 格式的 扁平化 对象列表 以及一个有点复杂的关系数据库模式 大约 20 个表对应于一个扁平化对象 我正在尝试在新的关系数据库中自动插入这些扁平对象 foreach var flattenedObject in fl
  • jQuery-UI 可排序 - 更新后同步数组(模型)

    假设我有一个包含数据的数组 它可能来自 Ajax 但无需在此处执行此操作 使用该数组 我生成 UL 元素的内容 并使用 jQuery UI 使 UL 可排序 在客户端对它进行排序之后 我希望保持数组的顺序与 UL 同步 有没有一种优雅的方法
  • 如何用python画动态规划表

    What is a good way to draw a dynamic programming such as this one with the path in python 我在网上查了一下 我看到了pygame http pygam
  • 从 PHP 关联数组中弹出键和值

    假设 S 是 PHP 中的关联数组 我需要从中检索并提取第一个元素 包括值和键 我会用 value1 array pop S 但它只给了我价值 我可以用 K array keys S key1 array pop K value1 arra
  • 在graphviz中从节点到边绘制边

    是否可以在 graphviz 中从节点绘制一条边到现有边的中心 我想复制化学或生物网络中常见的这种类型的反应图 Thanks Peter 是的 您可以使用不可见节点 例如这个例子 https stackoverflow com questi
  • Amazon Elasticsearch - 并发批量请求

    当我通过一个批量请求向 ElasticSearch 添加 200 个文档时 速度非常快 但我想知道是否有机会加快这一进程并发执行 20 个并发执行 每个并发执行 10 个文档 我知道这效率不高 但也许有机会通过并发执行来加快进程 较低的并发