作者:来自 Elastic Piotr Przybyl
掌握 Elasticsearch 分片和副本的概念并学习如何优化它们。
更多阅读:Elasticsearch 中的一些重要概念: cluster, node, index, document, shards 及 replica
节点、集群和分片 - Elasticsearch 101 课程
想获得 Elastic 认证吗?了解下一次 Elasticsearch 工程师培训的时间!
Elasticsearch 拥有大量新功能,可帮助你为自己的用例构建最佳搜索解决方案。深入查看我们的示例笔记本以了解更多信息,开始免费的云试用,或立即在本地计算机上尝试 Elastic。
Elasticsearch 通过在 Lucene 之上构建分布式系统来增强 Lucene 的功能,从而解决可扩展性和容错问题。它还提供基于 JSON 的 REST API,使与其他系统的互操作变得非常简单。
像 Elasticsearch 这样的分布式系统可能非常复杂,有许多因素会影响其性能和稳定性。分片(shards)是 Elasticsearch 中最基本的概念之一,了解它们的工作原理将使你能够有效地管理 Elasticsearch 集群。
本文解释了什么是主分片和副本分片,它们对 Elasticsearch 集群的影响,以及有哪些工具可以根据不同需求进行调整。
理解分片
Elasticsearch 索引中的数据可能会增长到非常庞大的规模。为了便于管理,每一部分数据都会保存在索引中,而索引会被拆分为多个分片。每个 Elasticsearch 分片都是一个 Apache Lucene 索引,每个独立的 Lucene 索引包含 Elasticsearch 索引中文档的一个子集。以这种方式拆分索引可以控制资源使用。一个 Apache Lucene 索引的文档上限是 2,147,483,519(2³¹ - 129)个文档。
有时,索引需要在节点之间迁移以实现重新平衡。由于这个过程可能耗时且消耗资源,因此索引不应变得过大,这有助于将恢复时间保持在可接受范围内。此外,由于索引由 Lucene 段组成,这些段需要不断合并,因此段不能太大。基于这些原因,Elasticsearch 将索引数据拆分为更小、更易管理的块,称为主分片(primary shards),可以更容易地分布在多台机器上。副本分片(Replica)只是对应主分片的精确副本,我们将在后文介绍它们的作用。
拥有合适数量的分片对性能很重要,因此最好提前规划。当查询在不同分片上并行运行时,如果每个分片位于不同节点且集群中有足够的节点,执行速度会比单分片索引快。但同时,分片会消耗内存和磁盘空间,包括索引数据和集群元数据。分片过多(也称为 oversharding)会减慢查询、索引请求和管理操作,因此保持适当的平衡至关重要。
主分片数量是在创建该索引实例时定义的。如果以后需要不同数量的主分片,可以使用 resize API —— split(更多主分片)、shrink(更少主分片)或 clone(主分片数量相同但副本设置不同)。这些操作会复制 Lucene 段,避免对所有文档进行完整的重新索引。在创建索引时,你可以将主分片和副本分片的数量设置为索引的配置。
PUT /sensor
{
"settings" : {
"index" : {
"number_of_shards" : 6,
"number_of_replicas" : 2
}
}
}
(如果你没有指定分片或副本的数量,从 Elasticsearch 7.0 起,两者的默认值都是 1)。理想的分片数量应根据索引中的数据量来确定。通常,一个最佳分片应包含 10-50GB 的数据,每个分片的文档数少于 2 亿个。例如,如果你预计每天会积累大约 300GB 的应用日志,那么该索引有大约 10 个分片是合理的,前提是你有足够的节点来存放它们。
在生命周期中,分片可能会经历多种状态,包括:
-
Initializing:分片在可用之前的初始状态。
-
Started:分片处于活跃状态,可以接收请求。
-
Relocating:分片正在迁移到其他节点时的状态。在某些情况下可能需要这样做,例如分片所在节点磁盘空间不足。
-
Unassigned:分片未能被分配时的状态。出现这种情况时会给出原因,例如承载分片的节点不再在集群中(
NODE_LEFT
)或由于恢复到一个已关闭的索引(EXISTING_INDEX_RESTORED
)。
要查看所有分片、它们的状态及其他元数据,可以使用以下请求:
GET _cat/shards
要查看特定索引的分片,可以将索引名称附加到 URL,例如 sensor:
GET _cat/shards/sensor
此命令会生成如下示例的输出。默认情况下,显示的列包括索引名称、分片名称(即编号)、它是主分片还是副本、其状态、文档数量、磁盘占用大小,以及分片所在节点的 IP 地址和节点 ID。
sensor 5 p STARTED 0 283b 127.0.0.1 ziap
sensor 5 r UNASSIGNED
sensor 2 p STARTED 1 3.7kb 127.0.0.1 ziap
sensor 2 r UNASSIGNED
sensor 3 p STARTED 3 7.2kb 127.0.0.1 ziap
sensor 3 r UNASSIGNED
sensor 1 p STARTED 1 3.7kb 127.0.0.1 ziap
sensor 1 r UNASSIGNED
sensor 4 p STARTED 2 3.8kb 127.0.0.1 ziap
sensor 4 r UNASSIGNED
sensor 0 p STARTED 0 283b 127.0.0.1 ziap
sensor 0 r UNASSIGNED
理解副本
虽然每个分片只包含一份数据,但一个索引可以包含该分片的多个副本。因此,分片有两种类型:主分片(primary shard)和副本分片(replica)。每个主分片的副本始终位于不同的节点上,这可确保在节点故障时数据的高可用性。除了冗余和防止数据丢失及停机的作用外,副本还可以通过与主分片并行处理查询来提升搜索性能,从而提高查询速度。
主分片和副本分片在行为上有一些重要区别。虽然它们都能处理查询,但索引请求(即向索引添加数据)必须先经过主分片,然后才能复制到副本分片。如上所述,如果主分片不可用,例如由于节点断开连接或硬件故障,副本将被提升以接管其角色。
虽然副本在节点故障时很有用,但副本过多会消耗内存、磁盘空间和索引时的计算资源。另一个区别是,主分片数量在索引创建后无法更改,而副本数量可以随时通过更新索引设置动态调整。
副本的另一个考虑因素是可用节点的数量。副本总是放在与主分片不同的节点上,因为相同数据的两份副本放在同一个节点上,在该节点故障时无法提供任何保护。因此,要支持 n 个副本,集群中至少需要 n + 1 个节点。例如,如果集群中有两个节点,而索引配置了 6 个副本,那么只会分配 1 个副本。另一方面,一个有 7 个节点的系统完全可以支持 1 个主分片和 6 个副本。
优化分片和副本
即使创建了主分片和副本分片比例合理的索引,也需要对它们进行监控,因为索引的情况会随时间变化。例如,在处理时间序列数据时,包含最新数据的索引通常比旧索引更活跃。如果不调整这些索引,它们将消耗相同的资源,尽管它们的需求差异很大。
可以使用 rollover 索引 API 来分离新旧索引。该 API 可以设置为在达到某个阈值(索引在磁盘上的大小、文档数量或存续时间)时自动创建新索引。这一 API 也有助于控制分片大小。由于索引创建后分片数量无法轻易更改,如果不满足 rollover 条件,分片将持续累积数据。对于只需不频繁访问的旧索引,可以通过缩小和强制合并两种方式来减少其内存和磁盘占用。前者减少索引中的分片数量,后者减少 Lucene 段的数量并释放被已删除文档占用的空间。
主分片和副本分片是 Elasticsearch 的基础
Elasticsearch 作为一个面向海量数据的分布式存储、搜索和分析平台,已经建立了良好的声誉。然而,在如此规模下运行时,必然会遇到各种挑战。这就是为什么理解主分片和副本分片的工作原理对 Elasticsearch 来说如此重要且基础,因为这有助于优化平台的可靠性和性能。
了解它们的工作方式以及如何优化它们,对于构建更强健、更高性能的 Elasticsearch 集群至关重要。如果你经常遇到查询响应缓慢或频繁宕机的问题,这些知识可能正是克服这些障碍的关键。
请参考 Elasticsearch 官方文档,了解更多关于集群、节点和分片、如何设置分片大小、分片分配及恢复等内容。
这一主题也可以在 Elastic 社区 YouTube 频道上的入门课程中找到。
最后但同样重要的是:如果你不想操心节点、分片或副本,可以试用 Elastic Cloud Serverless。这是 Elastic Cloud 提供的一项服务,由 Elastic 全面托管,并自动根据你的工作负载进行扩展。你可以通过免费试用来熟悉无服务器(serverless)方法的其他优势。