Elasticsearch 自动副本修复系统(Auto Replica Recovery System) 设计方案

在生产级 Elasticsearch 集群中,副本异常(如 UNASSIGNED、INITIALIZING 长时间未完成) 是常见问题,若不及时处理,可能导致:

  • 集群状态变为 yellowred
  • 查询性能下降
  • 数据丢失风险(主分片故障时无可用副本)

为此,我们设计一套 Elasticsearch 自动副本修复系统(Auto Replica Recovery System),实现 自动检测 → 根因分析 → 智能修复 → 验证闭环,大幅提升集群自愈能力。


一、系统目标

目标说明
✅ 自动发现异常副本实时监控分片状态
✅ 智能诊断根因区分磁盘、节点、配置等问题
✅ 安全自动修复支持多种修复策略,避免误操作
✅ 人工审批机制高风险操作需确认
✅ 修复结果验证修复后验证副本是否恢复正常
✅ 日志与审计记录所有操作,便于回溯

二、系统架构设计

+---------------------+
| Elasticsearch Cluster |
+----------+----------+
           |
           v
+------------------------+
| 数据采集器(Collector) | ← 定时调用 _cat/shards, _cluster/health, _nodes/stats
+----------+-------------+
           |
           v
+------------------------+
| 分析引擎(Analyzer)   | → 识别异常副本,分析原因
+----------+-------------+
           |
           v
+------------------------+
| 修复决策引擎(Repair Engine) | → 匹配修复策略,生成操作命令
+----------+-------------+
           |
     +-----+------+-------+
     |            |       |
     v            v       v
+----------+ +-----------+ +-------------+
| 执行器    | | 审批中心  | | 告警通知     |
| (Executor)| | (Approval)| | (Notifier)  |
+----------+ +-----------+ +-------------+
     |
     v
+------------------------+
| 状态验证 & 审计日志      | → 验证修复结果,记录操作
+------------------------+

✅ 可部署为独立微服务,支持多集群管理。


三、异常副本检测

1. 检测指标

指标来源说明
shard.state != STARTED_cat/shards主要异常状态
shard.prirep == r_cat/shards仅关注副本
unassigned_since_cluster/allocation/explain未分配时长
recovery.running_recovery恢复是否卡住

2. 异常状态分类

状态是否可自动修复说明
UNASSIGNED最常见,多数可自动修复
INITIALIZING > 10min可能卡住,需干预
RELOCATING > 30min⚠️大分片正常,小分片需检查
STARTED正常

四、根因分析(Diagnosis Engine)

通过多维度数据判断未分配原因:

1. 调用 _cluster/allocation/explain

GET /_cluster/allocation/explain
{
  "index": "logs-2024",
  "shard": 0,
  "primary": false
}

返回 can_allocateallocate_explanationunassigned_info.reason

2. 常见原因与修复策略映射

检测到的原因可修复修复操作
disk watermarks exceeded清理磁盘或迁移分片
cluster.routing.allocation.enable is none启用分配
NODE_LEFT触发重新分配
same shard already active强制重新路由
shard has exceeded the [cluster.routing.allocation.disk.watermark.flood_stage]紧急清理或临时放宽阈值
副本数 > 可用节点数减少副本数
分片太大导致恢复慢⚠️优化分片大小,不自动修复

五、修复策略库(Repair Policy)

1. 安全修复策略(无需审批)

策略操作适用场景
ENABLE_ALLOCATIONPUT /_cluster/settings { "cluster.routing.allocation.enable": "all" }分配被手动禁用
RETRY_FAILED_ALLOCATIONSPOST /_cluster/reroute?retry_failed临时失败
MOVE_SHARD_TO_ANOTHER_NODEPOST /_cluster/reroute + move 命令节点离线

2. 高风险策略(需审批)

策略操作审批方式
REDUCE_REPLICASPUT /index/_settings { "number_of_replicas": 1 }企业微信确认
FORCE_ALLOCATE_STALE_PRIMARY强制分配陈旧主分片仅限运维审批
DELETE_LONELY_SHARD删除孤立分片(dangling)二次确认

六、修复执行器(Executor)

1. 执行流程

检测到异常副本
是否在策略库中?
生成修复命令
是否高风险?
直接执行
发送审批请求
审批通过?
记录拒绝
执行修复
验证结果
记录审计日志

2. 示例:修复磁盘满导致的 UNASSIGNED

{
  "action": "move_shard",
  "index": "logs-2024-06-01",
  "shard": 2,
  "from_node": "node-3",
  "to_node": "node-5",
  "reason": "disk watermark exceeded on node-3"
}

执行:

POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "logs-2024-06-01",
        "shard": 2,
        "from_node": "node-3",
        "to_node": "node-5"
      }
    }
  ]
}

