我们正在针对我们目前正在构建的系统上的弹性搜索遇到一些性能问题或异常。
要求: 我们需要为多个客户捕获数据,这些客户将近乎实时地查询和报告这些数据。收到的所有文档都是具有相同属性的相同格式,并且是扁平结构(所有字段都是主要类型,没有嵌套对象)。我们希望将每个客户的信息彼此分开。
接收和查询的数据的频率: 我们以每秒200到700个文档的波动率接收每个客户的数据 - 峰值在当天中间。 查询将主要是每个客户大约1200万个文档的聚合 - 直方图/百分位数以显示随时间变化的模式以及偶尔的原始文档检索以查明特定时间点发生的情况。我们的目标是以不同的文件插入速度为50到100个客户提供服务 - 最小的一个可能是20个docs / sec到最大的一个,达到1000 docs / sec几分钟。
我们如何存储数据: 每个客户每天都有一个索引。例如,如果我们有5个客户,那么整周将有总共35个索引。我们每天打破它的原因是因为它主要是最近的两个被偶尔查询其余的其他人。我们也这样做,所以我们可以独立于客户删除旧索引(有些人可能希望保留7天,大约14天的数据)
我们如何插入 我们每分钟发送10到2000个数据。一份文件大约是900字节。
环境 AWS C3-Large - 3个节点 为测试目的,所有索引都使用10个分片和2个副本创建 Elasticsearch 1.3.2和1.4.1
我们注意到了什么:
如果我仅将数据推送到一个索引,当插入速率大约为每秒100个文档时,插入的每个批处理的响应时间从80到100毫秒开始。我提升它,我可以达到1600,然后插入速率接近每批1秒,当我将它增加到接近1700时,由于并发插入,它将在某个时刻撞到墙壁,时间将螺旋到4或5秒。说,如果我降低插入率,Elasticsearch可以很好地恢复。 CPU使用率随着速率的增加而增加。
如果我同时推送到2个索引,我总共可以达到1100个,并且每秒900个文档的CPU上升到93%。 如果我同时推送3个索引,我可以达到150个,CPU上升到95%到97%。我试过很多次了。有趣的是,响应时间大约是109毫秒。我可以将负载增加到900,响应时间仍然在400到600左右,但CPU保持不变。
问题:
根据我们的要求和上述发现,设计方便了什么?有没有我可以做的测试来了解更多信息?我需要检查(和更改)的设置吗?
答案 0 :(得分:4)
过去几年,我在https://bonsai.io上已经在AWS上托管了数千个Elasticsearch集群,并且有很多容量规划对话听起来像这样。
首先,听起来像你有一个非常好的集群设计和测试平台。我在这里的第一个直觉是你合法地接近你的c3.large实例的极限,并且想要很快升级到c3.xlarge(或更大)。
如果您的租户相对较少,则每个租户每天的索引可能是合理的。您可以考虑所有租户每天的索引,使用过滤器将搜索重点放在特定租户上。除非丢弃旧数据明显节省成本,否则过滤器也应足以强制执行数据保留窗口。
对每个租户的索引进行细分的主要好处是在不同的Elasticsearch集群之间移动您的租户。如果您的租户使用量远大于其他租户,这可能会有所帮助。或者将Elasticsearch集群状态管理的可能性降低为所有租户的单点故障。
要记住的其他一些事情可能有助于解释您所看到的效果差异。
最重要的是,索引是令人难以置信的CPU瓶颈。这是有道理的,因为Elasticsearch和Lucene基本上只是非常奇特的字符串解析器,而且你正在发送成堆的字符串。 (此处桩是合法的测量单位,对吗?)您的主要瓶颈将是CPU核心的数量和速度。
为了在编制索引时充分利用CPU资源,您应该考虑使用的主分片数。我建议从三个主分片开始,在集群中的三个节点上均匀分配CPU负载。
对于生产,你几乎肯定会最终使用更大的服务器。目标是您的峰值索引要求的总CPU负载最终低于50%,因此您有一些额外的开销来处理您的搜索。聚合也相当CPU饥饿。额外的性能开销也有助于优雅地处理任何其他无法预料的情况。
你提到同时推送到多个索引。在批量更新到Elasticsearch时,我会避免并发,转而使用Bulk API进行批量更新。您可以使用群集级/_bulk
端点批量装载多个索引的文档。让Elasticsearch在内部管理并发性,而不会增加解析更多HTTP连接的开销。
这只是对性能基准测试主题的快速介绍。 Elasticsearch文档有一篇关于Hardware的好文章,它也可以帮助您规划群集大小。