节点不会加入集群:NotMasterException(奇怪的主选举错误)
Nodes won't join cluster : NotMasterException (Weird master election bug)
我正在设置一个 elasticsearch (5.0.1) 集群。
它有三个符合主节点资格的节点:
el-m01
el-m02
el-m03
集群无法 assemble,并且每个主节点在日志中得到以下 NotMasterException
异常:
[2016-11-21T15:24:13,274][INFO ][o.e.d.z.ZenDiscovery ] [el-m01] failed to send join request to master [{el-m02}{bBhsu3fJSj-MyiWJGhQmog}{_IzdeUd4Sv6g-rhemGjEVQ}{192.168.110.118}{192.168.110.118:9300}{rack=r1}], reason [RemoteTransportException[[el-m02][192.168.110.118:9300][internal:discovery/zen/join]]; nested: NotMasterException[Node [{el-m02}{bBhsu3fJSj-MyiWJGhQmog}{_IzdeUd4Sv6g-rhemGjEVQ}{192.168.110.118}{192.168.110.118:9300}{rack=r1}] not master for join request]; ], tried [3] times
启用调试日志让我了解以下内容:
master 选举正在进行中,并且是成功的。然而,虽然每个节点都选择了一个 master,但没有节点认为他是 master。
即:
- el-m01认为el-m02是master
- el-m02认为el-m03是master
- el-m03认为el-m01是master
这里发生了什么?
情况是这样的:通过克隆一个 VM 来获得所有的主节点,每个节点都有 相同的节点 ID。
这可以通过以下命令验证,列出所有节点 ID:
GET /_cat/nodes?v&h=id,ip,name&full_id=true
请注意,由于您的集群尚未形成,因此需要单独查询每个节点,即:
curl 192.168.110.111:9200/_cat/nodes?v&h=id,ip,name&full_id=true
curl 192.168.110.112:9200/_cat/nodes?v&h=id,ip,name&full_id=true
(...)
这很糟糕。节点 ID 必须是唯一的。
要解决这种情况,您需要删除每个节点上的索引(/var/lib/elasticsearch
)。这将 删除 elasticsearch 中的所有数据,并且还会重置节点 ID。
要首先避免出现此问题,您可以:
- 一个。在克隆 VM
之后 安装 elasticsearch
- 乙。使用像 ansible 或 puppet 这样的自动化工具来管理 elasticsearch。
Elasticsearch 数据目录 $ES_HOME/data
,或者在 RPM 的情况下,例如 /var/lib/elasticsearch
包含 Elasticsearch 首次启动时随机生成的节点 ID。如果将此目录复制到多个期望形成集群的实例中,应该会收到以下错误:
failed to send join request to master [..] IllegalArgumentException [..] found existing node [..] with the same id but is a different node instance
然而,当 minimum_master_nodes
不满足时,会收到一个不太能说明问题的错误:
failed to send join request to master [..] NotMasterException [..] not master for join request
Github: https://github.com/elastic/elasticsearch/issues/32904
问题可以通过删除数据目录的内容来解决,首先不应复制数据目录。
我正在设置一个 elasticsearch (5.0.1) 集群。
它有三个符合主节点资格的节点:
el-m01
el-m02
el-m03
集群无法 assemble,并且每个主节点在日志中得到以下 NotMasterException
异常:
[2016-11-21T15:24:13,274][INFO ][o.e.d.z.ZenDiscovery ] [el-m01] failed to send join request to master [{el-m02}{bBhsu3fJSj-MyiWJGhQmog}{_IzdeUd4Sv6g-rhemGjEVQ}{192.168.110.118}{192.168.110.118:9300}{rack=r1}], reason [RemoteTransportException[[el-m02][192.168.110.118:9300][internal:discovery/zen/join]]; nested: NotMasterException[Node [{el-m02}{bBhsu3fJSj-MyiWJGhQmog}{_IzdeUd4Sv6g-rhemGjEVQ}{192.168.110.118}{192.168.110.118:9300}{rack=r1}] not master for join request]; ], tried [3] times
启用调试日志让我了解以下内容:
master 选举正在进行中,并且是成功的。然而,虽然每个节点都选择了一个 master,但没有节点认为他是 master。 即:
- el-m01认为el-m02是master
- el-m02认为el-m03是master
- el-m03认为el-m01是master
这里发生了什么?
情况是这样的:通过克隆一个 VM 来获得所有的主节点,每个节点都有 相同的节点 ID。
这可以通过以下命令验证,列出所有节点 ID:
GET /_cat/nodes?v&h=id,ip,name&full_id=true
请注意,由于您的集群尚未形成,因此需要单独查询每个节点,即:
curl 192.168.110.111:9200/_cat/nodes?v&h=id,ip,name&full_id=true
curl 192.168.110.112:9200/_cat/nodes?v&h=id,ip,name&full_id=true
(...)
这很糟糕。节点 ID 必须是唯一的。
要解决这种情况,您需要删除每个节点上的索引(/var/lib/elasticsearch
)。这将 删除 elasticsearch 中的所有数据,并且还会重置节点 ID。
要首先避免出现此问题,您可以:
- 一个。在克隆 VM 之后 安装 elasticsearch
- 乙。使用像 ansible 或 puppet 这样的自动化工具来管理 elasticsearch。
Elasticsearch 数据目录 $ES_HOME/data
,或者在 RPM 的情况下,例如 /var/lib/elasticsearch
包含 Elasticsearch 首次启动时随机生成的节点 ID。如果将此目录复制到多个期望形成集群的实例中,应该会收到以下错误:
failed to send join request to master [..] IllegalArgumentException [..] found existing node [..] with the same id but is a different node instance
然而,当 minimum_master_nodes
不满足时,会收到一个不太能说明问题的错误:
failed to send join request to master [..] NotMasterException [..] not master for join request
Github: https://github.com/elastic/elasticsearch/issues/32904
问题可以通过删除数据目录的内容来解决,首先不应复制数据目录。