七、审批中心(Approval Center)

1. 审批方式

  • 企业微信/钉钉机器人:发送审批卡片,点击通过/拒绝;
  • Web 控制台:运维登录后审批;
  • 邮件确认:回复“APPROVE”生效。

2. 审批内容示例

【Elasticsearch 修复审批】
集群: prod-es-cluster
操作: 将副本分片 reduce replicas from 2 to 1
索引: large-data-index
原因: 副本数 > 可用节点数
风险: 降低高可用性
请确认是否执行?[通过] [拒绝]

八、状态验证与闭环

修复执行后,必须验证是否成功:

def verify_repair(index, shard, expected_state="STARTED"):
    for _ in range(10):
        state = get_shard_state(index, shard)
        if state == expected_state:
            return True
        time.sleep(30)
    return False
  • 成功:记录 status=success,关闭告警;
  • 失败:重试 2 次,仍失败则告警通知人工介入。

九、审计日志设计

所有操作记录到专用索引 audit-repair-*

{
  "timestamp": "2024-06-01T10:00:00Z",
  "cluster": "prod-es",
  "action": "enable_allocation",
  "index": "logs-2024-06-01",
  "shard": 0,
  "executor": "auto-repair-bot",
  "approval_by": "zhangsan",
  "command": "PUT /_cluster/settings {\"cluster.routing.allocation.enable\": \"all\"}",
  "result": "success",
  "duration_ms": 1200
}

支持审计、回溯、统计修复成功率。


十、告警与通知

1. 告警场景

  • 修复失败;
  • 高风险操作待审批;
  • 连续出现同类问题(可能系统性故障)。

2. 通知渠道

  • 钉钉/企业微信机器人;
  • 邮件(To: devops@company.com);
  • Prometheus Alertmanager。

十一、部署与集成

1. 部署方式

  • Kubernetes Pod + CronJob + Webhook;
  • Python/Go 服务 + REST API;
  • 作为 Elastic Agent 集成模块(未来)。

2. 权限控制

  • 使用 API Key 或 Role-Based Access Control(RBAC);
  • 仅授予必要权限:
    • cluster:admin/settings/update
    • cluster:admin/reroute
    • indices:admin/settings/update

十二、安全与风险控制

风险控制措施
误删数据禁止自动执行 DELETE 操作
修复失败导致雪崩限流:每次只修复 1~2 个分片
权限过大使用最小权限原则
审批绕过强制高风险操作需审批
网络分区误判结合多个指标判断

十三、最佳实践 checklist ✅

项目建议
采集频率30s
修复重试最多 2 次
审批机制高风险操作必须审批
验证闭环修复后必须验证
日志审计所有操作可追溯
多集群支持支持 prod/staging/dev

十四、扩展建议

