如何在Ubuntu16.04上配置Redis复制

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

介绍

Redis 是一个开源的键值对数据存储,使用内存存储模型和可选的磁盘写入来实现持久性。 它具有事务、发布/订阅消息模式和自动故障转移等功能。 Redis 有用大多数语言编写的客户端, 他们的网站 上有推荐的客户端。

对于生产环境,跨至少两个节点复制数据被认为是最佳实践。 这允许在环境故障的情况下进行恢复,这在应用程序的用户群增长时尤其重要。 它还允许您安全地与生产数据交互,而无需修改它或影响性能。

在本指南中,我们将在运行 Ubuntu 16.04 的两台服务器之间配置复制。 如果需要,这个过程可以很容易地适应更多的服务器。

先决条件

为了完成本指南,您需要访问两台 Ubuntu 16.04 服务器。 根据 Redis 使用的术语,我们将负责接受写入请求的主服务器称为 master 服务器,将辅助只读服务器称为 slave 服务器。

您应该在每个服务器上配置一个具有 sudo 权限的非 root 用户。 此外,本指南将假设您有一个基本的防火墙。 您可以按照我们的 Ubuntu 16.04 初始服务器设置指南 来满足这些要求。

当您准备好开始时,请继续阅读本指南。

第 1 步:安装 Redis

首先,我们将在 masterslave 服务器上安装 Redis。

我们将使用 Chris Lea 的 Redis PPA 安装最新的 Redis 服务器包。 启用第三方存储库时请务必小心。 在这种情况下,Chris Lea 是一位知名的包装商,他维护着许多高质量的包装。

首先,将 PPA 添加到您的两台服务器:

sudo apt-add-repository ppa:chris-lea/redis-server

ENTER 接受存储库。

接下来,更新服务器的本地包索引并通过键入以下命令安装 Redis 服务器包:

sudo apt-get update
sudo apt-get install redis-server

这将安装 Redis 服务器并启动服务。

通过键入以下内容检查 Redis 是否已启动并正在运行:

redis-cli ping

您应该收到以下回复:

OutputPONG

这表明 Redis 正在运行并且本地客户端可以访问。

第 2 步:保护两台服务器之间的流量

在设置复制之前,了解 Redis 安全模型的含义很重要。 Redis 不提供本机加密选项,并假定它已部署到受信任对等点的专用网络。

如果 Redis 部署到隔离网络……

如果您的服务器在隔离网络中运行,您可能只需要调整 Redis 的配置文件以绑定到您的隔离网络 IP 地址。

在每台计算机上打开 Redis 配置文件:

sudo nano /etc/redis/redis.conf

找到 bind 行并附加服务器自己的隔离网络 IP 地址:

/etc/redis/redis.conf

bind 127.0.0.1 isolated_IP_address

保存并关闭文件。 通过键入以下内容重新启动服务:

sudo systemctl restart redis-server.service

打开对 Redis 端口的访问:

sudo ufw allow 6379

您现在应该能够通过将备用服务器的 IP 地址提供给带有 -h 标志的 redis-cli 命令来从另一台服务器访问:

redis-cli -h isolated_IP_address ping
OutputPONG

Redis 现在能够接受来自隔离网络的连接。

如果 Redis 没有部署到隔离网络……

对于未隔离或您无法控制的网络,必须通过其他方式保护流量。 有许多选项可以保护 Redis 服务器之间的流量,包括:

  • 使用 stunnel 建立隧道:您需要为每个服务器建立一个传入和传出隧道。 指南底部有一个示例。
  • 使用 spiped 建立隧道:您需要为每个服务器创建两个 systemd 单元文件,一个用于与远程服务器通信,另一个用于将连接转发到其自己的 Redis 进程。 详细信息包含在指南的底部。
  • 使用 PeerVPN 设置 VPN:两台服务器都需要在 VPN 上可访问。

使用上述方法之一,在您的 Redis 主从服务器之间建立安全的通信方法。 您应该知道每台机器安全连接到其对等机上的 Redis 服务所需的 IP 地址和端口。

第三步:配置 Redis Master

现在 Redis 已在每台服务器上启动并运行,并且已经建立了安全的通信通道,我们必须编辑它们的配置文件。 让我们从充当 master 的服务器开始。

使用您喜欢的文本编辑器打开 /etc/redis/redis.conf

sudo nano /etc/redis/redis.conf

首先找到 tcp-keepalive 设置并将其设置为 60 秒,如评论建议的那样。 这将帮助 Redis 检测网络或服务问题:

