# es-migrate **Repository Path**: kml/es-migrate ## Basic Information - **Project Name**: es-migrate - **Description**: Cross-version Elasticsearch index migration tool (GUI + CLI + single-file executable) - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-26 - **Last Updated**: 2026-08-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
# ⚡ ES Migrate **跨版本 Elasticsearch 索引批量迁移工具 · Python · 跨平台** 自带进度条 / 自动同步 mapping / 跨大版本支持 / GUI + CLI + 单文件可执行 --- [![Python](https://img.shields.io/badge/Python-3.9%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/) [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey)](#) [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE) [![CI](https://github.com/lookapu/es-migrate/actions/workflows/build-windows.yml/badge.svg)](https://github.com/lookapu/es-migrate/actions/workflows/build-windows.yml) [![Release](https://img.shields.io/github/v/release/lookapu/es-migrate?color=blue&logo=github)](https://github.com/lookapu/es-migrate/releases/latest) [![Downloads](https://img.shields.io/github/downloads/lookapu/es-migrate/total?color=orange)](https://github.com/lookapu/es-migrate/releases) **设计兼容范围:Elasticsearch 5.x → 9.x;实际迁移前请先在测试索引验证 mapping 与插件兼容性** [🚀 快速开始](#-快速开始) · [📦 特性](#-特性) · [🖥️ GUI 用法](#-gui-用法) · [💻 CLI 用法](#-cli-用法) · [🛠 打包](#-打包) · [❓ 跨大版本原理](#-跨大版本原理) · [☕ 赞助](#-赞助)
--- ## ✨ 项目特点 | | | |---|---| | 🎯 **跨大版本** | 7.8 → 9.x 自动回退到 scroll+bulk(无需中间集群) | | 🧠 **mapping 自动规整** | 7.x 剥 `_doc` 包装、剔 `_all` 等废弃字段 | | 🖥️ **三种形态** | 命令行 / 桌面 GUI / 单文件可执行(双击即用) | | 📊 **实时进度** | 索引级 + 文档级双层进度条 / 实时日志 | | 🔁 **安全发布** | 校验成功后在目标集群内原子切换别名(`--swap-aliases`) | | 🛟 **可恢复** | SQLite 持久任务、进程崩溃恢复、已完成索引跳过、审计报告 | | 🚦 **大数据保护** | PIT/scroll 流式读取、索引并发、全局限速、429 指数退避 | | 🧯 **失败隔离** | Bulk 子项级重试、不可恢复数据写入 DLQ JSONL | | 🏭 **生产安全模式** | 只写新索引、遇错即停、全量指纹、负载熔断、禁止破坏性冲突策略 | | 📸 **快照向导** | 自动按 ES 版本、仓库类型和部署方式生成插件安装与恢复演练教程 | | ⏱️ **快照增量接管** | 自动选择包含所选索引的最新快照,以快照开始时间为基线多轮追平 | | 🧾 **审批与支持** | 不可变执行计划、校验码审批、批准人审计、脱敏诊断包 | | 🔐 **多鉴权** | Basic Auth / API Key / CA 证书 / 跳过 TLS | --- ## 📁 文件清单 | 文件 | 用途 | |------|------| | `es_migrate.py` | 核心引擎 + CLI 入口 | | `es_migrate_gui.py` | tkinter 桌面 GUI 入口 | | `migration_store.py` | SQLite 任务、checkpoint 与审计事件 | | `es_migrate_jobs.py` | 查询任务和导出审计报告 | | `es_snapshot_guide.py` | 命令行生成版本感知的快照仓库教程 | | `diagnostics.py` | 生成不含凭证、数据库、DLQ 和索引内容的支持包 | | `product_info.py` | 产品版本与发布通道的统一来源 | | `es_migrate.spec` | macOS PyInstaller app bundle 配置 | | `es_migrate_windows.spec` | Windows PyInstaller 单文件配置 | | `build_windows.bat` | Windows 一键打包脚本 | | `build_macos.sh` | macOS 一键打包脚本(含 ad-hoc 签名) | | `es_migrate.command` | macOS 双击启动 GUI 脚本 | | `.github/workflows/build-windows.yml` | GitHub Actions 自动构建 Windows exe | | `requirements.txt` | 运行 / 打包依赖 | | `assets/sponsors/` | 赞助二维码(支付宝 / 微信) | --- ## 🚀 快速开始 ### ① 安装依赖 ```bash pip install -r requirements.txt ``` 依赖只有 `requests` 和 `tqdm`,加上打包用的 `pyinstaller`。 ### ② 命令行(开发 / 服务器) ```bash python es_migrate.py \ --source-url https://es7.internal:9200 \ --target-url https://es9.internal:9200 \ --source-user admin --source-password 'xxx' \ --target-user admin --target-password 'yyy' ``` ### ③ 桌面 GUI(运维 / 一次性任务) ```bash python es_migrate_gui.py ``` > macOS 用户也可以直接双击 `es_migrate.command`。 ### ④ 双击即用(零依赖) 从 [GitHub Releases](https://github.com/lookapu/es-migrate/releases/latest) 下载已构建好的可执行文件: - Windows:`es_migrate-windows-x64.zip`(单文件 exe,约 30-50 MB,双击即用) - 每个 Release 附带 `SHA256SUMS.txt` 校验和、`RELEASE.json` 发布元数据与 SPDX 2.3 SBOM > 推送新 tag(`git tag vX.Y.Z && git push origin vX.Y.Z`)后,GitHub Actions 会自动构建并附加到 Release,无需手动上传。详见 [🛠 打包](#-打包) 章节。 --- ## 📦 特性 - 批量迁移多索引(通配符 / 显式列表 / 全部用户索引) - **自动同步 mapping**:跨版本规整(剥 7.x `_doc` 包装、剔 `_all` 等废弃字段) - **索引选择器**:从源 ES 获取索引,支持搜索、多选、全选、反选 - **进度与中断**:CLI 用 tqdm;GUI 支持实时进度、取消任务和继续未完成 - **跨大版本**:auto 模式下 7.8 → 9.x 自动回退到 scroll+bulk - **在线追平与校验**:全量后按 `_id` 覆盖追平,可选日期/数值水位字段与回看窗口 - **快照后增量追平**:恢复 OSS/COS 快照后,从快照开始时间减去重叠窗口继续同步新增和更新 - **生产预检**:集群健康、mapping、`_source`、增量字段类型、目标冲突检查 - **内置配置建议**:关键选项旁提供 `?` 悬浮提示,说明推荐起点与生产风险 - **可靠写入**:Bulk 子项级分类,429/超时/5xx 仅重试失败项;致命项写入 DLQ - **请求体保护**:同时按条数和字节数拆分 Bulk;413 自动二分,单条超限进入 DLQ - **内容校验**:计数与水位稳定后,对源/目标 `_source` 做 SHA-256 抽样比对 - **持久任务**:SQLite WAL、schema 自动升级、进程租约/心跳、断点恢复和审计报告 - **海量迁移控制**:PIT + `search_after`(新版本)/ scroll 回退、并行索引、全局 docs/s 限速 - **防误操作**:使用 `cluster_uuid` 识别同一集群,即使源/目标入口 URL 不同 - 可选 **目标集群内别名原子切换**(只在数据校验成功后执行) - `--dry-run` / 失败重试 / 摘要报告 - GUI 持久化配置(保存到 `~/.es_migrate_gui.json`) --- ## ❓ 跨大版本原理 ### 为什么用 `requests` 而不是官方 Python client? `elasticsearch` 不同大版本的 Python client 兼容边界较多。脚本改用 `requests` 直连 HTTP API,减少客户端版本耦合;但自定义插件字段、分析器及 特殊 mapping 仍需在实际版本组合上验证。 ### 为什么 7.8 → 9.x 不能直接 `_reindex`? 本工具根据源、目标 `cluster_uuid` 判断是否为同一集群;同集群可使用 `_reindex`。不同集群统一使用 scroll+bulk,避免要求目标集群配置 remote whitelist,也能覆盖跨多个 major 的迁移场景。 | 方案 | 优点 | 缺点 | |------|------|------| | **scroll + bulk**(本工具默认 fallback) | 不需要中间集群、不需要 S3 | 慢(受单连接限制) | | 7.8 → 8.x → 9.x 两步 | 最稳 | 需要中间集群 | | Snapshot → S3/FS → restore | 最快 | 需要共享存储 | `--mode auto` / GUI 模式会自动判断。源、目标为同一集群时必须设置目标后缀, 否则工具会在任何删除或写入之前拒绝运行。 --- ## 💻 CLI 用法 ### 1. 迁移所有用户索引(自动选模式) ```bash python es_migrate.py \ --source-url https://es7.internal:9200 \ --target-url https://es9.internal:9200 \ --source-user admin --source-password 'xxx' \ --target-user admin --target-password 'yyy' ``` ### 2. 指定索引(通配符 / 显式) ```bash python es_migrate.py \ --source-url ... --target-url ... \ --indices "logs-*,metrics-2024*,user_behavior" ``` ### 3. 强制 scroll+bulk(即便版本兼容) ```bash python es_migrate.py --source-url ... --target-url ... --mode scroll ``` ### 4. 干跑(不写任何数据) ```bash python es_migrate.py --source-url ... --target-url ... --dry-run ``` ### 5. 目标加后缀 + 目标集群内别名原子切换 ```bash python es_migrate.py \ --source-url ... --target-url ... \ --target-suffix _v9 --swap-aliases ``` 切换只发生在目标集群,并且只在迁移和计数校验成功后执行。两个独立集群 之间无法通过 Alias API 原子切换客户端连接;业务侧仍需切换目标集群地址。 ### 6. 持续写入时追加追平轮次 ```bash python es_migrate.py \ --source-url ... --target-url ... \ --live-sync-rounds 4 --live-sync-interval 5 ``` 初次全量后最多再执行 4 轮覆盖同步。连续两轮满足“本轮前源计数 = 本轮后 源计数 = 目标计数”才判为收敛,否则任务明确失败,不会误报成功。 生产环境建议给每条新增和更新记录维护单调的日期或数值字段: ```bash python es_migrate.py \ --source-url ... --target-url ... \ --live-sync-rounds 8 --live-sync-interval 3 \ --incremental-field updated_at \ --incremental-overlap-ms 120000 ``` 第一轮仍是全量;后续轮次只扫描水位线回看窗口内的文档。回看窗口用于覆盖 乱序、时钟偏差和延迟写入,重复数据会按原 `_id` 幂等覆盖。 对象存储快照控制台还支持“快照后增量追平”:自动选择同时包含全部所选索引 的最新 SUCCESS 快照,并以快照 `start_time_in_millis` 作为第一轮水位。该模式 要求增量字段为 `date` 或 `date_nanos`,目标索引已经恢复完成,并通过生产执行 计划审批。物理删除无法通过时间范围查询推断;若业务存在删除,必须配合 CCR/CDC,或进入最终停写窗口完成删除核对后再切换业务流量。 ### 7. 带 query 过滤 ```bash python es_migrate.py \ --source-url ... --target-url ... \ --indices "logs-*" \ --query '{"range":{"@timestamp":{"gte":"2024-01-01"}}}' ``` ### 8. API Key 鉴权(ES 8.x/9.x 默认开 security) ```bash python es_migrate.py \ --source-url ... --target-url ... \ --source-api-key "VnVhQ..." --target-api-key "VnVhQ..." ``` ### 9. 自签名证书 / 内网 CA ```bash python es_migrate.py \ --source-url ... --target-url ... \ --source-ca /path/to/ca.pem --target-ca /path/to/ca.pem ``` ### 10. 海量数据限速、并发与失败恢复 ```bash python es_migrate.py \ --source-url ... --target-url ... \ --indices "logs-*" \ --concurrency 4 \ --docs-per-second 50000 \ --bulk-retries 8 \ --bulk-max-mb 10 \ --verify-sample-size 500 ``` 生产安全模式建议使用版本化目标后缀,并明确声明持续写入: ```bash python es_migrate.py \ --source-url ... --target-url ... \ --indices "orders-*" \ --target-suffix "_v20260727" \ --on-conflict skip \ --production-safe-mode \ --continuous-writes \ --incremental-field updated_at \ --stop-on-error \ --verify-full-content ``` 该模式强制使用可在请求边界暂停的 `scroll+bulk`,禁止覆盖或重建已有目标 索引,并在目标集群 red、Heap/磁盘压力、pending task 或写线程池新增拒绝时 暂停写入。超过安全等待上限会停止任务,而不是继续给线上集群施压。 生产安全模式在预检后生成: ```text ~/.es_migrate/reports/<任务ID>.plan.json ``` 计划包含实际集群 UUID、版本、源/目标索引映射、安全参数、预检风险和 SHA-256。GUI 要求输入该计划专属的 8 位校验码;批准人和完整计划哈希会 进入审计事件。CLI 使用两阶段流程: ```bash python es_migrate.py ... --production-safe-mode --plan-only # 保持全部迁移参数不变,使用上一步的任务 ID 与 approval_code python es_migrate.py ... --production-safe-mode \ --job-id <任务ID> --approve-plan ``` 每次启动都会生成任务 ID。停止、崩溃或失败后,用完全相同的迁移参数并追加: ```bash python es_migrate.py ... --job-id <任务ID> ``` 已完成索引不会重跑,运行中的索引会安全回到 pending 并按 `_id` 覆盖重试。 默认运行数据位于 `~/.es_migrate/`: - `state.db`:任务、索引状态、checkpoint 和审计事件 - `reports/<任务ID>.json`:完整结构化报告 - `dlq/*.jsonl`:不可恢复或重试耗尽的 Bulk 文档 任务查询和报告导出: ```bash python es_migrate_jobs.py list python es_migrate_jobs.py show <任务ID> python es_migrate_jobs.py export <任务ID> --output ./audit.json python es_migrate_jobs.py diagnostics <任务ID> \ --output ./support.zip \ --config ~/.es_migrate_gui.json ``` 诊断包只包含系统信息、脱敏审计报告、脱敏 GUI 配置及内部 SHA-256 清单; 明确排除凭证、SQLite 状态库、DLQ 文档和索引内容。 ### 常用参数 | 参数 | 默认 | 说明 | |------|------|------| | `--mode` | `auto` | `auto` / `reindex` / `scroll` | | `--on-conflict` | `merge` | `recreate`(删了重建)/ `skip` / `force` / `merge`(按 _id 覆盖) | | `--batch-size` | 1000 | scroll 单批大小 | | `--slices` | `auto` | `_reindex` 切片数(auto 由 ES 决定) | | `--swap-aliases` | 关 | 迁移完做原子别名切换 | | `--target-suffix` | `""` | 目标索引加后缀 | | `--live-sync-rounds` | `2` | 初次全量后的最大在线追平轮数 | | `--live-sync-interval` | `2` | 追平轮次之间等待秒数 | | `--incremental-field` | 空 | 更新水位字段,必须为日期或数值类型 | | `--incremental-overlap-ms` | `60000` | 水位回看窗口 | | `--concurrency` | `1` | 并行迁移索引数 | | `--docs-per-second` | `0` | 全任务写入限速,0 为不限速 | | `--bulk-retries` | `5` | 可恢复 Bulk 子项最大重试次数 | | `--bulk-max-mb` | `10` | 单个 Bulk 请求的编码后大小上限 | | `--verify-sample-size` | `200` | 收敛时进行 `_source` 哈希抽检的文档数 | | `--verify-full-content` | 关 | 常量内存流式比较全部 ID、routing 与 `_source` 内容指纹 | | `--production-safe-mode` | 关 | 强制新索引、预检、遇错即停、全量校验和运行时熔断 | | `--plan-only` | 关 | 仅预检并生成不可变执行计划,不创建索引或写入 | | `--approve-plan CODE` | 空 | 批准与当前任务、集群和参数绑定的生产计划 | | `--continuous-writes` | 关 | 声明源持续写入;安全模式要求可靠水位字段 | | `--no-runtime-guard` | 关 | 关闭目标资源熔断(生产不推荐) | | `--max-heap-percent` | `85` | 自动暂停写入的目标节点 Heap 阈值 | | `--min-disk-free-percent` | `10` | 自动暂停写入的最小磁盘可用比例 | | `--safety-pause-timeout` | `300` | 熔断等待上限,超时后安全终止 | | `--job-id` | 自动生成 | 恢复已有持久任务 | | `--state-db` | `~/.es_migrate/state.db` | 任务状态库 | | `--no-preflight` | 关 | 跳过预检(生产不推荐) | | `--no-verify` | 关 | 跳过源/目标计数校验(不推荐) | | `--exclude` | 系统索引 | 可多次追加排除模式 | | `--include-system` | 关 | 含 `.kibana*` 等 | | `--dry-run` | 关 | 只读不写 | | `--stop-on-error` | 关 | 任一索引失败立即停 | ### 快照插件与安装教程 GUI 测试连接后点击“📸 快照安装指南”,选择源/目标集群、仓库类型和部署方式, 工具会按实际 ES 版本生成教程,但不会自动安装插件、修改配置或重启节点。 也可以使用 CLI: ```bash python es_snapshot_guide.py \ --version 7.17.28 \ --repository s3 \ --deployment docker ``` 版本规则: - ES 8.0+ 已内置 `repository-s3`、`repository-gcs` 和 `repository-azure`,不要重复安装。 - ES 7.x 及更早的自建集群使用上述云仓库时,需要在每个节点安装与 ES 版本完全一致的插件,并逐节点滚动重启。 - `fs` 共享文件系统仓库不需要插件,但所有 master/data 节点必须配置相同 `path.repo` 并访问同一挂载路径。 - `repository-hdfs` 仍是独立插件;Elastic Cloud 不能按自建节点教程操作。 - 仓库注册后必须执行 `_verify`,并通过重命名恢复做真实恢复演练。 ### 阿里云 OSS / 腾讯云 COS 快照 连接测试后点击“☁ OSS / COS 快照”,可以检测两端插件和已有仓库、注册源端 可写仓库、验证仓库、创建所选索引快照、查询状态、注册目标只读仓库以及安全恢复。 - 阿里云托管 ES 使用 `repository-oss`;自建 ES 8.x 的仓库参数自动使用 `oss.client.*` 前缀。 - 腾讯云 COS 根据 ES 主版本自动选择旧版扁平参数或 ES 8.x 的 `cos.client` 嵌套结构。 - 快照异步提交,不会让界面等待到超时;只有状态为 `SUCCESS` 才允许恢复。 - 目标端始终以只读方式注册同一仓库,并在恢复前重新注册以刷新仓库缓存。 - 恢复默认添加 `restored_` 前缀、排除 global state 和 aliases,禁止覆盖生产索引。 - 工具不会删除进行中的快照;关闭窗口只停止查看,不会中止 ES 服务端任务。 - 仓库类型、部署方式、Endpoint/Region、Bucket、Base Path、凭证、限速、快照名和 恢复前缀会随 GUI 主配置自动保存,下次打开快照窗口直接回填。 ### 多节点集群地址 源和目标均可填写多个属于同一集群的节点 URL,使用逗号、分号或换行分隔; GUI 也提供“编辑节点列表”。连接测试会并行探测所有节点并校验 `cluster_uuid`,混入不同集群会直接拒绝。只要至少一个节点健康即可继续,运行期间 遇到网络故障、502、503、504 或 429 会自动切换到下一节点。单个集群最多 20 个地址; 已有高可用负载均衡地址时仍建议只填写负载均衡地址。 ### 环境变量(鉴权备选) ```bash export ES_SRC_USER=admin export ES_SRC_PASS='...' export ES_SRC_API_KEY='...' export ES_SRC_CA=/path/to/ca.pem export ES_TGT_USER=admin export ES_TGT_PASS='...' export ES_TGT_API_KEY='...' export ES_TGT_CA=/path/to/ca.pem ``` --- ## 🖥️ GUI 用法 启动: ```bash python es_migrate_gui.py ``` 界面分 5 个 tab: 1. **① 连接** — 源 / 目标节点列表、用户名密码、API Key、CA 证书;支持集群身份校验、自动故障切换、分别或并行测试,以及 OSS/COS 快照 2. **② 索引** — 从源 ES 获取并多选索引,支持搜索、全选、反选;也可使用全部 / 模式选择 3. **③ 选项** — 模式、批大小、冲突策略、并发、限速、水位字段、重试、任务恢复 ID 4. **④ 进度** — 计划校验码审批、实时进度、取消、恢复、日志与脱敏诊断包 5. **⑤ 说明** — 版本说明 + 跨大版本原理解释 > 配置自动保存到 `~/.es_migrate_gui.json`,下次启动自动加载。OSS/COS 仓库配置与 > 访问凭证也保存在该文件中;程序会在 macOS/Linux 上将文件权限设为 `0600`。 --- ## 🛠 打包 ### 打包 Windows 单文件 exe #### 方式 1:一键脚本(最简单) 在 Windows 上: ```cmd :: 安装 Python 3.9+ (勾选 Add to PATH) :: 下载代码,进入目录 build_windows.bat ``` 产物:`dist\es_migrate.exe`(约 30-50 MB),双击即用,**无需任何 Python 环境**。 脚本会自动创建隔离的 `build_venv_windows`,校验 Python/Tk/SQLite、安装依赖、 执行语法检查和全部测试,再构建以下产物: - `dist\es_migrate.exe` - `dist\es_migrate-windows-x64.zip` - `dist\SHA256SUMS.txt` - `dist\RELEASE.json` - `dist\SBOM.spdx.json` 可用以下方式指定构建 Python: ```cmd set PYTHON=C:\path\to\python.exe build_windows.bat ``` #### 方式 2:手动 PyInstaller ```cmd python -m pip install -r requirements.txt python -m PyInstaller --noconfirm --clean --onefile --windowed ^ --name es_migrate ^ --hidden-import=es_migrate ^ --hidden-import=migration_store ^ --collect-data=certifi ^ es_migrate_gui.py ``` #### 方式 3:Windows spec 文件 ```cmd python -m PyInstaller --noconfirm --clean es_migrate_windows.spec ``` Windows spec 已预配置: - 排除大依赖(numpy/pandas/matplotlib 等)→ 减小体积 - 启用 UPX 压缩 - `console=False` → 无控制台窗口 #### 方式 4:GitHub Actions 自动构建 ```bash git tag v1.0.0 git push origin v1.0.0 ``` CI 会在 `windows-latest` x64 runner 上运行测试、执行相同的一键脚本、启动打包 后的 GUI 做 5 秒冒烟测试,并上传 exe、zip、SHA-256 与发布元数据。Tag 构建会自动附加 到 Release;也可在 Actions 页面用 `workflow_dispatch` 手动触发。 本地商业签名: ```cmd set REQUIRE_SIGNING=1 set WINDOWS_CERT_PATH=C:\secure\release.pfx set WINDOWS_CERT_PASSWORD=<从安全环境注入> set WINDOWS_TIMESTAMP_URL=http://timestamp.digicert.com build_windows.bat ``` 脚本会定位 `signtool.exe`、执行 Authenticode SHA-256 时间戳签名并验证签名, 再生成 ZIP、SHA-256、`RELEASE.json` 和 SPDX 2.3 SBOM。CI 的 Tag 发布强制签名,需要配置 `WINDOWS_CERT_BASE64` 与 `WINDOWS_CERT_PASSWORD` 两个 GitHub Secrets;普通 手动构建可以生成明确标记为 unsigned 的开发产物。 --- ### 打包 macOS .app #### 方式 1:一键脚本(最简单) 在 macOS 上: ```bash bash build_macos.sh ``` 产物: - `dist/es_migrate.app`(arm64 原生) - `dist/es_migrate-macos-arm64.zip`(分发包) - `dist/SHA256SUMS.txt` - `dist/RELEASE.json` - `dist/SBOM.spdx.json` `build_macos.sh` 会完成: 1. 创建干净 venv(避免污染系统 site-packages,否则会拖入几百 MB 无关包) 2. 只装 `pyinstaller / requests / tqdm` 3. PyInstaller 打包成 .app 4. 写入统一产品版本并签名 5. 可选 Developer ID、公证与 stapling 6. 生成 ZIP、SHA-256、机器可读发布元数据和 SPDX 2.3 SBOM 商业签名与公证: ```bash REQUIRE_SIGNING=1 \ MACOS_SIGN_IDENTITY="Developer ID Application: Example Corp (TEAMID)" \ APPLE_ID="release@example.com" \ APPLE_TEAM_ID="TEAMID" \ APPLE_APP_PASSWORD="" \ bash build_macos.sh ``` 未提供商业证书时只生成明确标记为 `adhoc` 的开发/内部分发版本;设置 `REQUIRE_SIGNING=1` 后,缺少 Developer ID 或公证凭据会直接终止构建。 #### 方式 2:手动 PyInstaller ```bash python3 -m venv build_venv source build_venv/bin/activate pip install pyinstaller requests tqdm pyinstaller --windowed --name es_migrate \ --osx-bundle-identifier com.mavis.esmigrate \ --hidden-import=es_migrate es_migrate_gui.py codesign --force --deep --sign - dist/es_migrate.app ``` #### 方式 3:Intel Mac(x86_64) 上面的 build 默认是 arm64(Apple Silicon)。在 Intel Mac 上跑同一个脚本,PyInstaller 会自动产出 x86_64 版本(架构跟随构建机)。 如果要同时支持两种架构(universal binary),需要分别在 arm64 和 x86_64 上 build,再 `lipo` 合并(PyInstaller 不直接支持一键出 universal)。 #### Mac 签名说明 macOS 签名分三档: | 级别 | 命令 | 谁能用 | 用户体验 | |------|------|--------|----------| | **不签名** | (无) | 仅本机 | 双击 → "es_migrate 已损坏" 弹窗(其实没损坏,是 Gatekeeper 拦截) | | **Ad-hoc 签名**(默认) | `codesign --sign -` | 仅本机 | 双击正常;首次运行可能需到「系统设置 → 隐私与安全性」点"仍要打开"一次 | | **Developer ID + 公证** | `codesign --sign "Developer ID Application: ..."` + `xcrun notarytool submit` | 任何 Mac | 双击直接运行,无任何弹窗 | **本工具默认用 ad-hoc 签名**,够用场景: - 自己在 Mac 上跑 - 团队内网分发,同事首次「右键 → 打开」即可 **要发到公网 / App Store**,需要: 1. Apple Developer Program 账号($99/年) 2. 开发者证书 + 描述文件 3. 提交苹果公证(`xcrun notarytool`),可能等几分钟到几小时 如果你的 Mac 装了 Xcode,也可以这样强制打开(绕过签名): ```bash xattr -dr com.apple.quarantine dist/es_migrate.app ``` --- ## ⚠️ 注意事项 1. **7.8 → 9.x 的 mapping 兼容**:脚本会去掉 `_doc` 类型包装、剔除已废弃字段。但**字段类型本身不兼容**的情况(如 7.x 的 `keyword` 在 9.x 完全保留 — OK;7.x 的 `text` 字段在 9.x 默认仍 OK)。如有自定义 analyzer / runtime field,需人工 review。 2. **shard 数**:保留源端可移植设置;目标集群节点数、磁盘水位和分片规划仍需上线前容量评审。 3. **持续写入边界**:配置水位字段后可识别新增及更新(包括总数不变),前提是每次更新都同步更新该字段。通用搜索 API仍无法可靠传播物理删除;严格 RPO=0 必须使用业务双写、CDC/CCR、删除墓碑,或在最终切换前短暂冻结写入并补偿删除。 4. **别名边界**:别名切换只在目标集群内部原子执行,不能替代跨集群客户端地址切换。 5. **规模边界**:本工具支持流式、限速和多索引并发,不会把全量文档放入内存;但单个超大索引仍由一个读取流处理。十亿级数据应先基准压测,并对 snapshot/restore、CCR 或分布式 worker 做方案比较。 6. **继续未完成**:状态持久化到 SQLite。已完成索引跳过;中断中的索引从本索引安全重扫,增量水位持久保存。同一任务由租约保护,不能被两个进程同时恢复。DLQ 修复后应以同任务或受控补偿流程重放。 7. **打包体积**:单文件 exe 通常 30-50 MB。开启 UPX 压缩可降到 ~20 MB(在 spec 里 `upx=True` 已默认开启)。 8. **杀毒软件**:部分 Windows 杀软对 PyInstaller 打包的 exe 误报。可在 spec 中加 `--key` 加密(PyInstaller 不提供强加密,杀软可加白名单更稳)。 9. **Data Stream**:当前版本会识别 Data Stream 并终止预检,不会把 backing index 静默当普通索引迁移。完整迁移需要同时处理 component/index template、ILM、写索引与 rollover 语义。 10. **内容校验边界**:生产安全模式的全量指纹会再次读取全部文档,并以常量内存比较双重顺序无关 SHA-256 聚合;这提供极强的工程一致性证据,但源端仍在变化时可能安全失败。最终 RPO=0 仍依赖 CCR/CDC 或停写边界。 11. **熔断边界**:运行时熔断是迁移侧的附加保护,不替代 Elasticsearch 自身磁盘水位、容量规划、监控告警和限流策略。 ## 🏭 生产与商业化边界 当前代码已经是一套可审计、可恢复、可限流的**单机迁移执行器/桌面运维工具**。 它适合受控生产迁移,但不应被描述成已经完成的多租户商业 SaaS。商业平台还需 在执行器之外建设:服务端 API 与调度器、分布式 worker/租约与高可用、RBAC/SSO、 密钥托管、审批流、监控告警、租户配额、计费、灾备,以及真实规模的长期压测。 生产上线前至少完成: 1. 在脱敏副本上验证 mapping、分析器插件、模板、ILM 和数据流策略。 2. 按峰值写入量压测吞吐、429、磁盘水位、恢复时间和 DLQ 补偿。 3. 明确 RPO/RTO、删除传播方案、最终切换窗口与回滚路径。 4. 从小索引灰度,校验报告通过后再扩大并发;不要一开始就使用最大并发。 --- ## 📺 输出示例 ``` ____ _____ _ | ___\/ ____| | | ES 批量索引迁移工具 | |__ | (___ ___| |_ ___ _ __ ___ __ _ __ _ ___ |___/ \___ \ / _ \ __/ _ \ '_ ` _ \ / _` |/ _` |/ _ \ __ _ ____) | __/ || __/ | | | | | (_| | (_| | __/ |_____|_____/ \___|\__\___|_| |_| |_|\__,_|\__, |\___| __/ | |___/ 16:20:11 [INFO] source version: 7.8.0 16:20:11 [INFO] target version: 9.0.0 16:20:11 [INFO] source=... (v7.x) target=... (v9.x) 16:20:11 [INFO] found 12 indices: ['logs-2024.01', 'logs-2024.02', ...] 16:20:11 [INFO] migration mode = scroll indices: 100%|████████████| 12/12 [08:23<00:00, 41.9s/it] docs: 23.4M/23.4M [08:23<00:00, 46.5kdoc/s] 16:20:42 [INFO] ════════════════════════════════════════════════════════════════════ 16:20:42 [INFO] 📋 Migration Summary 16:20:42 [INFO] ════════════════════════════════════════════════════════════════════ 16:20:42 [INFO] ✓ ok 12 16:20:42 [INFO] ✗ failed 0 16:20:42 [INFO] docs 23,456,789 16:20:42 [INFO] elapsed 502.8s 16:20:42 [INFO] ════════════════════════════════════════════════════════════════════ ``` --- ## ☕ 赞助 如果这个工具帮你省下了迁移的时间,欢迎请作者喝杯咖啡 ☕

支付宝赞赏 微信赞赏

支付宝  ·  微信(长按识别 / 扫码)

--- ## 📜 License MIT — [LICENSE](LICENSE),随意用,欢迎 PR。