From 5080bf9bc194ab740b651119382dc04a50991f64 Mon Sep 17 00:00:00 2001 From: wangyu <823267011@qq.com> Date: Mon, 9 Feb 2026 18:16:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E4=B8=80=E5=AF=B9=E4=B8=80?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5=E8=83=BD?= =?UTF-8?q?=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 77 ++++++++++++++++-------------- docker-compose.yml | 114 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 128 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index c321942..6275119 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,72 @@ # DataKeep -一个运行在**备份服务器**上的容灾副本同步服务(Pull 模式): +一个运行在**备份服务器**上的轻量级容灾副本同步系统(Pull 模式)。 -- **备份服务器**上运行一套 MySQL/Redis/MinIO(作为容灾副本/隔离副本)。 -- `datakeep-backend` 定时从**生产环境**直连拉取数据,并同步写入备份端的 MySQL/Redis/MinIO。 -- 前端使用 **Vue2 + Vue CLI + ElementUI**,提供小时级(0-23)定时配置。 +## 核心设计 +- **物理隔离**:备份服务器运行独立的数据库实例(MySQL/Redis/MinIO),与生产环境物理隔离。 +- **主动同步**:由备份服务器主动连接生产环境拉取数据,即使生产环境被攻击,备份数据依然安全。 +- **多实例支持**:备份机可以同时为多个不同的生产服务提供备份,每个服务在备份机拥有独立的容器组。 ## 核心能力 +- **MySQL 同步**:支持**自动建库**与**表结构变更同步**。通过全量逻辑覆盖模式,确保备份库与生产库结构完全一致。 +- **Redis 同步**:采用键级同步(SCAN/DUMP/RESTORE),同步前自动 `FLUSHALL` 备份库,确保数据副本纯净。 +- **MinIO 同步**:对象级增量镜像(只增不删策略),防止生产端误删导致的灾难性后果。 +- **小时级定时**:前端支持 0-23 时精确配置,支持手动一键触发。 -- **MySQL 同步**:支持**自动建库**与**结构变更自动同步**(全量覆盖模式)。 -- **Redis 同步**:键级全量同步 `SCAN + DUMP + RESTORE`,同步前自动 `FLUSHALL` 备份库。 -- **MinIO 同步**:增量镜像,**只增不删**,确保生产端误删不传播。 -- **配置存储**:使用 SQLite 保证数据一致性。 +--- -## 本地启动指南 (非 Docker) +## 快速启动 (Docker Compose) -如果你想在本地开发环境直接运行,请按以下步骤操作: +这是在 Ubuntu 20.04 生产环境中最推荐的部署方式。 + +1. **执行启动命令**: + ```bash + docker compose up -d --build + ``` +2. **访问系统**: + 在浏览器打开 `http://<服务器IP>:12000` + +--- + +## 本地启动指南 (非 Docker 开发环境) ### 1. 后端 (FastAPI) -1. 进入 `backend` 目录。 -2. 创建并激活虚拟环境: +1. 进入 `backend` 目录,创建虚拟环境并激活: ```bash python -m venv .venv - # Windows: - .\.venv\Scripts\activate - # Linux/macOS: - source .venv/bin/activate + source .venv/bin/activate # Windows 使用 .\venv\Scripts\activate ``` -3. 安装依赖: +2. 安装依赖: ```bash pip install -r requirements.txt ``` -4. **前提条件**:确保本地已安装 `mysql-client`(支持 `mysqldump` 命令)。 -5. 启动服务: +3. 确保本地环境已安装 `mysql-client`(提供 `mysqldump` 命令)。 +4. 运行服务: ```bash uvicorn app:app --host 0.0.0.0 --port 8000 --reload ``` ### 2. 前端 (Vue CLI) 1. 进入 `frontend` 目录。 -2. 安装依赖: +2. 安装依赖并启动: ```bash npm install - ``` -3. 启动开发服务器: - ```bash npm run serve ``` -4. 访问地址:`http://localhost:8080`(默认会自动代理 API 请求到 8000 端口)。 +3. 访问 `http://localhost:8080`,默认配置会自动转发 API 请求到 8000 端口。 -## 生产部署 (Docker Compose) +--- -在备份服务器上,确保已安装 Docker,然后执行: +## 多实例扩展说明 -```bash -docker compose up -d --build -``` -访问地址:`http://服务器IP:12000` +如果你需要备份第 4 个或更多实例,请按以下规范修改 `docker-compose.yml`: -## 配置说明 -- **生产端 (Source)**:填写客户正在使用的生产环境数据库 IP 和账号。 -- **备份端 (Target)**: - - 如果使用 Docker 部署,Host 建议填写容器名:`dr-mysql`, `dr-redis`, `dr-minio`。 - - 如果本地部署,填写 `127.0.0.1` 及对应端口。 +1. **命名规范**:使用 `drN-mysql`、`drN-redis` 格式命名,其中 `N` 为实例序号。 +2. **存储路径**:将卷映射路径设为 `./data/drN/...` 以防数据混淆。 +3. **配置填写**: + - 在 DataKeep 前端新增实例时,**备份端 Host** 填写对应的容器名(如 `dr4-mysql`)。 + - 由于所有容器在同一网络下,直接使用容器名即可实现内网互访。 + +## 注意事项 +- **数据安全**:备份端 Redis 在同步前会清空(FLUSHALL),请勿在备份端 Redis 中存放其他重要数据。 +- **权限**:确保生产端提供的账号具备 `mysqldump`、`SCAN` 和 `GetObject` 权限。 diff --git a/docker-compose.yml b/docker-compose.yml index d562e28..0d2f030 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,9 @@ version: '3.8' +networks: + datakeep-net: + driver: bridge + services: backend: build: ./backend @@ -10,10 +14,6 @@ services: - DATAKEEP_DATA_DIR=/data volumes: - ./data/datakeep:/data - depends_on: - - dr-mysql - - dr-redis - - dr-minio networks: - datakeep-net @@ -28,49 +28,107 @@ services: networks: - datakeep-net - dr-mysql: + # ===== DR Instance 1 (示例) ===== + dr1-mysql: image: mysql:8.0 - container_name: dr-mysql + container_name: dr1-mysql restart: unless-stopped environment: - MYSQL_ROOT_PASSWORD: rootpass - MYSQL_DATABASE: datakeep + MYSQL_ROOT_PASSWORD: rootpass1 volumes: - - ./data/mysql:/var/lib/mysql - ports: - - "3306:3306" + - ./data/dr1/mysql:/var/lib/mysql networks: - datakeep-net - dr-redis: + dr1-redis: image: redis:7-alpine - container_name: dr-redis + container_name: dr1-redis restart: unless-stopped - ports: - - "6379:6379" - volumes: - - ./data/redis:/data command: ["redis-server", "--appendonly", "yes"] + volumes: + - ./data/dr1/redis:/data networks: - datakeep-net - dr-minio: + dr1-minio: image: minio/minio:latest - container_name: dr-minio + container_name: dr1-minio restart: unless-stopped environment: - MINIO_ROOT_USER: minioadmin - MINIO_ROOT_PASSWORD: minioadmin123 + MINIO_ROOT_USER: minio1 + MINIO_ROOT_PASSWORD: minio1pass123 command: server /data --console-address ":9001" - ports: - - "9000:9000" - - "9001:9001" volumes: - - ./data/minio:/data + - ./data/dr1/minio:/data networks: - datakeep-net -networks: - datakeep-net: - driver: bridge + # ===== DR Instance 2 (示例) ===== + dr2-mysql: + image: mysql:8.0 + container_name: dr2-mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: rootpass2 + volumes: + - ./data/dr2/mysql:/var/lib/mysql + networks: + - datakeep-net + dr2-redis: + image: redis:7-alpine + container_name: dr2-redis + restart: unless-stopped + command: ["redis-server", "--appendonly", "yes"] + volumes: + - ./data/dr2/redis:/data + networks: + - datakeep-net + + dr2-minio: + image: minio/minio:latest + container_name: dr2-minio + restart: unless-stopped + environment: + MINIO_ROOT_USER: minio2 + MINIO_ROOT_PASSWORD: minio2pass123 + command: server /data --console-address ":9001" + volumes: + - ./data/dr2/minio:/data + networks: + - datakeep-net + + # ===== DR Instance 3 (示例) ===== + dr3-mysql: + image: mysql:8.0 + container_name: dr3-mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: rootpass3 + volumes: + - ./data/dr3/mysql:/var/lib/mysql + networks: + - datakeep-net + + dr3-redis: + image: redis:7-alpine + container_name: dr3-redis + restart: unless-stopped + command: ["redis-server", "--appendonly", "yes"] + volumes: + - ./data/dr3/redis:/data + networks: + - datakeep-net + + dr3-minio: + image: minio/minio:latest + container_name: dr3-minio + restart: unless-stopped + environment: + MINIO_ROOT_USER: minio3 + MINIO_ROOT_PASSWORD: minio3pass123 + command: server /data --console-address ":9001" + volumes: + - ./data/dr3/minio:/data + networks: + - datakeep-net