外观
Neo4j 手动故障转移
手动故障转移前提条件
集群架构要求
核心节点数量:
- 最少3个核心节点,推荐奇数个节点
- 确保集群能够形成多数派
集群健康状态:
- 大多数核心节点处于健康状态
- 集群通信正常
- 数据同步状态良好
备份状态:
- 最近有成功的备份
- 确保数据安全性
监控和准备工作
监控工具:
- 确保监控系统正常运行
- 配置关键指标告警
- 实时监控集群状态
准备工作:
- 确认当前主节点和其他节点状态
- 检查数据同步情况
- 准备故障转移命令和脚本
- 通知相关团队和人员
回滚计划:
- 制定详细的回滚计划
- 准备回滚命令和脚本
- 确保能够快速恢复到原始状态
工具和权限要求
访问权限:
- 集群节点的 SSH 访问权限
- Neo4j 管理员权限
- 操作系统管理员权限
工具准备:
- Neo4j 命令行工具(neo4j-admin, cypher-shell)
- 集群监控工具
- SSH 客户端
- 日志查看工具
手动故障转移操作步骤
1. 故障检测和确认
检查集群状态
cypher
// 查看集群状态
CALL dbms.cluster.overview()
YIELD address, role, databases
RETURN address, role, databases
ORDER BY role;bash
# 使用 neo4j-admin 查看集群状态
neo4j-admin cluster status确认主节点故障
bash
# 检查主节点状态
ssh <master-node> "systemctl status neo4j"
# 检查主节点日志
ssh <master-node> "tail -n 100 /opt/neo4j/logs/neo4j.log"
# 检查网络连接
ping <master-node>
telnet <master-node> 76872. 选择新的主节点
评估候选节点
cypher
// 评估节点状态
CALL dbms.cluster.overview()
YIELD address, role, databases
WITH address, role, databases
UNWIND databases AS db
RETURN address, db.name AS database, db.status AS status, db.defaultAccessMode AS accessMode
ORDER BY address;选择标准
- 节点状态正常
- 数据同步状态良好
- 硬件资源充足
- 网络连接稳定
- 地理位置合理(如果是跨数据中心部署)
3. 执行故障转移操作
方法一:使用 cypher-shell 手动触发选举
cypher
// 查看当前主节点
CALL dbms.cluster.overview()
YIELD address, role
WHERE role = 'LEADER'
RETURN address AS current_leader;
// 手动触发选举(从任意核心节点执行)
CALL dbms.cluster.rotateLeader();方法二:使用 neo4j-admin 命令
bash
# 手动切换主节点
neo4j-admin cluster promote --database=neo4j --to=<new-leader-address>方法三:通过配置文件调整
bash
# 在候选主节点上调整配置
ssh <candidate-node> "echo 'causal_clustering.leader_election_timeout=5s' >> /opt/neo4j/conf/neo4j.conf"
# 重启候选节点
ssh <candidate-node> "systemctl restart neo4j"4. 验证故障转移结果
检查新主节点状态
cypher
// 查看新的主节点
CALL dbms.cluster.overview()
YIELD address, role
WHERE role = 'LEADER'
RETURN address AS new_leader;
// 检查数据库状态
CALL dbms.databases()
YIELD name, status, defaultAccessMode
RETURN name, status, defaultAccessMode;验证数据一致性
bash
# 检查数据一致性
neo4j-admin debug consistency --database=neo4j
# 验证数据完整性
cypher-shell -u neo4j -p <password> -c "MATCH (n) RETURN count(n) AS node_count;"
cypher-shell -u neo4j -p <password> -c "MATCH ()-[r]->() RETURN count(r) AS relationship_count;"测试读写操作
cypher
// 测试写操作
CREATE (t:Test {name: 'failover-test', timestamp: datetime()});
// 测试读操作
MATCH (t:Test) WHERE t.name = 'failover-test' RETURN t;
// 清理测试数据
MATCH (t:Test) WHERE t.name = 'failover-test' DELETE t;5. 恢复故障节点
修复故障节点
bash
# 登录故障节点
ssh <failed-node>
# 检查故障原因
journalctl -xe | grep -i neo4j
tail -n 200 /opt/neo4j/logs/neo4j.log
# 修复故障
# 例如,修复硬件问题、网络问题或配置问题
# 重启节点
neo4j restart重新加入集群
cypher
// 检查节点是否重新加入集群
CALL dbms.cluster.overview()
YIELD address, role
RETURN address, role;
// 检查数据同步状态
CALL dbms.cluster.overview()
YIELD address, databases
UNWIND databases AS db
RETURN address, db.name AS database, db.status AS status;不同场景下的手动故障转移
主节点故障场景
场景描述
- 主节点突然宕机
- 无法通过网络访问
- 自动故障转移未触发或失败
处理步骤
确认主节点故障:
bash# 多次尝试连接主节点 for i in {1..5}; do ssh <master-node> "echo 'test'" || echo "Connection failed $i"; sleep 1; done检查集群状态:
cypherCALL dbms.cluster.overview() YIELD address, role RETURN address, role;执行手动故障转移:
cypherCALL dbms.cluster.rotateLeader();验证新主节点:
cypherCALL dbms.cluster.overview() YIELD address, role WHERE role = 'LEADER' RETURN address;恢复故障节点:
- 修复故障原因
- 重启节点
- 验证节点重新加入集群
网络分区场景
场景描述
- 集群发生网络分区
- 形成多个子集群
- 出现分裂脑风险
处理步骤
检测网络分区:
bash# 检查节点间通信 for node in <node1> <node2> <node3>; do echo "Checking connectivity to $node:" ping -c 3 $node done确定分区情况:
cypherCALL dbms.cluster.overview() YIELD address, role RETURN address, role;选择主要分区:
- 选择包含大多数核心节点的分区
- 确保数据完整性
隔离次要分区:
bash# 停止次要分区的节点 for node in <secondary-partition-nodes>; do ssh $node "neo4j stop" done在主要分区执行故障转移:
cypherCALL dbms.cluster.rotateLeader();修复网络问题:
- 修复网络故障
- 逐步恢复次要分区节点
- 验证集群完整性
计划内维护场景
场景描述
- 主节点计划内维护
- 需要将主节点切换到其他节点
- 确保业务连续性
处理步骤
提前通知:
- 通知相关团队和用户
- 选择合适的维护窗口
准备工作:
- 备份数据库
- 检查集群状态
- 准备故障转移命令
执行故障转移:
cypherCALL dbms.cluster.rotateLeader();验证新主节点:
cypherCALL dbms.cluster.overview() YIELD address, role WHERE role = 'LEADER' RETURN address;执行维护操作:
- 在原主节点上执行维护
- 升级硬件、软件或配置
恢复原主节点:
- 重启原主节点
- 验证节点重新加入集群
- 可选:将主节点切换回原节点
故障转移后处理
数据一致性检查
检查数据完整性
bash
# 使用 neo4j-admin 检查数据一致性
neo4j-admin debug consistency --database=neo4j
# 检查事务日志
neo4j-admin tx-log info --database=neo4j验证业务数据
cypher
// 验证关键业务数据
MATCH (u:User {id: 1}) RETURN u;
MATCH (p:Product {id: 100}) RETURN p;
MATCH (o:Order {id: 1000}) RETURN o;
// 验证关系完整性
MATCH (u:User {id: 1})-[:OWNS]->(p:Product) RETURN u, p;监控调整
更新监控配置
bash
# 更新监控系统中的主节点信息
# 示例:Prometheus 配置更新
sed -i 's/<old-master-ip>/<new-master-ip>/g' /etc/prometheus/prometheus.yml
# 重启监控服务
systemctl restart prometheus调整告警规则
yaml
# 更新告警规则,确保监控新的主节点
groups:
- name: neo4j-alerts
rules:
- alert: Neo4jHighCpuUsage
expr: system_cpu_usage{instance="<new-master-ip>:9100"} > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Neo4j high CPU usage on {{ $labels.instance }}"
description: "CPU usage is above 80% for 5 minutes"文档更新
更新集群文档
- 更新集群拓扑图
- 更新主节点信息
- 记录故障转移事件
- 更新维护计划
更新操作手册
- 更新故障转移步骤
- 更新回滚计划
- 添加经验教训
- 更新联系方式
手动故障转移最佳实践
1. 定期演练
制定演练计划
- 定期进行故障转移演练
- 模拟不同故障场景
- 记录演练过程和结果
- 优化故障转移流程
演练步骤
准备工作:
- 通知相关团队
- 准备演练脚本和工具
- 确保监控系统正常运行
执行演练:
- 模拟主节点故障
- 执行手动故障转移
- 验证故障转移结果
- 恢复故障节点
评估和优化:
- 分析演练结果
- 识别问题和瓶颈
- 优化故障转移流程
- 更新文档和计划
2. 监控和告警
关键监控指标
- 集群状态:节点状态、角色分布
- 数据同步:复制延迟、事务日志应用速率
- 资源使用:CPU、内存、磁盘 I/O
- 网络状态:节点间通信延迟、丢包率
告警配置
yaml
# 示例:Prometheus 告警规则
- alert: Neo4jLeaderFailure
expr: neo4j_cluster_role{role="LEADER"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Neo4j Leader Failure"
description: "No leader found in the cluster for 1 minute"
- alert: Neo4jReplicationLag
expr: neo4j_cluster_replication_lag > 1000
for: 5m
labels:
severity: warning
annotations:
summary: "Neo4j High Replication Lag"
description: "Replication lag is above 1000ms for 5 minutes"3. 恢复计划
制定详细的恢复计划
- 故障检测和确认流程
- 故障转移操作步骤
- 数据验证方法
- 节点恢复流程
- 回滚计划
恢复工具和脚本
bash
#!/bin/bash
# manual-failover.sh - 手动故障转移脚本
# 配置
NEO4J_USER="neo4j"
NEO4J_PASSWORD="password"
CLUSTER_NODES="node1 node2 node3"
# 检查集群状态
check_cluster_status() {
echo "Checking cluster status..."
for node in $CLUSTER_NODES; do
echo "Node: $node"
cypher-shell -a neo4j://$node:7687 -u $NEO4J_USER -p $NEO4J_PASSWORD "CALL dbms.cluster.overview() YIELD address, role RETURN address, role;"
echo ""
done
}
# 执行故障转移
execute_failover() {
echo "Executing manual failover..."
cypher-shell -a neo4j://$1:7687 -u $NEO4J_USER -p $NEO4J_PASSWORD "CALL dbms.cluster.rotateLeader();"
}
# 验证故障转移结果
verify_failover() {
echo "Verifying failover result..."
cypher-shell -a neo4j://$1:7687 -u $NEO4J_USER -p $NEO4J_PASSWORD "CALL dbms.cluster.overview() YIELD address, role WHERE role = 'LEADER' RETURN address AS new_leader;"
}
# 主流程
echo "Starting manual failover process..."
check_cluster_status
echo "Enter the node to execute failover:"
read EXECUTE_NODE
execute_failover $EXECUTE_NODE
verify_failover $EXECUTE_NODE
echo "Manual failover process completed."4. 团队协作
明确角色和职责
- DBA 团队:负责执行故障转移操作
- 监控团队:负责故障检测和告警
- 开发团队:负责验证业务功能
- 运维团队:负责硬件和网络支持
建立沟通机制
- 建立故障转移沟通频道
- 明确通知流程
- 制定决策流程
- 建立 escalation 机制
常见问题和解决方案
问题 1:手动故障转移失败
症状
- 执行故障转移命令后没有反应
- 集群仍然没有主节点
- 出现错误信息
解决方案
检查集群状态:
cypherCALL dbms.cluster.overview() YIELD address, role, databases RETURN address, role, databases;检查节点状态:
bashfor node in <node1> <node2> <node3>; do ssh $node "neo4j status" done检查日志信息:
bashtail -n 200 /opt/neo4j/logs/neo4j.log | grep -i error尝试其他方法:
- 重启所有核心节点
- 检查网络连接
- 验证集群配置
问题 2:数据不一致
症状
- 故障转移后数据不完整
- 查询结果不一致
- 出现数据丢失
解决方案
检查数据一致性:
bashneo4j-admin debug consistency --database=neo4j从备份恢复:
bashneo4j-admin restore --from=/backup/neo4j --database=neo4j --force重新同步数据:
bash# 删除旧数据 rm -rf /var/lib/neo4j/data/databases/neo4j rm -rf /var/lib/neo4j/data/transactions/neo4j # 重启节点,自动从其他节点同步数据 neo4j restart
问题 3:节点无法重新加入集群
症状
- 修复后的节点无法加入集群
- 日志中出现连接错误
- 节点状态异常
解决方案
检查网络连接:
bashping <other-node> telnet <other-node> 5000检查集群配置:
bashgrep -A 10 "dbms.cluster" /opt/neo4j/conf/neo4j.conf清理旧数据:
bash# 清理集群状态数据 rm -rf /var/lib/neo4j/data/cluster/ # 重启节点 neo4j restart手动添加节点:
cypher// 从其他节点执行 CALL dbms.cluster.addNode('new-node:5000');
问题 4:分裂脑问题
症状
- 集群出现多个主节点
- 数据出现分歧
- 集群状态混乱
解决方案
立即隔离节点:
bash# 停止多余的主节点 for node in <node1> <node2>; do ssh $node "neo4j stop" done选择权威节点:
- 选择数据最新、状态最健康的节点作为权威节点
- 以该节点的数据为准
重建集群:
- 从权威节点恢复其他节点
- 确保集群形成单一主节点
- 验证数据一致性
预防措施:
- 确保集群节点数量为奇数
- 配置合理的选举超时时间
- 加强网络监控
- 定期进行集群健康检查
常见问题(FAQ)
Q1: 什么时候需要执行手动故障转移?
A1: 手动故障转移适用于以下场景:
- 计划内维护(硬件升级、软件更新、配置调整)
- 自动故障转移失败
- 集群处于分裂脑状态
- 需要在特定时间窗口进行故障转移
- 需要将主节点切换到特定健康节点
- 需要验证故障转移流程
Q2: 手动故障转移前需要做哪些准备工作?
A2: 手动故障转移前的准备工作包括:
- 确保监控系统正常运行
- 备份数据库
- 检查集群状态,确保多数核心节点健康
- 准备故障转移命令和脚本
- 制定回滚计划
- 通知相关团队和用户
Q3: 如何选择新的主节点?
A3: 选择新主节点时应考虑以下因素:
- 节点状态正常
- 数据同步状态良好
- 硬件资源充足
- 网络连接稳定
- 地理位置合理(跨数据中心部署时)
Q4: 手动故障转移有哪些风险?
A4: 手动故障转移的主要风险包括:
- 数据不一致
- 集群分裂脑
- 业务中断
- 节点无法重新加入集群
为降低这些风险,应严格遵循故障转移流程,做好准备工作,并在故障转移后验证结果。
Q5: 如何验证手动故障转移的结果?
A5: 手动故障转移后的验证工作包括:
- 检查新主节点状态
- 验证数据一致性
- 测试读写操作
- 检查集群完整性
- 验证业务功能正常
Q6: 如何处理手动故障转移失败?
A6: 手动故障转移失败时的处理方法:
- 检查集群状态和节点状态
- 查看日志信息,分析失败原因
- 尝试其他故障转移方法
- 重启核心节点
- 检查网络连接
- 验证集群配置
Q7: 如何预防分裂脑问题?
A7: 预防分裂脑问题的措施包括:
- 确保集群节点数量为奇数
- 配置合理的选举超时时间
- 加强网络监控,及时发现网络分区
- 定期进行集群健康检查
- 实施自动故障转移监控
Q8: 如何提高手动故障转移的成功率?
A8: 提高手动故障转移成功率的方法:
- 定期进行故障转移演练
- 制定详细的故障转移计划和脚本
- 确保团队成员熟悉故障转移流程
- 加强监控和告警
- 做好备份和回滚准备
- 保持集群处于健康状态
Q9: 计划内维护时如何执行手动故障转移?
A9: 计划内维护时的手动故障转移步骤:
- 提前通知相关团队和用户
- 选择合适的维护窗口
- 备份数据库
- 检查集群状态
- 执行故障转移操作
- 验证转移结果
- 在原主节点上执行维护操作
- 恢复原主节点并重新加入集群
- 可选:将主节点切换回原节点
Q10: 如何处理故障转移后的数据一致性问题?
A10: 处理数据一致性问题的方法:
- 使用 neo4j-admin debug consistency 检查数据一致性
- 从备份恢复有问题的节点
- 重新同步数据(删除旧数据,让节点从其他节点重新同步)
- 必要时重建集群,以健康节点的数据为准
