[译]如何防止elasticsearch的脑裂问题
我们都去过那里-我们开始计划一个Elasticsearch集群,随后出现的第一个问题是“集群应具有多少个节点?”。如您所知,这个问题的答案取决于很多因素,例如预期的负载,数据大小,硬件等。在本博客中,我不会详细介绍如何调整您的大小集群,而是讨论同样重要的事情-如何避免裂脑问题。
什么是裂脑?
让我们以一个带有两个节点的enlasticsearch集群的简单情况为例。集群包含一个带有一个分片和一个副本的索引。节点1在群集启动时被选为主节点,并拥有主分片(在以下架构中标记为0P),而节点2则拥有副本分片(0R)。
现在,如果由于任何原因两个节点之间的通信失败,将会发生什么?发生这种情况的原因可能是网络故障,也可能只是因为其中一个节点没有响应(例如,在世界停止垃圾回收的情况下)。
两个节点都认为另一个已失败。节点1不会执行任何操作,因为它已被选为主节点。但是节点2会自动将自己选举为主节点,因为它认为它是群集的一部分,而该群集不再具有主节点。在Elasticsearch集群中,主节点负责在节点之间平均分配分片。节点2拥有一个副本分片,但它认为主分片不再可用。因此,它将自动将副本分片提升为主数据库。
我们的集群现在处于不一致状态。为将要命中节点1的索引请求编制索引将在其主分片副本中索引数据,而发送至节点2的请求将填充该分片的第二份副本。在这种情况下,碎片的两个副本已经分开,并且如果没有完全重新索引的话,将很难(如果不是不可能)重新对齐它们。更糟糕的是,对于不了解群集的索引客户端(例如使用REST接口的客户端),此问题将完全透明-每次调用索引节点时,索引请求都将成功完成。搜索数据时,该问题仅会稍微引起注意:根据搜索请求命中的节点,结果将有所不同。
如何避免裂脑问题
elasticsearch配置具有出色的默认值。但是,elasticsearch团队无法事先知道您的特定情况的所有详细信息。因此,应更改某些配置参数以适合您的特定需求。可以在elasticsearch安装的config文件夹中的elasticsearch.yml文件中更改本文中提到的所有参数。
为了避免出现脑裂情况,我们可以查看的第一个参数是Discovery.zen.minimum_master_nodes。此参数确定要选举一个主机需要通信的节点数。默认值为1。经验法则是应将其设置为N / 2 + 1,其中N是群集中节点的数量。例如,在3节点群集的情况下,minimum_master_nodes应该设置为3/2 + 1 = 2(向下舍入为最接近的整数)。
让我们想象一下,如果我们将Discovery.zen.minimum_master_nodes设置为2(2/2 + 1),在上述情况下会发生什么。当两个节点之间的通信丢失时,节点1将失去其主控状态,而节点2将永远不会被选举为主节点。没有一个节点会接受索引或搜索请求,这使所有客户端的问题立即显而易见。此外,所有分片都不会处于不一致状态。
您可以调整的另一个参数是Discovery.zen.ping.timeout。默认值为3秒,它确定节点在假定节点发生故障之前将等待集群中其他节点响应的时间。在网络速度较慢的情况下,稍微增加默认值绝对是个好主意。此参数不仅可以满足更高的网络延迟,而且在节点由于过载而响应较慢的情况下也很有用。
两节点集群?
如果您认为在两节点集群的情况下将minimum_master_nodes参数设置为2是错误的(或至少是不直观的),则可能是正确的。在这种情况下,节点发生故障时,整个群集都会发生故障。尽管这消除了出现裂脑的可能性,但它也否定了弹性搜索的主要功能之一-通过使用副本分片内置的高可用性机制。
如果您刚开始使用Elasticsearch,建议您计划一个3节点集群。这样,您可以将minimum_master_nodes设置为2,从而限制了发生裂脑问题的机会,但仍保持了高可用性优势:如果配置了副本,则可以承受丢失节点但仍保持集群正常运行的风险。
但是,如果您已经在运行两个节点的Elasticsearch集群怎么办?您可以选择保留裂脑,同时保持高可用性,或者选择避免裂脑而失去高可用性。为了避免妥协,这种情况下最好的选择是将节点添加到群集。这听起来很激烈,但不一定如此。对于每个elasticsearch节点,您可以通过设置node.data参数来选择该节点是否保留数据。默认值为“ true”,这意味着默认情况下,每个elasticsearch节点也将是一个数据节点。
对于两节点群集,您可以向其添加一个新节点,该节点的node.data参数设置为“ false”。这意味着该节点将永远不会容纳任何分片,但可以将其选为主节点(默认行为)。由于新节点是一个无数据节点,因此可以在较便宜的硬件上启动它。现在您有了一个由三个节点组成的集群,可以安全地将minimum_master_nodes设置为2,避免出现裂脑现象,并且仍然可以在不丢失数据的情况下丢失节点。
结论
裂脑问题显然很难永久解决。在Elasticsearch的问题跟踪器中,仍然存在一个未解决的问题,描述了一个极端情况,即使使用了minimum_master_nodes参数的正确值,仍然会发生裂脑。elasticsearch小组目前正在努力更好地实现主选举算法,但是如果您已经在运行Elasticsearch集群,那么一定要意识到这一潜在问题。
尽快识别它也很重要。一种检测出问题的简单方法是为每个节点安排对/ _nodes端点响应的检查。该端点返回集群中所有节点的简短状态报告。如果两个节点报告的群集组成不同,则表明发生裂脑情况是一个明显的迹象。