diff --git a/README.md b/README.md index 08cb390..e66793a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RedisShake: Redis Data Processing & Migration Tool +# RedisShake 4.x: Redis Data Processing & Migration Tool [![CI](https://github.com/tair-opensource/RedisShake/actions/workflows/ci.yml/badge.svg?event=push&branch=v4)](https://github.com/tair-opensource/RedisShake/actions/workflows/ci.yml) [![CI](https://github.com/tair-opensource/RedisShake/actions/workflows/pages.yml/badge.svg?branch=v4)](https://github.com/tair-opensource/RedisShake/actions/workflows/pages.yml) diff --git a/docs/src/zh/guide/mode.md b/docs/src/zh/guide/mode.md index 7fcba0f..1de03c7 100644 --- a/docs/src/zh/guide/mode.md +++ b/docs/src/zh/guide/mode.md @@ -4,17 +4,27 @@ outline: deep # 迁移模式选择 +## 概述 + 目前 RedisShake 有三种迁移模式:`PSync`、`RDB` 和 `SCAN`,分别对应 [`sync_reader`](../reader/sync_reader.md)、[`rdb_reader`](../reader/rdb_reader.md) 和 [`scan_reader`](../reader/scan_reader.md)。 -对于从备份中恢复数据的场景,可以使用 `rdb_reader`。 +* 对于从备份中恢复数据的场景,可以使用 `rdb_reader`。 +* 对于数据迁移场景,优先选择 `sync_reader`。一些云厂商没有提供 PSync 协议支持,可以选择`scan_reader`。 +* 对于长期的数据同步场景,RedisShake 目前没有能力承接,因为 PSync 协议并不可靠,当复制连接断开时,RedisShake 将无法重新连接至源端数据库。如果对于可用性要求不高,可以使用 `scan_reader`。如果写入量不大,且不存在大 key,也可以考虑 `scan_reader`。 -对于数据迁移场景,优先选择 `sync_reader`。一些云厂商没有提供 PSync 协议支持,可以选择`scan_reader`。 +不同模式各有优缺点,需要查看各 Reader 章节了解更多信息。 -对于长期的数据同步场景,RedisShake 目前没有能力承接,因为 PSync 协议并不可靠,当复制连接断开时,RedisShake 将无法重新连接至源端数据库。如果对于可用性要求不高,可以使用 `scan_reader`。如果写入量不大,且不存在大 key,也可以考虑 `scan_reader`。 +## Redis Cluster 架构 -不同模式各有优缺点,需要查看各 Reader 章节了解更多信息。 +当源端 Redis 以 cluster 架构部署时,可以使用 `sync_reader` 或者 `scan_reader`。两者配置项中均有开关支持开启 cluster 模式,会通过 `cluster nodes` 命令自动获取集群中的所有节点,并建立连接。 + +## Redis Sentinel 架构 + +当源端 Redis 以 sentinel 架构部署且 RedisShake 使用 `sync_reader` 连接主库时,会被主库当做 slave,从而有可能被 sentinel 选举为新的 master。 + +为了避免这种情况,应选择备库作为源端。 ## 云 Redis 服务 @@ -44,11 +54,6 @@ outline: deep 不方便提交工单时,可以使用 `scan_reader`。需要注意的是,`scan_reader` 会对源库造成较大的压力。 -## 自建 Redis 或 Redis-like 数据库 - -## Redis Sentinel 架构 - -当 Redis 以 sentinel 架构部署时,RedisShake 通过 PSync 协议连接主库会被认为是 slave,从而有可能被 sentinel 选举为新的 master。为了避免这种情况,应选择备库作为源端。 diff --git a/docs/src/zh/reader/rdb_reader.md b/docs/src/zh/reader/rdb_reader.md index 1865353..e2db740 100644 --- a/docs/src/zh/reader/rdb_reader.md +++ b/docs/src/zh/reader/rdb_reader.md @@ -11,3 +11,4 @@ filepath = "/tmp/dump.rdb" ``` +* 应传入绝对路径。 diff --git a/docs/src/zh/reader/scan_reader.md b/docs/src/zh/reader/scan_reader.md index 3abd2c1..ea99e26 100644 --- a/docs/src/zh/reader/scan_reader.md +++ b/docs/src/zh/reader/scan_reader.md @@ -2,32 +2,32 @@ ## 介绍 -当源端数据库不兼容 PSync 协议时,推荐使用 `scan_reader`。 +::: tip +本方案为次选方案,当可以使用 [`sync_reader`](sync_reader.md) 时,请优选 [`sync_reader`](sync_reader.md)。 +::: + +`scan_reader` 通过 `SCAN` 命令遍历源端数据库中的所有 Key,并使用 `DUMP` 与 `RESTORE` 命令来读取与写入 Key 的内容。 -优势:兼容性好,只要源端数据库支持 `SCAN` 与 `DUMP` 命令,就可以使用 `scan_reader`。 +注意: +1. Redis 的 `SCAN` 命令只保证 `SCAN` 的开始与结束之前均存在的 Key 一定会被返回,但是新写入的 Key 有可能会被遗漏,期间删除的 Key 也可能已经被写入目的端。可以通过 `ksn` 配置解决 +2. `SCAN` 命令与 `DUMP` 命令会占用源端数据库较多的 CPU 资源。 -劣势: -1. 数据一致性不如 [`sync_reader`](./sync_reader.md)。 -2. `SCAN` 命令与 `DUMP` 命令会占用源端数据库较多的 CPU 资源 ## 配置 ```toml [scan_reader] -cluster = false -address = "127.0.0.1:6379" # when cluster is true, address is one of the cluster node +cluster = false # set to true if source is a redis cluster +address = "127.0.0.1:6379" # when cluster is true, set address to one of the cluster node username = "" # keep empty if not using ACL password = "" # keep empty if no authentication is required +ksn = false # set to true to enabled Redis keyspace notifications (KSN) subscription tls = false -ksn = false ``` -默认情况下,RedisShake 会使用 `SCAN` 命令来遍历一遍所有的 Key,分别使用 `DUMP` 与 `RESTORE` 命令来从源端读取 Key -的内容,并写入目标端。Redis 的 SCAN 命令只保证 SCAN 的开始与结束之前均存在的 Key 一定会被返回,但是新写入的 Key 有可能会被遗漏。 - -如果需要提高数据一致性,可以开启 `ksn` 参数,这样 RedisShake 会在 `SCAN` -之前使用 [Redis keyspace notifications](https://redis.io/docs/manual/keyspace-notifications/) +* 当源端为集群时,配置 cluster 为 true,address 为集群中的任意一个节点即可。`scan_reader` 会通过 `cluster nodes` 命令自动获取集群中的所有节点,并建立连接获取数据。 +* 开启 `ksn` 参数后 RedisShake 会在 `SCAN` 之前使用 [Redis keyspace notifications](https://redis.io/docs/manual/keyspace-notifications/) 能力来订阅 Key 的变化。当 Key 发生变化时,RedisShake 会使用 `DUMP` 与 `RESTORE` 命令来从源端读取 Key 的内容,并写入目标端。 ::: warning Redis keyspace notifications 不会感知到 `FLUSHALL` 与 `FLUSHDB` 命令,因此在使用 `ksn` 参数时,需要确保源端数据库不会执行这两个命令。 diff --git a/docs/src/zh/reader/sync_reader.md b/docs/src/zh/reader/sync_reader.md index 16b8e06..b4407dc 100644 --- a/docs/src/zh/reader/sync_reader.md +++ b/docs/src/zh/reader/sync_reader.md @@ -9,15 +9,18 @@ * ElastiCache 部分兼容 * MemoryDB 部分兼容 -优势:数据一致性最佳,可以实现不停机的切换 +优势:数据一致性最佳,对源库影响小,可以实现不停机的切换 ## 配置 ```toml [sync_reader] -cluster = false -address = "127.0.0.1:6379" # when cluster is true, address is one of the cluster node +cluster = false # set to true if source is a redis cluster +address = "127.0.0.1:6379" # when cluster is true, set address to one of the cluster node username = "" # keep empty if not using ACL password = "" # keep empty if no authentication is required tls = false ``` + +* 当源端为集群时,配置 `cluster` 为 true,`address` 为集群中的任意一个节点即可。`sync_reader` 会通过 `cluster nodes` 命令获取集群中的所有节点信息,并建立连接获取数据。 + diff --git a/docs/src/zh/writer/redis_writer.md b/docs/src/zh/writer/redis_writer.md index 9d6fec1..f9f23ca 100644 --- a/docs/src/zh/writer/redis_writer.md +++ b/docs/src/zh/writer/redis_writer.md @@ -14,3 +14,6 @@ username = "" # keep empty if not using ACL password = "" # keep empty if no authentication is required tls = false ``` + +* 当目的端为集群时,配置 cluster 为 true,address 为集群中的任意一个节点即可。`redis_writer` 会通过 `cluster nodes` 命令获取集群中的所有节点,并建立连接。 +* 当目的端为集群时,应保证源端发过来的命令满足 [Key 的哈希值属于同一个 slot](https://redis.io/docs/reference/cluster-spec/#implemented-subset)。 \ No newline at end of file diff --git a/shake.toml b/shake.toml index 3a15fcf..6d3c5cd 100644 --- a/shake.toml +++ b/shake.toml @@ -2,25 +2,26 @@ function = "" [sync_reader] -cluster = false -address = "127.0.0.1:6379" +cluster = false # set to true if source is a redis cluster +address = "127.0.0.1:6379" # when cluster is true, set address to one of the cluster node username = "" # keep empty if not using ACL password = "" # keep empty if no authentication is required tls = false # [scan_reader] -# cluster = false -# address = "127.0.0.1:6379" +# cluster = false # set to true if source is a redis cluster +# address = "127.0.0.1:6379" # when cluster is true, set address to one of the cluster node # username = "" # keep empty if not using ACL # password = "" # keep empty if no authentication is required +# ksn = false # set to true to enabled Redis keyspace notifications (KSN) subscription # tls = false # [rdb_reader] # filepath = "/tmp/dump.rdb" [redis_writer] -cluster = false -address = "127.0.0.1:6380" +cluster = false # set to true if target is a redis cluster +address = "127.0.0.1:6380" # when cluster is true, set address to one of the cluster node username = "" # keep empty if not using ACL password = "" # keep empty if no authentication is required tls = false