Redis是一个开源键值数据存储,使用内存存储模型和可选的磁盘写入来实现持久性。它具有事务,发布/订阅消息传递模式以及其他功能之间的自动故障转移功能。Redis客户端有多种语言编写的版本,并在其网站上提供了推荐的客户端。
对于生产环境,至少在两个节点上复制数据被认为是最佳实践。这允许在环境失败的情况下进行恢复,这在应用程序的用户群增长时尤其重要。它还允许您安全地与生产数据交互,而无需修改或影响性能。
在本教程中,我们将在两台服务器之间配置复制,两台服务器都运行Ubuntu 16.04。如有必要,可以轻松地将此过程调整为更多服务器。
要完成本教程,您需要访问两个Ubuntu 16.04服务器。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。根据Redis使用的术语,我们将负责接受写请求的主服务器称为主服务器,将辅助只读服务器称为从服务器。
您应该有一个非root用户,并sudo
在每个服务器上配置了权限。此外,本教程将假设您已准备好基本防火墙。您可以按照我们的Ubuntu 16.04初始服务器设置指南来满足这些要求。
准备好开始时,请继续阅读本教程。
首先,我们将在主服务器和从服务器上安装Redis 。
我们将使用Chris Lea的Redis PPA安装最新的Redis Server软件包。启用第三方存储库时请务必小心。在这种情况下,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
您应该收到以下回复:
PONG
这表示Redis正在运行并且可供本地客户端访问。
在设置复制之前,了解Redis安全模型的含义非常重要。Redis不提供本机加密选项,并假定它已部署到受信任对等方的专用网络。
如果您的服务器在隔离网络中运行,您可能只需要调整Redis的配置文件以绑定到隔离的网络IP地址。
在每台计算机上打开Redis配置文件:
sudo nano /etc/redis/redis.conf
找到该bind
行并附加服务器自己的隔离网络IP地址:
bind 127.0.0.1 isolated_IP_address
保存并关闭文件。输入以下命令重启服务:
sudo systemctl restart redis-server.service
打开对Redis端口的访问:
sudo ufw allow 6379
您现在应该可以通过redis-cli
带有-h
标志的命令将备用服务器的IP地址提供给来从另一个服务器访问一个服务器:
redis-cli -h isolated_IP_address ping
您应该收到以下回复:
PONG
Redis现在可以接受来自隔离网络的连接。
对于非隔离或您无法控制的网络,必须通过其他方式保护流量。有许多选项可以保护Redis服务器之间的流量,包括:
使用上述方法之一,在Redis主服务器和从服务器之间建立安全通信方法。您应该知道每台计算机在其对等设备上安全连接到Redis服务所需的IP地址和端口。
现在Redis已在每台服务器上运行并且已建立安全的通信通道,我们必须编辑它们的配置文件。让我们从将作为主服务器的服务器开始。
用您喜欢的文本编辑器打开/etc/redis/redis.conf
:
sudo nano /etc/redis/redis.conf
首先找到tcp-keepalive
设置并将其设置为60秒,如下所示。这将有助于Redis检测网络或服务问题:
. . .
tcp-keepalive 60
. . .
找到该requirepass
指令并将其设置为强密码。虽然您的Redis流量应该来自外部各方,但这为Redis本身提供了身份验证。由于Redis速度快且不限制密码尝试,因此请选择强度大而复杂的密码以防止强力尝试:
requirepass your_redis_master_password
最后,根据您的使用场景,您可能希望调整一些可选设置。
如果您不希望Redis在填满时自动修剪旧的和较少使用的密钥,您可以关闭自动密钥驱逐:
maxmemory-policy noeviction
为了提高耐久性保证,您可以打开仅附加文件持久性。这将有助于在系统出现故障时将数据丢失降至最低,但代价是文件较大且性能稍慢:
appendonly yes
appendfilename "redis-staging-ao.aof"
完成后,保存并关闭文件。
重新启动Redis服务以重新加载配置更改:
sudo systemctl restart redis-server.service
现在配置了主服务器,下面就可以进行测试。
检查您是否可以使用通过启动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
现在我们已准备好主服务器,让我们继续设置我们的从服务器。
接下来,我们需要进行一些更改以允许我们的从服务器连接到我们的主实例。
在从属服务器上打开/etc/redis/redis.conf
:
sudo nano /etc/redis/redis.conf
首先,找到并取消注释该slaveof
行。此伪指令使用您用于安全联系主Redis服务器的IP地址和端口,以空格分隔。默认情况下,Redis服务器在本地接口6379上侦听,但每种网络安全方法都以外部方的某种方式修改默认值。
您使用的值取决于您用于保护网络流量的方法:
slaveofisolated_IP_address 6379
)。slaveof 127.0.0.1 8000
)。slaveof 10.8.0.1 6379
)。一般形式是:
slaveof ip_to_contact_master port_to_contact_master
接下来,取消注释并使用为Redis主服务器设置的密码填写masterauth
行:
masterauth your_redis_master_password
为从属服务器设置密码以防止未经授权的访问。有关密码复杂性的相同警告适用于此:
requirepass your_redis_slave_password
完成后保存并关闭文件。
在我们重新启动服务以实现更改之前,让我们连接到从属计算机上的本地Redis实例并验证该test
密钥是否未设置:
redis-cli
输入以下内容查询密钥:
get test
你应该得到以下回复:
Redis slave output(nil)
这表示本地Redis实例没有名为test
的密钥。输入以下命令退回到shell:
exit
在从服务器上重新启动Redis服务以实现这些更改:
sudo systemctl restart redis-server.service
这将应用我们对Redis从站配置文件所做的所有更改。
再次重新连接到本地Redis实例:
redis-cli
与Redis主服务器一样,如果未经授权,操作应该失败:
get test
Redis slave output(error) NOAUTH Authentication required.
现在,使用您在上一节中设置的Redis slave的密码进行身份验证:
auth your_redis_slave_password
Redis slave outputOK
如果我们这次尝试访问密钥,我们会发现它可用:
get test
Redis slave output"this key was defined on the master server"
一旦我们在slave上重新启动Redis服务,立即开始复制。
您可以使用Redis的info
命令进行验证,该命令报告有关复制的信息。master_host
和master_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
如您所见,主服务器和从服务器在其定义的关系中能互相正确识别。
设置复制的主要原因是以最小的数据丢失和停机时间处理故障。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.
要禁用复制并将当前服务器提升为主状态,请使用slaveof
值为no one
的命令:
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 output
OK
Redis 从服务器输出:
OK
请记住,由于配置文件仍将此节点指定为Redis从服务器,因此如果在不修改配置的情况下重新启动服务,它将恢复复制。另请注意,您可能需要在此处重新应用用于Redis主服务器的任何设置(例如,启用仅附加文件或修改驱逐策略)。
如果有任何其他从属服务器,请将它们指向新升级的主服务器以继续复制更改。您可以使用slaveof
命令和新的主服务器的连接信息来完成。
要手动恢复到原始主服务器的复制,请使用包含配置文件中使用的值的slaveof
命令将临时主服务器和从服务器指回原始主服务器:
slaveof ip_to_contact_master port_to_contact_master
Redis 从服务器输出:
OK
如果再次检查从服务器上的键,您应该看到Redis主服务器已恢复原始值:
get test
Redis slave output"this key was defined on the master server"
出于一致性原因,从主服务器重新同步时,将刷新从服务器上的所有数据。
自动提升Redis从站需要与应用层协调。这意味着在很大程度上实现取决于应用程序环境,因此很难建议具体的操作。
但是,我们可以介绍完成自动故障转移所需的一般步骤。以下步骤假定所有Redis服务器都已配置为相互访问:
slaveof no one
命令。这将停止复制并将其提升为主状态。slaveof new_master_ip new_master_port
。这将使从服务器停止从旧的主服务器中复制,完全丢弃它们(现已弃用)的数据,并开始从新主服务器中复制。在将服务恢复到原始主服务器之后,您可以允许它作为指向新升级主服务器的从服务器重新加入,或者允许它作为主服务器恢复工作(如果需要)。
我们已经建立了一个由两台服务器组成的环境,一台作为Redis主服务器,另一台作为从服务器复制数据。这在系统或网络发生故障时提供冗余,并且出于性能原因可以帮助在多个服务器之间分配读取操作。这是设计Redis配置以适应您正在运行的应用程序和基础架构需求的良好教程,但不是关于该主题的详尽教程。
要了解有关将Redis用于满足应用程序需求的更多信息,请查看我们的其他Redis教程,更多Linux教程请前往腾讯云+社区学习更多知识。
参考文献:《How To Configure Redis Replication on Ubuntu 16.04》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。