You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch移除自定义路由后更新致重复记录,求无停机解决方案

无停机移除Elasticsearch自定义路由的优化方案

场景回顾

  • 环境:Elasticsearch 7.8.1,原索引routing参数为可选,此前使用customerId作为自定义路由
  • 核心问题:切换为默认docId路由后,相同_id的文档因路由值不同落在不同分片,出现重复记录;原本的更新操作变成新增重复数据,原方案存在残留数据或需停机的弊端

方案一:双写+渐进式迁移(适合大数据量场景)

  1. 启动双写模式
    • 修改应用代码,所有写入/更新请求同时指向两个目标:
      • 原索引:保持原有customerId路由的写入逻辑,确保旧数据正常维护
      • 新索引:创建时关闭自定义路由(使用默认_id作为路由),写入时不指定_routing参数
    • 后台启动异步_reindex任务,将原索引数据批量迁移至新索引,通过wait_for_completion=false让任务后台执行,同时设置合理的scroll_size控制批次,避免冲击集群性能
  2. 校验数据一致性
    • 编写脚本对比新旧索引的文档总数,随机抽样文档内容进行校验,确保双写和迁移的数据完全一致
  3. 切换读流量
    • 当数据一致性达标(比如差异率低于0.01%),将应用的所有读请求切换至新索引,写请求仍保持双写,确保过渡期间无数据丢失
  4. 停止双写并清理旧索引
    • 观察24小时确认新索引读写正常后,停止往原索引写数据,最后分批清理或直接删除原索引

方案二:别名+原地清理(适合中等数据量场景)

  1. 统一请求入口
    • 给原索引创建读写别名(如my_index_alias),应用所有请求通过别名操作
  2. 渐进式更新写入逻辑
    • 修改应用,新写入/更新的文档不再指定customerId路由,使用默认_id路由
    • 后台启动任务,遍历原索引中带自定义路由的文档,重新写入同一索引(不指定_routing),此时文档会落到对应分片,原分片的旧文档暂时保留
  3. 清理旧路由文档
    • 先更新索引映射,开启_routing字段存储:
      PUT /my_index/_mapping
      {
        "_routing": {"required": false, "store": true}
      }
      
    • 用_delete_by_query分批删除带自定义路由的旧文档,通过scroll和size控制批次大小,避免集群压力过高
  4. 移除路由配置
    • 旧文档清理完成后,修改索引配置,彻底移除自定义路由相关设置

方案优势

  • 方案一:完全隔离新旧数据,切换风险极低,支持超大规模数据迁移,全程无需停机
  • 方案二:无需创建新索引,节省集群资源,操作步骤更简洁,适合数据量中等的场景

内容的提问来源于stack exchange,提问作者bhushan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:20:18