为什么这个错误发生 #
not_master_exception 表示请求被发送到一个不是主节点的节点,但该操作需要主节点来处理。这通常发生在集群主节点变更期间。
这个错误可能由以下原因引起:
- 主节点故障:原主节点宕机或故障
- 主节点选举:集群正在进行主节点选举
- 节点角色错误:请求发送到了非主节点
- 网络分区:网络问题导致节点与主节点失联
- 主节点变更:主节点刚刚发生变更,集群状态尚未同步
- 候选主节点不足:没有足够的候选主节点形成法定人数
- 请求重定向:客户端缓存了过时的主节点信息
如何修复这个错误 #
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 个候选主节点
- 使用专用的主节点(不存储数据)
- 配置客户端自动发现主节点
- 监控主节点健康状态
- 确保网络稳定,避免分区
- 使用负载均衡器分发请求
- 实现客户端重试逻辑
- 定期检查集群法定人数状态
- 在维护期间正确下线节点





