了解Redis Cluster吗?多加几个实例数据要怎么迁移?

1 个回答

  • 狄青秋
    世间行乐亦如此,古来万事东流水。
    * **Redis Cluster 的数据分布 = 16384 个哈希槽(hash slot)**。每个 **master** 负责一部分槽,键的路由:`slot = CRC16(key) % 16384`(带 `{tag}` 只取花括号内参与哈希)。 * **加新实例(新 master)= 给它分配一部分槽**,再把这些槽里的**键**从旧 master 迁到新 master。迁移在线进行、按**槽为单位**,对客户端是 **MOVED/ASK** 重定向,业务不停机。 # 加节点并迁移数据的标准流程 > 以下用 `redis-cli --cluster` 自带的“集群管理器”,它会自动用 `CLUSTER SETSLOT` + `MIGRATE` 把对应槽的 key 搬过去。 1. **准备新实例** * 配置 `cluster-enabled yes`、独立 `nodes.conf`、`cluster-announce-ip/port`(有密码再配 `requirepass/masterauth`)。 * 启动后先不要自己写数据。 2. **把新实例加入集群(作为 master)** ```bash redis-cli -a <pass> --cluster add-node NEW_IP:NEW_PORT EXISTING_IP:ANY_MASTER_PORT ``` > 如果先加从库:加节点时带 `--cluster-slave --cluster-master-id <某个masterId>`;之后也能再提升为主。 3. **迁移槽(reshard / rebalance)** * **平均分配(最省心)**: ```bash # 以某个已在集群的节点为入口,自动把槽“均衡”到所有 master(包含新加的空 master) redis-cli -a <pass> --cluster rebalance EXISTING_IP:PORT --cluster-use-empty-masters ``` * **把 N 个槽指定迁给新 master(精细控制)**: ```bash redis-cli -a <pass> --cluster reshard EXISTING_IP:PORT # 按提示输入:要移动的 slot 数、目标 nodeId(新master)、来源节点(可填 all) ``` 这些命令会对每个 slot 做: * 在**源**节点把该 slot 标记为 *MIGRATING*,在**目标**节点标记为 *IMPORTING*; * 用 `MIGRATE` 批量搬运该 slot 内的 key(含 TTL),期间客户端可能收到 `ASK` 重定向; * 完成后把该 slot 的 owner 切到目标节点。 4. **校验与收尾** ```bash redis-cli -a <pass> --cluster check ANY_IP:PORT redis-cli -a <pass> cluster nodes redis-cli -a <pass> cluster info ``` * 看 16384 槽是否都分配(no “slots not covered”),复制(replica)是否健康。 * 有副本需求:给新 master 再加从库或重绑原有从库,保证每主至少 1 个 replica。 # 迁移期间业务影响与注意 * **在线无停机**:命令执行仍串行,迁移按槽逐步进行。客户端需要正确处理 **`MOVED` 和 `ASK`**(主流驱动都支持)。 * **键的成组语义**:用 `{tag}` 的多键操作会落到同一 slot —— **迁移时这个 slot 一起移动**,不会打散。 * **大键/热键**:`MIGRATE` 搬运大 value 会占用网络与主线程时间,建议: * 迁移在业务低峰进行; * 事先用 `redis-cli --bigkeys` 找大键,必要时先拆分; * 分批/多次 `reshard`,不要一次移动太多槽。 * **均衡策略**:`--cluster rebalance` 支持**权重**(大机器多分点槽): ```bash redis-cli --cluster rebalance ENTRY --cluster-weight <nodeIdA>=2 <nodeIdB>=1 ... ``` * **覆盖设置**:保持默认 `cluster-require-full-coverage yes` 即可;按槽迁移不会造成“槽未覆盖”,无需改。 # 常见问题速答 * **能直接把 RDB/AOF 拷到新节点吗?** 不行。那是全量数据,新节点会变成独立实例。**Cluster 的扩容必须按槽迁移**。 * **跨机房迁移?** 不建议跨高延迟链路做 Cluster;如需跨 DC,做上层同步/双集群架构。 * **怎么把新 master 先当 slave 再切主?** 用 `add-node --cluster-slave` 加从 → `CLUSTER REPLICATE <masterId>` 绑定 → 准备就绪后 `CLUSTER FAILOVER` 提升,再 `rebalance`。 ## 最简操作清单(可复制) ```bash # 1) 加新 master redis-cli -a <pass> --cluster add-node 10.0.0.9:7001 10.0.0.1:7001 # 2) 均衡槽到所有 master(包含新节点) redis-cli -a <pass> --cluster rebalance 10.0.0.1:7001 --cluster-use-empty-masters # 3) 校验 redis-cli -a <pass> --cluster check 10.0.0.1:7001 ```
    编辑于 2025-08-19 18:24 •IP属地 北京
    举报
    评论
    收藏