/etc/redis/redis.conf

. . .
tcp-keepalive 60
. . .

找到 requirepass 指令并将其设置为强密码。 虽然您的 Redis 流量应该不受外部各方的影响,但这为 Redis 本身提供了身份验证。 由于 Redis 速度很快并且不会限制密码尝试,因此请选择一个强大、复杂的密码来防止暴力尝试:

/etc/redis/redis.conf

requirepass your_redis_master_password

最后,您可能希望根据您的使用场景调整一些可选设置。

如果您不希望 Redis 在填满时自动修剪旧的和较少使用的密钥,您可以关闭自动密钥驱逐:

/etc/redis/redis.conf

maxmemory-policy noeviction

为了提高持久性保证,您可以打开仅附加文件持久性。 这将有助于在系统发生故障时最大限度地减少数据丢失,但会以更大的文件和稍慢的性能为代价:

/etc/redis/redis.conf

appendonly yes
appendfilename "redis-staging-ao.aof"

完成后,保存并关闭文件。

重新启动 Redis 服务以重新加载我们的配置更改:

sudo systemctl restart redis-server.service

现在主服务器已配置,请花点时间对其进行测试。

第 4 步:测试 Redis Master

通过启动 Redis 客户端检查您是否可以使用您设置的密码进行身份验证:

redis-cli

首先,在不进行身份验证的情况下尝试一个命令:

info replication

您应该得到以下响应:

Redis master outputNOAUTH Authentication required.

这是意料之中的,表明我们的 Redis 服务器正确拒绝了未经身份验证的请求。

接下来,使用 auth 命令进行身份验证:

auth your_redis_master_password

您应该会收到您的凭据已被接受的确认信息:

Redis master outputOK

如果再次尝试该命令,这次应该会成功:

info replication
Redis master output# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

当您通过身份验证时,设置一个测试密钥,以便我们稍后可以检查复制:

set test 'this key was defined on the master server'

完成后退出操作系统 shell:

exit

现在我们已经准备好了主服务器,让我们继续我们的从机。

第 5 步:配置 Redis 从站

接下来,我们需要进行一些更改以允许我们的 从服务器 连接到我们的主实例。

在从服务器上打开/etc/redis/redis.conf

sudo nano /etc/redis/redis.conf

首先,找到并取消注释 slaveof 行。 该指令采用您用来安全联系主 Redis 服务器的 IP 地址和端口,以空格分隔。 默认情况下,Redis 服务器在本地接口上侦听 6379,但每种网络安全方法都会以某种方式为外部各方修改默认值。

您使用的值取决于您用于保护网络流量的方法:

  • 隔离网络:使用主服务器的隔离网络IP地址和Redis端口(6379)(例如slaveof isolated_IP_address 6379)。
  • stunnelspiped:使用本地接口 (127.0.0.1) 和配置为隧道流量的端口(如果您按照指南操作,则为 slaveof 127.0.0.1 8000)。
  • PeerVPN:使用主服务器的 VPN IP 地址和常规 Redis 端口(如果您按照指南操作,则为 slaveof 10.8.0.1 6379)。

一般形式为:

/etc/redis/redis.conf

slaveof ip_to_contact_master port_to_contact_master

接下来,取消注释并使用为 Redis 主服务器设置的密码填写 masterauth 行:

/etc/redis/redis.conf

masterauth your_redis_master_password

为您的从服务器设置密码以防止未经授权的访问。 关于密码复杂性的相同警告也适用于此处:

/etc/redis/redis.conf

requirepass your_redis_slave_password

完成后保存并关闭文件。

第 6 步:测试 Redis 从站并应用更改

在我们重新启动服务以实现我们的更改之前,让我们连接到从机上的本地 Redis 实例并验证 test 键是否未设置:

redis-cli

通过键入以下内容查询密钥:

get test

您应该得到以下响应:

Redis slave output(nil)

这表明本地 Redis 实例没有名为 test 的键。 键入以下命令退出到 shell:

exit

重启slave上的Redis服务来实现这些改变:

sudo systemctl restart redis-server.service

这将应用我们对 Redis 从配置文件所做的所有更改。

再次重新连接到本地 Redis 实例:

redis-cli

与 Redis 主服务器一样,如果未经授权,操作现在应该会失败:

get test
Redis slave output(error) NOAUTH Authentication required.

现在,使用您在上一节中设置的 Redis 从站密码进行身份验证:

auth your_redis_slave_password
Redis slave outputOK

