是否需要使用ElasticSearch的负载均衡器?

时间:2014-07-15 06:13:30

标签: amazon-web-services elasticsearch amazon-ec2 lucene nosql

我在AWS EC2上运行了3个ElasticSearch节点的集群。这些节点使用OpsWorks / Chef进行设置。我的目的是将这个集群设计得非常有弹性和弹性(节点可以在需要时进出)。

从我读过的关于ElasticSearch的所有内容来看,似乎没有人建议在群集前放置负载均衡器;相反,似乎建议做两件事之一:

  1. 将客户端指向一个节点的URL / IP,让ES为您执行负载平衡,并希望该节点永远不会出现故障。

  2. 将所有节点的URL / IP硬编码到客户端应用程序中,让应用程序处理故障转移逻辑。

  3. 我的背景主要是在网络农场中,创建大量自治网络服务器,在他们面前抛出ELB并让负载均衡器决定哪些节点存活或死亡只是常识。为什么ES似乎不支持这种相同的架构?

4 个答案:

答案 0 :(得分:49)

我认为负载平衡Elasticsearch集群是一个好主意(设计一个容错系统,可以抵御单节点故障。)

要构建您的群集,您需要有关Elasticsearch的两个主要功能的背景知识:1。编写和更新文档以及2.查询文档。

在elasticsearch中编写/索引文档:

  1. 当新文档进入Elasticsearch进行索引时,Elasticsearch使用“碎片路由算法”确定应将文档分配给“主分片”
  2. 与分片关联的Lucene进程“映射”文档中的字段;
  3. Lucene进程将文档添加到分片的Lucene“倒排索引”
  4. 然后任何“复制碎片”都会收到该文件;副本分片“映射”文档并将文档添加到副本分片的Lucene“倒排索引”
  5. 在Elasticsearch中查询文档:

    1. 默认情况下,当查询发送到Elasticsearch时,查询会命中一个节点 - 这将成为该查询的“查询节点”或“网关查询节点”
    2. 节点将查询广播到索引中的每个分片(主要和副本)
    3. 每个分片对分片的本地Lucene倒排索引执行查询。
    4. 每个分片将前10 - 20个结果返回到“网关查询节点”
    5. “网关查询节点”然后对从其他分片返回的组合结果执行合并排序,
    6. 合并排序完成后,“网关查询节点”并将结果返回给客户端
      • 合并排序是CPU和内存资源重
    7. 为写入/索引/更新构建负载均衡器

      Elasticsearch自我管理节点上分片的位置。 “主节点”保持并更新“分片路由表”。 “主节点”将分片路由表的副本提供给集群中的其他节点。

      通常,您不希望主节点执行的操作远远超过群集的运行状况检查,更新路由表以及管理分片。

      最好将负载均衡器指向“数据节点”(数据节点是包含数据=分片的节点),并让数据节点使用其分片路由表来获取正确的分片。< / p>

      查询架构

      Elasticsearch创建了一个特殊的节点类型:“客户端节点”,其中包含“无数据”,不能成为“主节点”。客户端节点的功能是在查询结束时执行最终资源重合并排序。

      对于AWS,您可能使用c3或c4实例类型作为“客户端节点”

      最佳做法是将负载均衡器指向客户端节点的查询。

      干杯!

      <强>参考文献:

      1. Elasticsearch Node Types
      2. Elasticsearch: Shard Routing Algorithm
      3. Elasticsearch: Replica Shards
      4. Elasticsearch: Cluster State i.e. the Shard Routing Table
      5. ElasticHQ - Introduction to Elasticsearch Video
      6. Elasticsearch: Shard numbers and Cluster Scaling

答案 1 :(得分:17)

您不需要负载均衡器 - ES已经提供了该功能。你只是另一个组件,它可能行为不端,会增加不必要的网络跳跃。

ES会将您的数据分片(默认为5个分片),它会尝试在您的实例之间均匀分配。在你的情况下,2个实例应该有2个分片而1个只有一个,但你可能想要将分片更改为6以获得相同的分布。

默认情况下,复制设置为"number_of_replicas":1,因此每个分片都有一个副本。假设您使用6个分片,它可能看起来像这样(R是一个复制的分片):

  • node0:1,4,R3,R6
  • node1:2,6,R1,R5
  • node2:3,5,R2,R4

假设node1死亡,群集将更改为以下设置:

  • node0:1,4,6,R3 +新复制品R5,R2
  • node2:3,5,2,R4 +新复制品R1,R6

根据您的连接设置,您可以连接到一个实例(传输客户端),也可以加入群集(节点客户端)。使用节点客户端,您将避免双跳,因为您始终会连接到正确的分片/索引。使用传输客户端,您的请求将被路由到正确的实例。

所以没有什么可以为自己加载余额,你只是增加了开销。自动聚类可能是ES的最大优势。

答案 2 :(得分:11)

您想要设计“故障转移”是非常正确的,而在AWS中,我建议您这样做。

1)限制群集中可以选为主节点的节点。其余的,设置node.client:true。根据您对可用于故障转移的数量的主要可选节点数量进行选择。

2)创建一个仅包含主要可选节点的ELB。

3)在Route 53中,为您的群集创建一个CNAME,其值设置为ELB的DNS名称。

答案 3 :(得分:0)

当主节点发生故障时应该做些什么还不清楚。挖掘之后,有两个选项:

  1. 如果您正在使用客户端连接到Elasticsearch集群,则可以在连接配置中指定DNS名称数组。客户端将尝试按顺序解析DNS。如果第一个失败,将尝试第二个。
  2. 使用轮询DNS。类似于第一选项,但没有客户端。 这两个选项都可能导致延迟,因为DNS需要先失败才能路由到下一个可用别名。 DNS或客户端无法知道特定主机已关闭。
  3. 使用某种负载平衡器,这样LB就会提前知道主机的行为异常,并且不会造成任何延迟。