我们正在将 Elasticsearch 实施为我们组织中的搜索解决方案。对于 POC,我们实现了一个 3 节点集群(每个节点具有 16 个 VCore 和 60 GB RAM 和 6 * 375 GB SSD),所有节点都充当主节点、数据节点和协调节点。由于它是 POC 索引速度不是考虑因素,我们只是想看看它是否有效。
注意:我们确实尝试在我们的 POC 集群上索引 2000 万个文档,大约需要 23-24 小时才能做到这一点,这促使我们花时间设计具有适当大小和设置的生产集群。
现在我们正在尝试实现一个生产集群(在 Google Cloud Platform 中),重点是索引速度和搜索速度。
我们的用例如下:
We are aiming for a 0.5 million document per second indexing throughput.当我们添加更多客户时,我们也在寻找一种横向扩展的策略。我在后面的章节中提到了这个策略。
We are aiming for sub second query times for 95th percentile of queries.我在这个论坛和其他博客上做了很多阅读,其中公司拥有成功运行的高性能 Elasticsearch 集群。
以下是我的学习:
有专用的主节点(总是奇数以避免裂脑)。这些机器可以是中型的(16 个 vCore 和 60 Gigs ram)。
将 50% 的 RAM 分配给 ES 堆,但不超过 31 GB 以上的堆大小以避免 32 位指针。我们计划在每个节点上将其设置为 28GB。
数据节点是集群的主力,因此必须占用大量 CPU、RAM 和 IO。我们计划拥有(64 个 VCore、240 Gb RAM 和 6 * 375 GB SSD)。
也有协调节点来处理批量索引和搜索请求。
现在我们计划从以下配置开始:
3 Masters - 16Vcores, 60GB RAM and 1 X 375 GB SSD
3 Cordinators - 64Vcores, 60GB RAM and 1 X 375 GB SSD (Compute Intensive machines)
6 Data Nodes - 64 VCores, 240 Gb RAM and 6 * 375 GB SSDs
Run Code Online (Sandbox Code Playgroud)
我们计划为每个传入客户端添加 1 个数据节点。
现在由于硬件不在 Windows 中,让我们专注于索引策略。
我整理的一些最佳实践如下:
接下来是批量索引过程。我们有一个完整的elasticsearch-hadoopSpark安装,将使用连接器将数据从 Spark 推送到我们的集群。
在编制索引期间,我们将 设置refresh_interval为1m以确保刷新频率较低。
我们正在使用 100 个并行 Spark 任务,每个任务都2MB为批量请求发送数据。因此,有时会有2 * 100 = 200 MB大量请求,我认为这完全在 ES 可以处理的范围内。我们绝对可以根据反馈或反复试验来更改这些设置。
我已经阅读了有关设置缓存百分比、线程池大小和队列大小设置的更多信息,但我们计划在开始时将它们保留为智能默认值。
我们对 GC使用两者Concurrent CMS或G1GC算法持开放态度,但需要就此提供建议。我已经阅读了使用这两种方法的利弊以及在使用哪种方法的困境中。
现在我的实际问题:
向协调器节点发送批量索引请求是一个好的设计选择还是我们应该将其直接发送到数据节点?
我们将通过协调器节点发送查询请求。现在我的问题是,假设我的数据节点有 64 个内核,每个节点的线程池大小为 64,队列大小为 200。假设在搜索数据节点线程池和队列大小完全耗尽期间,协调器节点是否会继续接受和缓冲搜索请求,直到他们的队列也填满?还是每个查询请求都会阻止协调器上的 1 个线程?
假设一个搜索请求到达协调器节点,它在那里阻塞 1 个线程,并将请求发送到数据节点,数据节点又根据查询数据所在的位置阻塞数据节点上的线程。这个假设正确吗?
参考
\n\n\n我们确实尝试在 POC 集群上索引 2000 万个文档,大约花了 23-24 小时
\n
这是令人惊讶的小 \xe2\x80\x94 就像不到 250 个文档/秒。我认为我的 8GB RAM 笔记本电脑可以在 2 小时内插入 1300 万份文档。要么您的文档非常复杂,有一些错误的设置,要么您的瓶颈位于摄取方面。
\n\n关于你的节点:我认为你可以轻松地在主节点上使用更少的内存(比如 32GB 应该足够了)。数据节点上的内存也相当高;我通常期望堆与其余内存的比例为 1:1,或者对于大量“热”数据可能为 1:3。不确定您是否能充分利用 1:7.5 的比例。
\n\nCMS 与 G1GC:如果您有当前的 Elasticsearch 和 Java 版本,则两者都是一个选项,否则 CMS。您通常会用吞吐量换取 (GC) 延迟,因此,如果您进行基准测试,请确保有足够长的时间范围来正确命中 GC 阶段,并尽可能并行地运行生产查询。
\n\n\n\n\n向协调器节点发送批量索引请求是一个好的设计选择还是我们应该将其直接发送到数据节点?
\n
我想说协调员很好。除非您使用自定义路由键并且批量仅包含该特定数据节点的数据,否则 5/6 的文档无论如何都需要转发到其他数据节点(如果您有 6 个数据节点)。您可以将批量处理和协调处理卸载到非数据节点。\n但是,总体而言,拥有 3 个附加数据节点并跳过专用协调节点可能更有意义。尽管这只能通过对特定场景进行基准测试才能确定。
\n\n\n\n\n现在我的问题是,假设我的数据节点有 64 个核心,每个节点的线程池大小为 64,队列大小为 200。假设在搜索期间数据节点线程池和队列大小完全耗尽,那么协调器节点是否会在其末尾继续接受和缓冲搜索请求,直到队列也填满为止?或者每个查询请求协调器上的 1 个线程也会被阻塞?
\n
我不确定我是否理解这个问题。但是您是否研究过https://www.elastic.co/blog/why-am-i-seeing-bulk-rejections-in-my-elasticsearch-cluster,这可能会对这个主题有更多的了解?
\n\n\n\n\n当批量索引正在进行时(假设我们不会并行地为所有客户端运行索引并将它们安排为顺序)如何进行最佳设计以确保在此批量索引期间查询时间不会受到太大影响。
\n
虽然不同的查询操作有不同的队列,但没有明确的任务分离(例如“仅使用 20% 的资源用于索引)。也许在并行批量请求上更加保守,以避免节点过载。
\n\n如果您在索引时没有从索引中读取数据(理想情况下,完成后翻转别名):您可能希望完全禁用刷新率并让 Elasticsearch 根据需要创建段,但执行强制刷新并更改设置完成后。另外,您也可以尝试在索引时使用 0 个副本运行,完成后将副本更改为 1,然后等待它完成 \xe2\x80\x94,尽管我会进行基准测试,看这是否对整体有帮助以及是否值得增加了复杂性。
\n| 归档时间: |
|
| 查看次数: |
804 次 |
| 最近记录: |