如果我们这次尝试访问密钥,我们会发现它是可用的:

get test
Redis slave output"this key was defined on the master server"

一旦我们在从属服务器上重新启动我们的 Redis 服务,复制就会立即开始。

您可以使用 Redis 的 info 命令验证这一点,该命令报告有关复制的信息。 master_hostmaster_port 的值应该与您用于 slaveof 选项的参数匹配:

info replication
Redis slave output# Replication
role:slave
master_host:10.8.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:1387
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

如果您碰巧在 Redis 主服务器上查看相同的信息,您会看到如下内容:

info replication
Redis master output# Replication
role:master
connected_slaves:1
slave0:ip=10.8.0.2,port=6379,state=online,offset=1737,lag=1
master_repl_offset:1737
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1736

如您所见,主服务器和从服务器在其定义的关系中正确识别彼此。

第 7 步:将 Redis 从站提升为主站

设置复制的一个主要原因是以最小的数据丢失和停机时间来处理故障。 Redis 从站可以提升为主站状态,以在 Redis 主站发生故障时处理写入流量。

手动提升 Redis 从站

我们可以从 Redis 从服务器手动执行此操作。 使用 Redis 客户端登录:

redis-cli

使用 Redis 从属密码进行身份验证:

auth your_redis_slave_password

在提升 Redis 从站之前,尝试覆盖测试密钥:

set test 'this key was overwritten on the slave server'

这应该会失败,因为默认情况下,Redis 从站配置为使用 slave-read-only yes 选项只读:

Redis slave output(error) READONLY You can't write against a read only slave.

要禁用复制并将当前服务器提升为主服务器状态,请使用值为 no oneslaveof 命令:

slaveof no one
Redis slave outputOK

再次检查复制信息:

info replication
Redis slave output# Replication
role:master
connected_slaves:0
master_repl_offset:6749
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

如您所见,从属现在被指定为 Redis 主控。

再次尝试覆盖密钥,这一次应该会成功:

set test 'this key was overwritten on the slave server'
Redis slave outputOK

请记住,由于配置文件仍然将此节点指定为 Redis 从属节点,因此如果在不修改配置的情况下重新启动服务,它将恢复复制。 另请注意,您用于 Redis 主服务器的任何设置都可能需要在此处重新应用(例如,打开仅附加文件或修改驱逐策略)。

如果还有其他 slave,将它们指向新提升的 master 以继续复制更改。 这可以使用 slaveof 命令和新主站的连接信息来完成。

要手动恢复到原始主服务器的复制,请使用 slaveof 命令和配置文件中使用的值将临时主服务器和从服务器指向原始主服务器:

slaveof ip_to_contact_master port_to_contact_master
Redis slave outputOK

如果再次检查slave上的key,应该会看到Redis master已经恢复了原来的值:

get test
Redis slave output"this key was defined on the master server"

出于一致性原因,从属服务器与主服务器重新同步时,会刷新从属服务器上的所有数据。

自动提升 Redis 从站

自动提升 Redis 从站需要与应用层协调。 这意味着实施在很大程度上取决于应用程序环境,因此很难建议具体的操作。

但是,我们可以了解完成自动故障转移所需的一般步骤。 以下步骤假设所有 Redis 服务器都已配置为相互访问:

  • 从应用程序中,检测到主服务器不再可用。
  • 在一台从站上,执行 slaveof no one 命令。 这将停止复制并将其提升为主状态。
  • 调整新母版上的任何设置以与之前的母版设置保持一致。 这可以在大多数选项的配置文件中提前完成。
  • 将您的应用程序的流量引导到新提升的 Redis 主服务器。
  • 在任何剩余的从站上,运行 slaveof new_master_ip new_master_port。 这将使从服务器停止从旧主服务器复制,完全丢弃它们(现已弃用)的数据,并开始从新主服务器复制。

在您恢复对原始主服务器的服务后,您可以允许它作为指向新提升的主服务器的从服务器重新加入,或者在需要时允许它恢复作为主服务器的职责。

结论

我们建立了一个由两台服务器组成的环境,一台作为 Redis 主服务器,另一台作为从服务器复制数据。 这在系统或网络故障的情况下提供了冗余,并且可以帮助出于性能原因在多个服务器之间分配读取操作。 这是设计 Redis 配置以满足您的生产应用程序和基础架构需求的良好起点,但绝不是该主题的详尽指南。 要了解有关使用 Redis 满足您的应用程序需求的更多信息,请查看我们的 其他 Redis 教程