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

use*_*100 48 lucene amazon-ec2 amazon-web-services nosql elasticsearch

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

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

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

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

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

Man*_*ego 50

我相信负载平衡Elasticsearch集群是一个好主意(设计容错系统,对单节点故障具有弹性.)

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

在elasticsearch中编写/索引文档:

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

在Elasticsearch中查询文档:

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

为写入/索引/更新构建负载均衡器

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

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

最好将负载均衡器指向"数据节点"(数据节点是包含数据=分片的节点)并让数据节点使用其分片路由表来获取对正确分片的写入.

构建查询

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

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

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

干杯!

参考文献:

  1. Elasticsearch节点类型
  2. Elasticsearch:分片路由算法
  3. Elasticsearch:Replica Shards
  4. Elasticsearch:群集状态,即分片路由表
  5. ElasticHQ - Elasticsearch Video简介
  6. Elasticsearch:分片数和群集缩放


xer*_*raa 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的最大优势.

  • 这不回答这个问题.这是关于ES如何在内部平衡数据的一个很好的文章,但是连接到ES集群的客户端应用程序仍然需要一种机制,以便在node1失败时切换到node2的IP.浮动IP或IP负载均衡器可以完成该工作,但它不包含在ES中. (14认同)
  • 谢谢你的回答.我想我更关心故障转移平衡.我知道ES会为我做负载平衡,但如果我连接的节点发生故障或停止服务怎么办?对于ELB(至少就Web服务器而言),它将平衡所有服务中节点的请求.ES集群是否有类似的模式? (4认同)
  • 这种方法的牺牲是,现在您的服务器拓扑上的客户端直接依赖.而且,不,你不是"添加另一个网络跃点".您只是改变了域名解析的方式.除非你在谈论甚至在客户端配置中使用IP地址,在这种情况下......是的. (2认同)

Gle*_*ith 12

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

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

2)创建仅包含主可选节点的ELB.

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