如何在Ubuntu18.04上通过复制迁移Redis数据

来自菜鸟教程
跳转至:导航、​搜索

介绍

Redis 是一种内存中的键值数据存储,以其灵活性、性能、广泛的语言支持和 复制 等内置功能而闻名。 复制是定期将数据从一个数据库复制到另一个数据库的做法,以便拥有始终保持与主实例完全相同的副本。 Redis 复制的一个常见用途是将现有的 Redis 数据存储迁移到新服务器,就像在扩展其基础架构以获得更好的性能时所做的那样。

本教程概述了使用 Redis 的内置复制功能将数据从一个 Ubuntu 18.04 服务器(“源”)迁移到另一个(“目标”)的过程。 这包括对每台服务器进行一些配置更改,将目标服务器设置为源服务器的副本,然后在迁移完成后将副本提升回主服务器。

先决条件

要完成本教程,您需要:

  • 两台运行 Ubuntu 18.04 的服务器。 每个服务器都应该有一个配置有管理权限的用户和一个使用 ufw 设置的防火墙。 要设置此环境,请按照我们的 两个服务器的 Ubuntu 18.04 初始服务器设置指南进行操作。
  • 每台服务器上安装的最新版本的 Redis。 要进行此设置,请按照我们关于 如何在 Ubuntu 18.04 上从源代码安装 Redis 的指南进行操作。

第 1 步 - (可选)使用示例数据加载源 Redis 实例

此可选步骤涉及使用一些示例数据加载源 Redis 实例,以便您可以尝试将数据迁移到目标实例。 如果您已经有要迁移到目标的数据,您可以继续进行 步骤 2,其中将介绍如何备份它。

首先,以非 root 用户身份连接到您将用作源 Redis 实例的 Ubuntu 服务器:

ssh sammy@source_server_ip

然后运行以下命令访问您的 Redis 服务器:

redis-cli

如果您已将 Redis 服务器配置为需要密码验证,请运行 auth 命令,然后输入您的 Redis 密码:

auth source_redis_password

接下来,运行以下命令。 这些将创建一些键,其中包含一些字符串、一个哈希、一个列表和一个集合:

mset string1 "Redis" string2 "is" string3 "fun!"
hmset hash1 field1 "Redis" field2 "is" field3 "fast!"
rpush list1 "Redis" "is" "feature-rich!"
sadd set1 "Redis" "is" "free!"

此外,运行以下 expire 命令为其中一些键提供超时。 这将使它们变为 volatile,这意味着 Redis 将在指定的时间量(在本例中为 7500 秒)后删除它们:

expire string2 7500
expire hash1 7500
expire set1 7500

这样,您就有了一些可以导出到目标 Redis 实例的示例数据。 暂时保持 redis-cli 提示符打开,因为我们将在下一步中运行更多命令来备份这些数据。

第 2 步 — 备份您的源 Redis 实例

每当您计划将数据从一台服务器移动到另一台服务器时,都有可能出现问题并因此丢失数据。 即使这种风险很小,我们也会使用 Redis 的 bgsave 命令为您的源 Redis 数据库创建备份,以防您在复制过程中遇到错误。

如果你还没有打开它,首先打开 Redis 命令行界面:

redis-cli

此外,如果您已将 Redis 服务器配置为需要密码验证,请运行 auth 命令,后跟您的 Redis 密码:

auth password

接下来,运行 bgsave 命令。 这将创建当前数据集的快照并将其导出到 Redis 工作目录中保存的转储文件中:

bgsave

注意: 您可以使用 savebgsave 命令对 Redis 数据库进行快照。 但是,我们在这里使用 bgsave 命令的原因是 save 命令同步运行 ',这意味着它将阻止任何其他连接到数据库的客户端。 因此,save 命令文档 建议您几乎不要在生产环境中运行它。

相反,它建议使用异步运行 'bgsave 命令。 这将导致 Redis 将数据库分叉为两个进程:父进程将继续为客户端提供服务,而子进程将在退出前保存数据库:

请注意,如果客户端在 bgsave 操作运行时添加或修改数据,这些更改将不会在快照中捕获。