功能说明
AI 根因预测使用历史数据训练模型预测故障原因
修复效果评估统计“修复后稳定性”指标
与 ILM 集成自动调整冷数据副本数
可视化修复流程在 Kibana 中展示修复路径
文章目录概况安装PostgreSQL设置主节点设置从节点验证故障处理,主从节点切换从节点扩容概况CentOS Linux release 7.7.1908PostgreSQL13三台服务器,一主两从,实时复制。主节点读写,从节点只读,读写分离不借助插件或第三方中间件,仅使用PostgreSQL自带的流复制功能Replication主节点可建库建表、可读写,两个从节点为只读,程序使用时可以将查询和统计相关服务读取从节点,通过读写分离减少数据库读写压力设置同步复制,为热备份,数据实时同步,对于大多数业务来说,可以认为三个库数据完全相同,当一个库故障时,其他库仍然可提供服务,增加服务可用性当主节点故障时,数据无法更新,只能手动将从节点升格为主节点,需要修改服务的数据库连接配置等,服务短暂不可用(也可提前准备好监控和切换脚本,服务不可用时尽早发现和切换)。需要根据自己业务特点,是否能接受此种情况,来决定是否使用此方式。单点故障,自动切换的集群,可以考虑使用PGPool-II 等第三方中间件搭建,后面研究好我会出一篇文档安装PostgreSQL命令如下,具体可参考我之前的博客《PostgreSQL简介和安装部署》# 安装 repository 源:sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装 PostgreSQL13:sudo yum install -y postgresql13-server# 初始化数据库,并设置启动命令和开机启动:sudo /usr/pgsql-13/bin/postgresql-13-setup initdbsudo systemctl enable postgresql-13sudo systemctl start postgresql-13# 另外,查看状态,关闭命名和重启命令sudo systemctl status postgresql-13sudo systemctl stop postgresql-13sudo systemctl restart postgresql-13123456789101112131415三个节点安装完成后,就可以开始使用了可以创建用户、赋予权限、修改密码,可以建库建表早一些功能测试等默认安装创建的数据库,没有主从之分,都是主节点,可以使用这条语句验证下是否为从节点,查询结果为"f"表示false,当前数据库节点为主库节点sudo -u postgres /usr/pgsql-13/bin/psql -c "select pg_is_in_recovery()"1下面开始搭建集群,关闭三个PostgreSQL服务,开始改配置文件设置主节点主从节点可以自己规划好,准备好不同机器就行,也可以使用最小集群一主一从主要是修改2个配置文件,都在data目录下,一个是数据库基础配置,一个是访问权限控制默认初始化的数据库,data目录在/var/lib/pgsql/13/data修改文件夹里面的pg_hba.conf,设置 Replication 访问策略,允许流复制# replication privilege.# 追加一条“允许postgres用户,通过全部网络地址使用 Replication ”的策略host replication postgres 0.0.0.0/0 trust123继续修改数据库配置文件postgres.conf,进行一些参数设置,允许流复制# -----------------------------# PostgreSQL configuration file# -----------------------------# - Connection Settings -listen_addresses = '*' # what IP address(es) to listen on;#port = 5432 # (change requires restart)max_connections = 200 # (change requires restart)# - Authentication -#authentication_timeout = 1min # 1s-600spassword_encryption = scram-sha-256 # md5 or scram-sha-256#------------------------------------------------------------------------------# RESOURCE USAGE (except WAL)#------------------------------------------------------------------------------# - Memory -shared_buffers = 1GB # min 128kB 官方推荐内存设置带大小为系统内存的1/4temp_buffers = 64MB # min 800kBwork_mem = 64MB # min 64kBmax_stack_depth = 4MB # min 100kBdynamic_shared_memory_type = posix # the default is the first option#------------------------------------------------------------------------------# WRITE-AHEAD LOG#------------------------------------------------------------------------------wal_level = replica # minimal, replica, or logicalfsync = on # flush data to disk for crash safetysynchronous_commit = on # synchronization level;wal_log_hints = on # also do full page writes of non-critical updates# - Checkpoints -checkpoint_timeout = 10min # range 30s-1dmax_wal_size = 1GBmin_wal_size = 80MB# - Archiving -archive_mode = on # enables archiving; off, on, or always# (change requires restart)archive_command = 'cp %p /data/postgresql/archive/%f' # command to use to archive a logfile segment#-----------------------------------------------------------------------------# REPLICATION#------------------------------------------------------------------------------max_wal_senders = 10 # max number of walsender processes 设置了可以最多有几个流复制的链接# (change requires restart)wal_keep_size = 1024 # in megabytes; 0 disablesmax_slot_wal_keep_size = 10 # in megabytes; -1 disableswal_sender_timeout = 120s # in milliseconds; 0 disables# - Standby Servers -hot_standby = on # "off" disallows queries during recovery#------------------------------------------------------------------------------# REPORTING AND LOGGING#------------------------------------------------------------------------------# - Where to Log -log_destination = 'stderr' # Valid values are combinations oflogging_collector = on # Enable capturing of stderr and csvloglog_directory = 'log' # directory where log files are written,# can be absolute or relative to PGDATAlog_filename = 'postgresql-%a.log' # log file name pattern,log_truncate_on_rotation = on # If on, an existing log file with thelog_rotation_age = 1d # Automatic rotation of logfiles willlog_rotation_size = 50MB # Automatic rotation of logfiles willlog_min_duration_statement = 2000 # 配置数据库慢查询时间,如果超过配置的时间,就会将查询的SQL语句记录到日志# - What to Log -log_connections = onlog_disconnections = onlog_line_prefix = '%m [%p] ' # special values:log_timezone = 'Asia/Shanghai'datestyle = 'iso, mdy'#intervalstyle = 'postgres'timezone = 'Asia/Shanghai'# These settings are initialized by initdb, but they can be changed.lc_messages = 'en_US.UTF-8' # locale for system error message# stringslc_monetary = 'en_US.UTF-8' # locale for monetary formattinglc_numeric = 'en_US.UTF-8' # locale for number formattinglc_time = 'en_US.UTF-8' # locale for time formatting# default configuration for text searchdefault_text_search_config = 'pg_catalog.english'shared_preload_libraries = '' # citus (change requires restart)1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586启动服务,使配置生效,主节点设置完毕sudo systemctl start postgresql-13# 或sudo systemctl restart postgresql-13123设置从节点主从要保持一致,主要是 data 保持一致,我们可以直接将主节点data同步到从节点如果从节点没有关闭,可以先关闭 sudo systemctl stop postgresql-13去默认的data位置,删除所有文件
03-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值