介绍 (Introduction)
Redis is an in-memory, key-value data store known for its flexibility, performance, wide language support, and built-in features like replication. Replication is the practice of regularly copying data from one database to another in order to have a replica that always remains an exact duplicate of the primary instance. One common use of Redis replication is to migrate an existing Redis data store to a new server, as one might do when scaling up their infrastructure for better performance.
Redis是一个内存中的键值数据存储,以其灵活性,性能,广泛的语言支持以及诸如复制之类的内置功能而闻名。 复制是一种定期将数据从一个数据库复制到另一个数据库,以使副本始终始终与主实例完全相同的做法。 Redis复制的一种常见用法是将现有Redis数据存储迁移到新服务器,就像在扩展其基础架构以提高性能时可能所做的那样。
This tutorial outlines the process of using Redis’s built-in replication features to migrate data from one Ubuntu 18.04 server (the “source”) to another (the “target”). This involves making a few configuration changes to each server, setting the target server to function as a replica of the source, and then promoting the replica back to a primary after the migration is completed.
本教程概述了使用Redis的内置复制功能将数据从一台Ubuntu 18.04服务器(“源”)迁移到另一台(“目标”)的过程。 这涉及对每个服务器进行一些配置更改,将目标服务器设置为充当源服务器的副本,然后在迁移完成后将副本提升回主服务器。
先决条件 (Prerequisites)
To complete this tutorial, you will need:
要完成本教程,您将需要:
Two servers running Ubuntu 18.04. Each server should have a user configured with administrative privileges and a firewall set up with
ufw
. To set up this environment, follow our initial server setup guide for Ubuntu 18.04 for both servers.两台运行Ubuntu 18.04的服务器。 每个服务器应具有配置了管理权限的用户和使用
ufw
设置的防火墙。 要设置该环境,请针对两个服务器都遵循我们针对Ubuntu 18.04的初始服务器设置指南 。The latest version of Redis installed on each server. To set this up, follow our guide on How To Install Redis from Source on Ubuntu 18.04.
每台服务器上都安装了最新版本的Redis。 要进行此设置,请遵循有关如何在Ubuntu 18.04上从源安装Redis的指南。
步骤1 —(可选)使用示例数据加载源Redis实例 (Step 1 — (Optional) Loading Your Source Redis Instance with Sample Data)
This optional step involves loading your source Redis instance with some sample data so you can experiment with migrating data to your target instance. If you already have data that you want to migrate over to your target, you can move ahead to Step 2 which will go over how to back it up.
此可选步骤涉及使用一些示例数据加载源Redis实例,以便您可以尝试将数据迁移到目标实例。 如果已经有要迁移到目标的数据,则可以继续执行步骤2 ,该步骤将介绍如何备份数据。
To begin, connect to the Ubuntu server you’ll use as your source Redis instance as your non-root user:
首先,以非root用户身份连接到将用作源Redis实例的Ubuntu服务器:
ssh sammy@source_server_ip
ssh sammy @ source_server_ip
Then run the following command to access your Redis server:
然后运行以下命令来访问您的Redis服务器:
- redis-cli redis-cli
If you’ve configured your Redis server to require password authentication, run the auth
command followed by your Redis password:
如果已将Redis服务器配置为要求密码认证,请运行auth
命令,然后输入Redis密码:
auth source_redis_password
验证source_redis_password
Next, run the following commands. These will create a number of keys holding a few strings, a hash, a list, and a set:
接下来,运行以下命令。 这些将创建一些包含几个字符串,哈希,列表和集合的键:
- mset string1 "Redis" string2 "is" string3 "fun!" mset string1“ Redis” string2“是” string3“有趣!
- hmset hash1 field1 "Redis" field2 "is" field3 "fast!" hmset hash1 field1“ Redis” field2“ is” field3“ fast!”
- rpush list1 "Redis" "is" "feature-rich!" rpush list1“ Redis”“是”“功能丰富!”
- sadd set1 "Redis" "is" "free!" sadd set1“ Redis”“是”“免费!”
Additionally, run the following expire
commands to provide a few of these keys with a timeout. This will make them volatile, meaning that Redis will delete them after a specified amount of time (7500
seconds, in this case):
此外,运行以下expire
命令可为其中一些键提供超时。 这将使它们不稳定 ,这意味着Redis将在指定的时间段(在这种情况下为7500
秒)后删除它们:
- expire string2 7500 到期string2 7500
- expire hash1 7500 过期hash1 7500
- expire set1 7500 过期set1 7500
With that, you have some example data you can export to your target Redis instance. Keep the redis-cli
prompt open for now, since we will run a few more commands from it in the next step to back this data up.
这样,您就可以将示例数据导出到目标Redis实例。 暂时保持redis-cli
提示符为打开状态,因为在下一步中,我们将从中再运行一些命令来备份此数据。
步骤2 —备份源Redis实例 (Step 2 — Backing Up Your Source Redis Instance)
Any time you plan to move data from one server to another, there’s a risk that something could go wrong and you could lose data as a result. Even though this risk is small, we will use Redis’s bgsave
command to create a backup of your source Redis database in case you encounter an error during the replication process.
每当您计划将数据从一台服务器移动到另一台服务器时,都有可能出问题,并且可能因此而丢失数据。 即使这种风险很小,我们也将使用Redis的bgsave
命令创建源Redis数据库的备份,以防在复制过程中遇到错误。
If you don’t already have it open, start by opening up the Redis command line interface:
如果尚未打开它,请先打开Redis命令行界面:
- redis-cli redis-cli
Also, if you’ve configured your Redis server to require password authentication, run the auth
command followed by your Redis password:
另外,如果您已将Redis服务器配置为要求密码认证,请运行auth
命令,然后输入Redis密码:
auth password
验证密码
Next, run the bgsave
command. This will create a snapshot of your current data set and export it to a dump file held in Redis’s working directory:
接下来,运行bgsave
命令。 这将创建当前数据集的快照,并将其导出到Redis工作目录中保存的转储文件:
- bgsave 储存
Note: You can take a snapshot of your Redis database with either the save
or bgsave
commands. The reason we use the bgsave
command here, though, is that the save
command runs synchronously, meaning it will block any other clients connected to the database. Because of this, the save
command documentation recommends that you should almost never run it in a production environment.
注意:您可以使用save
或bgsave
命令为Redis数据库创建快照。 但是,我们在这里使用bgsave
命令的原因是save
命令是同步运行的,这意味着它将阻止连接到数据库的任何其他客户端。 因此, save
命令文档建议您几乎永远不要在生产环境中运行它。
Instead, it suggests using the bgsave
command which runs asynchronously. This will cause Redis to fork the database into two processes: the parent process will continue to serve clients while the child saves the database before exiting:
相反,它建议使用异步运行的bgsave
命令。 这将导致Redis将数据库分叉到两个进程中:父进程将继续为客户端提供服务,而子进程将在退出之前保存数据库:
Note that if clients add or modify data while the bgsave
operation is running, these changes won’t be captured in the snapshot.
请注意,如果客户端在bgsave
操作运行时添加或修改数据,则这些更改将不会捕获到快照中。
Following that, you can close the connection to your Redis instance by running the exit
command:
然后,您可以通过运行exit
命令关闭与Redis实例的连接:
- exit 出口
If you need it in the future, you can find the data dump file in your Redis instance’s working directory. Recall how in the prerequisite Redis installation tutorial you set your Redis instance to use /var/lib/redis
as its working directory.
如果将来需要,可以在Redis实例的工作目录中找到数据转储文件。 回想一下在必备的Redis安装教程中如何将Redis实例设置为使用/var/lib/redis
作为其工作目录。
List the contents of your Redis working directory to confirm that it’s holding the data dump file:
列出您的Redis工作目录的内容,以确认该目录是否包含数据转储文件:
- sudo ls /var/lib/redis 须藤ls / var / lib / redis
If the dump file was exported correctly, you will see it in this command’s output. By default, this file is named dump.rdb
:
如果转储文件已正确导出,您将在此命令的输出中看到它。 默认情况下,该文件名为dump.rdb
:
Output
dump.rdb
After confirming that your data was backed up correctly, you’re all set to configure your source Redis server to accept external connections and allow for replication.
在确认您的数据已正确备份之后,就可以将源Redis服务器配置为接受外部连接并允许复制。
步骤3 —配置源Redis实例 (Step 3 — Configuring Your Source Redis Instance)
By default, Redis isn’t configured to listen for external connections, meaning that any replicas you configure won’t be able to sync with your source instance unless you update its configuration. Here, we will update the source instance’s configuration file to allow for external connections and also set a password which the target instance will use to authenticate once replication begins. After that, we’ll add a firewall rule to allow connections to the port on which Redis is running.
默认情况下,Redis未配置为侦听外部连接,这意味着您配置的任何副本都将无法与源实例同步,除非您更新其配置。 在这里,我们将更新源实例的配置文件以允许外部连接,并设置一个密码,复制开始后目标实例将使用该密码进行身份验证。 之后,我们将添加防火墙规则以允许连接到运行Redis的端口。
Open up your source Redis instance’s configuration file with your preferred text editor. Here, we’ll use nano
:
使用首选的文本编辑器打开源Redis实例的配置文件。 在这里,我们将使用nano
:
- sudo nano /etc/redis/redis.conf 须藤nano /etc/redis/redis.conf
Navigate to the line that begins with the bind
directive. It will look like this by default:
导航到以bind
指令开头的行。 默认情况下如下所示:
. . .
bind 127.0.0.1
. . .
This directive binds Redis to 127.0.0.1
, an IPv4 loopback address that represents localhost
. This means that this Redis instance is configured to only listen for connections that originate from the same server as the one where it’s installed. To allow your source instance to accept any connection made to its public IP address, such as those made from your target instance, add your source Redis server’s IP address after the 127.0.0.1
. Note that you shouldn’t include any commas after 127.0.0.1
:
该指令将Redis绑定到127.0.0.1
,这是一个表示localhost
的IPv4回送地址。 这意味着该Redis实例配置为仅侦听与安装它的服务器来自同一服务器的连接。 要允许源实例接受与其公用IP地址建立的任何连接,例如从目标实例建立的连接,请在127.0.0.1
之后添加源Redis服务器的IP地址。 请注意,在127.0.0.1
之后,您不应包含任何逗号:
. . .
bind 127.0.0.1 source_server_IP
. . .
Next, if you haven’t already done so, use the requirepass
directive to configure a password which users must enter before they can interact with the data on the source instance. Do so by uncommenting the directive and setting it to a complex password or passphrase:
接下来,如果尚未执行此操作,请使用requirepass
指令来配置用户在与源实例上的数据进行交互之前必须输入的密码。 通过取消注释指令并将其设置为复杂的密码或密码短语,可以做到这一点:
. . .
requirepass source_redis_password
. . .
Be sure to take note of the password you set here, as you will need it when you configure the target server.
确保记下您在此处设置的密码,因为在配置目标服务器时将需要它。
Following that change, you can save and close the Redis configuration file. If you edited it with nano
, do so by pressing CTRL+X
, Y
, then ENTER
.
进行此更改后,您可以保存并关闭Redis配置文件。 如果您使用nano
编辑,请按CTRL+X
, Y
,然后按ENTER
。
Then, restart the Redis service to put these changes into effect:
然后,重新启动Redis服务以使这些更改生效:
- sudo systemctl restart redis sudo systemctl重新启动redis
That’s all you need to do in terms of configuring Redis, but if you configured a firewall on your server it will continue to block any attempts by your target server to connect with the source. Assuming you configured your firewall with ufw
, you could update it to allow connections to the port on which Redis is running with the following command. Note that Redis is configured to use port 6379
by default:
这就是配置Redis所需要做的一切,但是如果您在服务器上配置了防火墙,它将继续阻止目标服务器与源连接的任何尝试。 假设您使用ufw
配置了防火墙,则可以使用以下命令对其进行更新,以允许连接到运行Redis的端口。 请注意,默认情况下,Redis配置为使用端口6379
:
sudo ufw allow 6379
须藤ufw允许6379
After making that final change you’re all done configuring your source Redis server. Continue on to configure your target Redis instance to function as a replica of the source.
完成最终更改后,就可以完成对源Redis服务器的配置。 继续将目标Redis实例配置为充当源的副本。
步骤4 —配置目标Redis实例 (Step 4 — Configuring your Target Redis Instance)
By this point you’ve configured your source Redis instance to accept external connections. However, because you’ve locked down access to the source by uncommenting the requirepass
directive, your target instance won’t be able to replicate the data held on the source. Here, you will configure your target Redis instance to be able to authenticate its connection to the source, thereby allowing replication.
至此,您已经将源Redis实例配置为接受外部连接。 但是,由于已通过取消注释requirepass
指令来锁定对源的访问,因此目标实例将无法复制源中保存的数据。 在这里,您将配置目标Redis实例以能够验证其与源的连接,从而允许复制。
Begin by connecting to your target Redis server as your non-root user:
首先以非root用户身份连接到目标Redis服务器:
ssh sammy@target_server_ip
ssh sammy @ target_server_ip
Next, open up your target server’s Redis configuration file:
接下来,打开目标服务器的Redis配置文件:
- sudo nano /etc/redis/redis.conf 须藤nano /etc/redis/redis.conf
If you haven’t done so already, you should configure a password for your target Redis instance with the requirepass
directive:
如果尚未这样做,则应使用requirepass
指令为目标Redis实例配置密码:
. . .
requirepass target_redis_password
. . .
Next, uncomment the masterauth
directive and set it to your source Redis instance’s authentication password. By doing this, your target server will be able to authenticate to the source instance after you enable replication:
接下来,取消注释masterauth
指令,并将其设置为源Redis实例的身份验证密码。 这样,您的目标服务器将能够在启用复制后向源实例进行身份验证:
. . .
masterauth source_redis_password
. . .
Lastly, if you have clients writing information to your source instance, you will want to configure them to write data to your target instance as well. This way, if a client writes any data after you promote the target back to being a primary instance, it won’t get lost.
最后,如果您有客户端将信息写入源实例,则需要配置它们以将数据也写入目标实例。 这样,如果客户端在将目标提升回为主实例后写入任何数据,则不会丢失。
To do this, though, you will need to adjust the replica-read-only
directive. This is set to yes
by default, which means that it’s configured to become a “read-only” replica which clients won’t be able to write to. Set this directive to no
to allow clients to write to it:
但是,为此,您将需要调整“ replica-read-only
指令。 默认情况下,此选项设置为yes
,这意味着它已配置为成为客户端无法写入的“只读”副本。 将此指令设置为no
以允许客户端对其进行写入:
. . .
replica-read-only no
. . .
Those are all the changes you need to make to the target’s configuration file, so you can save and close it.
这些就是您需要对目标的配置文件进行的所有更改,因此您可以保存并关闭它。
Then, restart the Redis service to put these changes into effect:
然后,重新启动Redis服务以使这些更改生效:
- sudo systemctl restart redis sudo systemctl重新启动redis
After restarting the Redis service your target server will be ready to become a replica of the source. All you’ll need to do to turn it into one is to run a single command, which we’ll do shortly.
重新启动Redis服务后,您的目标服务器将准备好成为源的副本。 将其转换为一个命令所需要做的就是运行一个命令,稍后我们将做。
Note: If you have any clients writing data to your source Redis instance, now would be a good time to configure them to also write data to your target.
注意:如果有任何客户端将数据写入源Redis实例,现在是配置它们也将数据写入目标的好时机。
步骤5 —启动和验证复制 (Step 5 — Starting and Verifying Replication)
By this point, you have configured your source Redis instance to accept connections from your target server and you’ve configured your target Redis instance to be able to authenticate to the source as a replica. With these pieces in place, you’re ready to turn your target instance into a replica of the source.
至此,您已将源Redis实例配置为接受来自目标服务器的连接,并且已将目标Redis实例配置为能够作为副本身份验证源。 准备好这些片段后,您就可以将目标实例转换为源副本了。
Begin by opening up the Redis command line interface on your target Redis server:
首先在目标Redis服务器上打开Redis命令行界面:
- redis-cli redis-cli
Run the auth
command to authenticate the connection:
运行auth
命令以验证连接:
auth password
验证密码
Next, turn the target instance into a replica of the source with the replicaof
command. Be sure to replace source_server_ip
with your source instance’s public IP address and source_port
with the port used by Redis on your source instance:
接下来,使用replicaof
命令将目标实例转换为源实例的副本。 确保用源实例的公共IP地址替换source_server_ip
并用源实例上Redis使用的端口替换source_port
:
replicaof source_server_ip source_port
source_server_ip source_port的副本
From the prompt, run the following scan
command. This will return all the keys currently held by the replica:
在提示符下,运行以下scan
命令。 这将返回副本当前持有的所有密钥:
- scan 0 扫描0
If replication is working as expected, you will see all the keys from your source instance held in the replica. If you loaded your source with the sample data in Step 1, the scan
command’s output will look like this:
如果复制按预期工作,则您将看到源实例中所有密钥的副本。 如果在步骤1中将示例数据加载到源中,则scan
命令的输出将如下所示:
Output
1) "0"
2) 1) "string3"
2) "string1"
3) "set1"
4) "string2"
5) "hash1"
6) "list1"
Note: Be aware that this command may return the keys in a different order than what’s shown in this example.
注意:请注意,此命令可能以与本示例中所示顺序不同的顺序返回键。
However, if this command doesn’t return the same keys held on your source Redis instance, it may be that there is an error in one of your servers’ configuration files preventing the target database from connecting to the source. In this case, close the connection to your target Redis instance, and double check that you’ve edited the configuration files on both your source and target Redis servers correctly.
但是,如果此命令未返回源Redis实例上保存的相同键,则可能是服务器的一个配置文件中存在错误,导致目标数据库无法连接到源。 在这种情况下,请关闭与目标Redis实例的连接,然后再次检查您是否已正确编辑源Redis服务器和目标Redis服务器上的配置文件。
While you have the connection open, you can also confirm that the keys you set to expire are still volatile. Do so by running the ttl
command with one of these keys as an argument:
打开连接后,您还可以确认设置为过期的密钥仍然不稳定。 通过使用以下键之一作为参数运行ttl
命令来执行此操作:
ttl hash1
ttl hash1
This will return the number of seconds before this key will be deleted:
这将返回删除该密钥之前的秒数:
Output
5430
Once you’ve confirmed that the data on your source instance was correctly synced to your target, you can promote the target back to being a primary instance by running the replicaof
command once again. This time, however, instead of following replicaof
with an IP address and port, follow it with no one
. This will cause the target instance to stop syncing with the source immediately:
一旦确认源实例上的数据已正确同步到目标,就可以通过再次运行replicaof
命令将目标提升回主实例。 然而这一次,而不是跟随replicaof
的IP地址和端口,以遵循它no one
。 这将导致目标实例立即停止与源实例同步:
- replicaof no one 没有人的复制品
To confirm that the data replicated from the source persist on the target, rerun the scan
command you entered previously:
要确认从源复制的数据仍保留在目标上,请重新运行之前输入的scan
命令:
scan 0
You should see the same keys in this command’s output as when you ran the scan
command when the target was still replicating the source:
当目标仍在复制源时,您应该在此命令的输出中看到与运行scan
命令时相同的键:
Output
1) "0"
2) 1) "string3"
2) "string1"
3) "set1"
4) "string2"
5) "hash1"
6) "list1"
With that, you’ve successfully migrated all the data from your source Redis instance to your target. If you have any clients that are still writing data to the source instance, now would be a good time to configure them to only write to the target.
这样,您就成功地将所有数据从源Redis实例迁移到了目标。 如果您有任何客户端仍在将数据写入源实例,现在是将它们配置为仅写入目标实例的好时机。
结论 (Conclusion)
There are several methods besides replication you can use to migrate data from one Redis instance to another, but replication has the advantages of requiring relatively few configuration changes to work and only a single command to initiate or stop.
除了复制外,还有多种方法可用于将数据从一个Redis实例迁移到另一个实例,但是复制的优点是需要进行相对较少的配置更改,并且只需要一个命令即可启动或停止。
If you’d like to learn more about working with Redis, we encourage you to check out our tutorial series on How To Manage a Redis Database. Also, if you want to move your Redis data to a Redis instance managed by DigitalOcean, follow our guide on how to do so.
如果您想了解有关使用Redis的更多信息,我们建议您阅读有关如何管理Redis数据库的教程系列。 另外,如果要将Redis数据移动到DigitalOcean管理的Redis实例,请按照我们的指南进行操作 。
翻译自: https://www.digitalocean.com/community/tutorials/how-to-migrate-redis-data-with-replication-ubuntu-18-04