之后,您可以通过运行 exit 命令关闭与 Redis 实例的连接:

exit

如果以后需要,可以在 Redis 实例的工作目录中找到数据转储文件。 回想一下在 先决条件 Redis 安装教程 中如何将 Redis 实例设置为使用 /var/lib/redis 作为其工作目录。

列出您的 Redis 工作目录的内容,以确认它包含数据转储文件:

sudo ls /var/lib/redis

如果转储文件已正确导出,您将在此命令的输出中看到它。 默认情况下,此文件名为 dump.rdb

Outputdump.rdb

确认您的数据已正确备份后,您就可以将源 Redis 服务器配置为接受外部连接并允许复制。

第 3 步 — 配置您的源 Redis 实例

默认情况下,Redis 未配置为侦听外部连接,这意味着您配置的任何副本都无法与源实例同步,除非您更新其配置。 在这里,我们将更新源实例的配置文件以允许外部连接,并设置一个密码,一旦复制开始,目标实例将使用该密码进行身份验证。 之后,我们将添加一条防火墙规则以允许连接到运行 Redis 的端口。

使用您喜欢的文本编辑器打开源 Redis 实例的配置文件。 在这里,我们将使用 nano

sudo nano /etc/redis/redis.conf

导航到以 bind 指令开头的行。 默认情况下它看起来像这样:

/etc/redis/redis.conf

. . .
bind 127.0.0.1
. . .

该指令将 Redis 绑定到 127.0.0.1,这是一个表示 localhost 的 IPv4 环回地址。 这意味着此 Redis 实例配置为仅侦听源自与其安装所在服务器相同的服务器的连接。 要允许您的源实例接受与其公共 IP 地址建立的任何连接,例如从您的目标实例建立的连接,请在 127.0.0.1 之后添加您的源 Redis 服务器的 IP 地址。 请注意,您不应在 127.0.0.1 之后包含任何逗号:

/etc/redis/redis.conf

. . .
bind 127.0.0.1 source_server_IP
. . .

接下来,如果您还没有这样做,请使用 requirepass 指令配置用户在与源实例上的数据交互之前必须输入的密码。 通过取消注释指令并将其设置为复杂的密码或密码来做到这一点:

/etc/redis/redis.conf

. . .
requirepass source_redis_password
. . .

请务必记下您在此处设置的密码,因为您在配置目标服务器时将需要它。

进行该更改后,您可以保存并关闭 Redis 配置文件。 如果您使用 nano 对其进行编辑,请按 CTRL+XY,然后按 ENTER 进行编辑。

然后,重新启动 Redis 服务以使这些更改生效:

sudo systemctl restart redis

这就是配置 Redis 所需要做的所有事情,但是如果您在服务器上配置了防火墙,它将继续阻止目标服务器与源连接的任何尝试。 假设您使用 ufw 配置了防火墙,您可以使用以下命令对其进行更新以允许连接到运行 Redis 的端口。 请注意,Redis 默认配置为使用端口 6379

sudo ufw allow 6379

在进行最后的更改之后,您就完成了对源 Redis 服务器的配置。 继续配置您的目标 Redis 实例以用作源的副本。

第 4 步 — 配置您的目标 Redis 实例

至此,您已将源 Redis 实例配置为接受外部连接。 但是,由于您已通过取消注释 requirepass 指令来锁定对源的访问,因此您的目标实例将无法复制源中保存的数据。 在这里,您将配置您的目标 Redis 实例,使其能够验证其与源的连接,从而允许复制。

首先以非 root 用户身份连接到目标 Redis 服务器:

ssh sammy@target_server_ip

接下来,打开目标服务器的 Redis 配置文件:

sudo nano /etc/redis/redis.conf

如果您还没有这样做,您应该使用 requirepass 指令为您的目标 Redis 实例配置密码:

/etc/redis/redis.conf

. . .
requirepass target_redis_password
. . .

接下来,取消注释 masterauth 指令并将其设置为您的源 Redis 实例的身份验证密码。 通过这样做,您的目标服务器将能够在启用复制后对源实例进行身份验证:

