ElasticSearch 永远扩展

ElasticSearch Scale Forever

ElasticSearch 社区: 假设我有一位名为 Twitter 的客户,他今天雇用我来为一个 181 词的社交媒体网站构建他们的搜索功能。

假设我无法预测未来扩展所需的分片数量,并且存储大小已经达到数十 TB。

假设我不需要在索引后编辑任何文档。这完全是为了搜索。

参考上图,似乎有一些文档指向 'rolling indexes' ref1 ref2 ref3,据此我可以创建一个索引(ea.index named tweets1 -> N)on-the-飞。当一个索引填满时,我可以简单地添加一台具有新索引的新机器,并将其添加到相同的集群和别名以进行搜索。

这种架构在生产中是否站得住脚?

这个 'rolling index' 架构是否有任何长期影响,而不是在该估计范围内预测分片数量和扩展?

elasticsearch 中的分片只是一个lucene 索引。 elasticsearch 索引只是 lucene 索引(分片)的集合。鉴于此,对于您所处情况的容量规划,您只需要计算出您可以在一个索引中仅使用一个分片存储多少文档,并且仍然可以获得您想要的查询性能。

是底层的lucene索引耗尽了资源。根据您的文档在 lucene 索引中的索引方式,集群中的任何单个节点都可以处理有限数量的分片。您始终可以通过向集群添加更多节点来进行扩展。只需监控资源使用情况和查询响应时间即可了解何时添加更多节点。

创建名为 tweet_1tweet_2tweet_3 等的索引是完全合理的,向前滚动而不是担心重新分片数据。它最终完成了同样的事情。只需使用 index alias 来隐藏数字。

一旦计算出每个分片可以存储多少文档以获得查询性能,然后决定每个索引需要多少个分片,然后将这些数字相乘并将索引限制在您的文档数代码。一旦达到上限,您就可以转到新索引。这是我在代码中所做的以确定将文档发送到哪个索引(我有顺序 ID):

$index = 'file_' . (int)($fid / $docsPerIndex);

请注意,我正在使用 index templates,因此它可以自动创建一个新索引,而无需在达到上限时手动滚动。

另一个考虑因素是您将执行什么类型的查询。随着数据的增长,您有两种缩放选项。

  1. 您的集群中需要有足够的节点来并行化查询,以便它可以轻松搜索所有索引并仍然快速响应。

  1. 您需要为您的索引命名,这样您就知道要查询哪些索引并且只需要查询集群中索引的一个子集。

请记住,如果您有顺序的或可预测的 ID,则 Elasticsearch 可以有效地执行基于 ID 的查询,而无需实际查询整个集群。如果您让 ES 自动分配 ID(假设您使用的是 ES >=1.4.0),它将使用可预测的 ID(flake ids)。这也加快了索引编制。随机 ID 会造成最坏的情况。

如果您的查询是基于时间的,那么它将必须在该方案下为每个查询搜索整个索引集。对于基于时间的查询,您希望根据一定时间滚动索引(例如每天或每月,具体取决于您在该时间范围内收到的数据量)并将它们命名为 tweets_2015_01tweets_2015_02, 等。通过这样做,您可以根据请求的搜索时间范围缩小在查询时必须搜索的索引集。