Elasticsearch 是一款 NoSQL 搜索和分析引擎,可轻松用于日志分析、文本搜索、实时分析等。不过,Elasticsearch 本质上是一个复杂的分布式系统,需要使用多种杠杆来实现最佳性能。
在本博客中,我们将介绍解决 Elasticsearch 大规模性能挑战的方法,包括索引速度慢、搜索速度慢、分片和索引大小以及多租户。许多解决方案都源自与拥有大规模操作系统实践经验的工程领导者和架构师的访谈和讨论。
在处理具有高写入吞吐量的工作负载时,您可能需要调整 Elasticsearch 以提高索引性能。我们提供了几种最佳实践,以便为索引提供足够的资源,以便该操作不会影响应用程序中的搜索性能:
增加刷新间隔:Elasticsearch 通过刷新索引使新数据可供搜索。当索引在过去 30 秒内收到查询时,刷新设置为每秒自动发生一次。您可以增加刷新间隔以保留更多资源用于索引。
使用Bulk API :当提取大规模数据时,使用 Update API 的索引时间通常需要数周时间。在这些情况下,您可以使用 Bulk API 以更节省资源的方式加快数据索引速度。即使使用 Bulk API,您也需要了解索引的文档数量和批量请求的总体大小,以确保它不会影响集群性能。Elastic 建议对批量大小进行基准测试,一般经验法则是5-15 MB/批量请求。
增加索引缓冲区大小:您可以将未完成索引请求的内存限制增加到高于堆的默认值 10%。对于索引繁重的工作负载,这可能是建议的,但可能会影响其他内存密集型操作。
禁用复制:您可以将复制设置为零以加快索引速度,但如果 Elasticsearch 是您的工作负载的记录系统,则不建议这样做。
限制就地更新插入和数据变更:插入、更新和删除需要重新索引整个文档。如果您将 CDC 或事务数据传输到 Elasticsearch,您可能需要考虑存储较少的数据,因为这样需要重新索引的数据就较少。
简化数据结构:请记住,使用嵌套对象等数据结构会增加写入和索引。通过简化字段数量和数据模型的复杂性,可以加快索引速度。
当您的查询执行时间过长时,这可能意味着您需要简化数据模型或消除查询复杂性。以下是需要考虑的几个方面:
创建复合索引:将两个低基数字段的值合并在一起,以创建一个可以轻松搜索和检索的高基数字段。例如,如果邮政编码和月份是您通常用于查询过滤的两个字段,则可以将一个字段与邮政编码和月份合并。
启用文档的自定义路由:Elasticsearch 将查询广播到所有分片以返回结果。使用自定义路由,您可以确定数据驻留在哪个分片上,以加快查询执行速度。也就是说,在采用自定义路由时,您确实需要留意热点。
使用关键字字段类型进行结构化搜索:当您想要根据内容(例如 ID 或 zipcode)进行过滤时,建议使用关键字字段类型而不是整数类型或其他数字字段类型,以便更快地进行检索。
远离父子和嵌套对象:父子关系是解决 Elasticsearch 缺乏连接支持问题的好办法,有助于加快提取速度并限制重新索引。最终,组织会通过这种方法达到内存限制。当这种情况发生时,您可以通过执行数据非规范化来加快查询性能。
Elasticsearch 的许多扩展挑战都归结于分片和索引策略。对于您应该拥有多少个分片或分片应该有多大,没有一种万能的策略。确定策略的最佳方法是对统一的生产工作负载运行测试和基准测试。以下是一些需要考虑的其他建议:
使用 强制合并 API :使用强制合并 API 减少每个分片中的段数。段合并在后台自动进行,并删除任何已删除的文档。使用强制合并可以手动删除旧文档并提高性能。这可能会占用大量资源,因此不应在高峰使用期间发生。
注意负载不平衡:Elasticsearch 没有很好的方法来了解分片的资源利用率,并在确定分片位置时考虑到这一点。因此,可能会出现热分片。为了避免这种情况,您可能需要考虑让分片多于数据节点,让分片小于数据节点。
使用基于时间的索引:基于时间的索引可以根据保留减少集群中的索引和分片数量。Elasticsearch 还提供了滚动索引 API,以便您可以根据年龄或文档大小滚动到新索引以释放资源。
多租户最常见的策略是为每个客户或租户设置一个索引或使用自定义路由。以下是您可以如何权衡适合您的工作负载的策略:
按客户或租户设置索引:按客户配置单独的索引适用于用户群较小(数百到几千个客户)的公司,以及客户不共享数据的情况。如果每个客户都有自己的架构并且需要更大的灵活性,那么按客户设置索引也很有帮助。
自定义路由:自定义路由可让您指定文档所在的分片(例如客户 ID 或租户 ID),以便在索引文档时指定路由。当基于特定客户进行查询时,查询将直接转到包含客户数据的分片,以缩短响应时间。当您在客户之间拥有一致的架构并且拥有大量客户时,自定义路由是一种很好的方法,这在您提供免费增值模式时很常见。
Elasticsearch 专为日志分析和文本搜索用例而设计。许多使用 Elasticsearch 进行大规模实时分析的组织必须做出权衡以保持性能或成本效益,包括限制查询复杂性和数据提取延迟。当您开始限制使用模式、刷新间隔超出 SLA 或添加更多需要连接在一起的数据集时,寻找 Elasticsearch 的替代方案可能是明智之举。
Rockset 是替代方案之一,专为实时流数据提取和大规模低延迟查询而设计。了解如何从 Elasticsearch 迁移并探索这两个系统之间的架构差异。