/etc/redis/redis.conf

. . .
masterauth source_redis_password
. . .

最后,如果您有客户端将信息写入源实例,您将需要配置它们以将数据也写入目标实例。 这样,如果客户端在您将目标提升回主实例后写入任何数据,它就不会丢失。

但是,为此,您需要调整 replica-read-only 指令。 默认设置为 yes,这意味着它被配置为客户端无法写入的“只读”副本。 将此指令设置为 no 以允许客户端对其进行写入:

/etc/redis/redis.conf

. . .
replica-read-only no
. . .

这些是您需要对目标的配置文件进行的所有更改,因此您可以保存并关闭它。

然后,重新启动 Redis 服务以使这些更改生效:

sudo systemctl restart redis

重新启动 Redis 服务后,您的目标服务器将准备好成为源的副本。 要将它变成一个命令,您需要做的就是运行一个命令,我们很快就会这样做。

注意: 如果您有任何客户端将数据写入源 Redis 实例,现在是配置它们以也将数据写入目标的好时机。


第 5 步 — 启动和验证复制

至此,您已将源 Redis 实例配置为接受来自目标服务器的连接,并且您已将目标 Redis 实例配置为能够作为副本向源进行身份验证。 有了这些部分,您就可以将目标实例转换为源实例的副本了。

首先在目标 Redis 服务器上打开 Redis 命令行界面:

redis-cli

运行 auth 命令验证连接:

auth password

接下来,使用 replicaof 命令将目标实例变为源实例的副本。 请务必将 source_server_ip 替换为源实例的公共 IP 地址,将 source_port 替换为 Redis 在源实例上使用的端口:

replicaof source_server_ip source_port

在提示符下,运行以下 scan 命令。 这将返回副本当前持有的所有密钥:

scan 0

如果复制按预期工作,您将看到来自源实例的所有密钥都保存在副本中。 如果您在步骤 1 中使用示例数据加载源,scan 命令的输出将如下所示:

Output1) "0"
2) 1) "string3"
   2) "string1"
   3) "set1"
   4) "string2"
   5) "hash1"
   6) "list1"

注意: 请注意,此命令可能会以与此示例中显示的顺序不同的顺序返回键。

但是,如果此命令未返回源 Redis 实例上保存的相同密钥,则可能是您的服务器配置文件之一中存在错误,导致目标数据库无法连接到源。 在这种情况下,请关闭与目标 Redis 实例的连接,并仔细检查您是否已正确编辑源 Redis 服务器和目标 Redis 服务器上的配置文件。


当您打开连接时,您还可以确认您设置为过期的密钥仍然是不稳定的。 通过使用以下键之一作为参数运行 ttl 命令来执行此操作:

ttl hash1

这将返回删除此键之前的秒数:

Output5430

确认源实例上的数据已正确同步到目标后,您可以通过再次运行 replicaof 命令将目标提升为主实例。 但是,这一次,不是在 replicaof 后面加上 IP 地址和端口,而是在 no one 后面跟着它。 这将导致目标实例立即停止与源同步:

replicaof no one

要确认从源复制的数据是否保留在目标上,请重新运行您之前输入的 scan 命令:

scan 0

您应该在此命令的输出中看到与在目标仍在复制源时运行 scan 命令时相同的键:

Output1) "0"
2) 1) "string3"
   2) "string1"
   3) "set1"
   4) "string2"
   5) "hash1"
   6) "list1"

至此,您已成功将所有数据从源 Redis 实例迁移到目标。 如果您有任何客户端仍在将数据写入源实例,那么现在是将它们配置为仅写入目标的好时机。

结论

除了复制之外,您还可以使用多种方法将数据从一个 Redis 实例迁移到另一个实例,但复制的优点是需要相对较少的配置更改即可工作,并且只需一个命令即可启动或停止。

如果您想了解有关使用 Redis 的更多信息,我们鼓励您查看我们关于 如何管理 Redis 数据库 的教程系列。 此外,如果您想将 Redis 数据移动到由 DigitalOcean 管理的 Redis 实例,请按照我们的 指南进行操作