我们几乎将弹性搜索用作缓存,存储在时间窗口中找到的文档。我们不断地插入大量不同大小的文档,然后我们使用文本查询结合日期过滤器在 ES 中进行搜索,这样当前线程就不会得到它已经看到的文档。像这样的东西:
“((字 1 与字 2)或(字 3 与字 4))与插入日期 > 1389000”
我们使用 TTL 功能将弹性搜索中的数据保持 30 分钟。今天,我们至少有 3 台机器每分钟为每台机器批量插入新文档,并连续不断地使用上述查询进行搜索。
我们在索引和检索这些文档时遇到了很多麻烦,ES 索引和返回的文档的吞吐量并不大。我们甚至无法每秒索引 200 个文档。
我们认为问题在于同时查询、插入和 TTL 删除。我们不需要在弹性中保留旧数据,我们只需要在给定时间在弹性中索引的文档的小时间窗口。我们应该做些什么来提高我们的表现?
提前致谢
机器的种类:
- 一个 Amazon EC2 中型实例(3.7 GB RAM)
附加信息:
用于构建索引的代码是这样的: https ://gist.github.com/dggc/6523411
我们的 elasticsearch.json 配置文件: https ://gist.github.com/dggc/6523421
编辑
很抱歉这么久才给你们一些反馈。我们公司的事情有点忙,我选择等待平静的时间来更详细地说明我们如何解决我们的问题。我们仍然需要做一些基准测试来衡量实际的改进,但关键是我们解决了这个问题:)
首先,我认为索引性能问题是由部分使用错误引起的。正如我之前所说,我们使用 Elasticsearch 作为一种缓存,在 30 分钟的时间窗口内查找文档。我们在 elasticsearch 中查找内容与某个查询匹配且插入日期在某个范围内的文档。然后,Elastic 会向我们返回完整的文档 json(除了索引内容之外,还有大量数据)。我们的配置错误地对文档 json 字段进行了弹性索引(除了 content 和 insertDate 字段),我们认为这是导致索引性能问题的主要原因。
然而,我们也做了一些修改,正如这里的答案所建议的那样,我们相信这也提高了性能:
我们现在不使用 TTL 功能,而是在一个公共别名下使用两个“滚动索引”。当索引变旧时,我们创建一个新索引,为其分配别名,然后删除旧索引。
我们的应用程序每秒执行大量查询。我们认为这会严重影响弹性,并降低索引性能(因为我们只使用一个节点进行弹性搜索)。我们为节点使用了 10 个分片,这导致我们向弹性发起的每个查询都被转换为 10 个查询,每个分片一个。由于我们可以随时丢弃 elastic 中的数据(因此改变分片数量对我们来说不是问题),我们只需将分片数量更改为 1,大大减少了弹性节点中的查询数量。
我们的索引中有 9 个映射,每个查询都会被触发到一个特定的映射。在这 9 个映射中,大约 90% 的插入文档进入了其中两个映射。我们为每个映射创建了一个单独的滚动索引,并将其他 7 个保留在同一索引中。
不是真正的修改,但我们从 Sematext 安装了 SPM(可扩展性能监控),这使我们能够密切监控弹性搜索并了解重要指标,例如触发的查询数量 -> sematext.com/spm/index.html
我们的使用量相对较小。我们有大约 100 个文档/秒到达,它们必须被索引,峰值为 400 个文档/秒。至于搜索,我们每分钟大约有 1500 次搜索(在更改分片数量之前是 15000 次)。在进行这些修改之前,我们遇到了这些性能问题,但现在不是了。