📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

为什么这个错误发生 #

not_master_exception 表示请求被发送到一个不是主节点的节点,但该操作需要主节点来处理。这通常发生在集群主节点变更期间。

这个错误可能由以下原因引起:

  1. 主节点故障:原主节点宕机或故障
  2. 主节点选举:集群正在进行主节点选举
  3. 节点角色错误:请求发送到了非主节点
  4. 网络分区:网络问题导致节点与主节点失联
  5. 主节点变更:主节点刚刚发生变更,集群状态尚未同步
  6. 候选主节点不足:没有足够的候选主节点形成法定人数
  7. 请求重定向:客户端缓存了过时的主节点信息

如何修复这个错误 #

1. 检查当前主节点 #

# 查看当前主节点
GET /_cat/master?v

# 获取主节点详细信息
GET /_cluster/state?filter_path=master_node

2. 等待主节点选举完成 #

# 等待主节点选举完成
GET /_cluster/health?wait_for_active_shards=0&timeout=50s

# 查看集群状态
GET /_cluster/health

3. 检查节点角色 #

# 查看所有节点及其角色
GET /_cat/nodes?v&h=name,master

# 查看节点配置
GET /_nodes/<node_name>/settings?filter_path=*.master

4. 确保有足够的候选主节点 #

# 检查候选主节点数量
GET /_cat/nodes?v&h=name,master,data

# 至少需要 3 个候选主节点以避免脑裂

5. 重试请求 #

# 客户端可以实现重试逻辑
# 等待短暂时间后重试
sleep(5)
# 然后重新发送请求

6. 使用正确的端点 #

# 确保请求发送到正确的节点
# 某些操作必须由主节点处理
PUT /_cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.enable": "all"
  }
}

7. 检查网络连接 #

# 测试节点间的网络连接
ping <master_node_ip>
telnet <master_node_ip> 9300

# 检查防火墙规则

8. 检查法定人数配置 #

# 查看集群配置
GET /_cluster/settings?flat_settings=true

# 对于较旧版本,检查 minimum_master_nodes
# 新版本使用投票配置自动处理

9. 处理分裂脑 #

如果发生脑裂:

# 检查集群状态
GET /_cluster/state?filter_path=**.master_node

# 重启受影响的节点以恢复集群

10. 客户端配置 #

# 配置客户端使用嗅探功能自动发现主节点
# 例如在 Java 客户端中
RestClient client = RestClient.builder(
    new HttpHost("node1", 9200),
    new HttpHost("node2", 9200),
    new HttpHost("node3", 9200)
).build();

11. 检查节点日志 #

# 查看主节点相关日志
grep -i "master" /path/to/easysearch/logs/easysearch.log | tail -50

# 查看选举相关日志
grep -i "election" /path/to/easysearch/logs/easysearch.log | tail -50

12. 手动触发选举(谨慎使用) #

# 如果主节点无法恢复,可以重启候选主节点
# 触发新的选举

# 但要确保避免脑裂,一次只操作一个节点

预防措施 #

  • 配置至少 3 个候选主节点
  • 使用专用的主节点(不存储数据)
  • 配置客户端自动发现主节点
  • 监控主节点健康状态
  • 确保网络稳定,避免分区
  • 使用负载均衡器分发请求
  • 实现客户端重试逻辑
  • 定期检查集群法定人数状态
  • 在维护期间正确下线节点