如何在Ubuntu 16.04上配置Redis复制

介绍

Redis是一个开源键值数据存储,使用内存存储模型和可选的磁盘写入来实现持久性。它具有事务,发布/订阅消息传递模式以及其他功能之间的自动故障转移功能。Redis客户端有多种语言编写的版本,并在其网站上提供了推荐的客户端。

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

在本教程中,我们将在两台服务器之间配置复制,两台服务器都运行Ubuntu 16.04。如有必要,可以轻松地将此过程调整为更多服务器。

准备

要完成本教程,您需要访问两个Ubuntu 16.04服务器。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。根据Redis使用的术语,我们将负责接受写请求的服务器称为服务器,将辅助只读服务器称为服务器。

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

准备好开始时,请继续阅读本教程。

第一步:安装Redis

首先,我们将在服务器和服务器上安装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部署到隔离网络......

如果您的服务器在隔离网络中运行,您可能只需要调整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服务器之间的流量,包括:

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

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

第三步:配置Redis Master

现在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 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

现在我们已准备好主服务器,让我们继续设置我们的从服务器。

第五步:配置Redis Slave

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

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

sudo nano /etc/redis/redis.conf

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

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

  • 隔离网络:使用主服务器的隔离网络IP地址和Redis端口(6379)(例如slaveofisolated_IP_address 6379)。
  • stunnelspiped:使用本地接口(127.0.0.1)和配置为隧道流量的端口(如果您按照教程进行操作的话,是slaveof 127.0.0.1 8000)。
  • PeerVPN:使用主服务器的VPN IP地址和常规Redis端口(如果您按照教程操作的,则会这样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 Slave并应用更改

在我们重新启动服务以实现更改之前,让我们连接到从属计算机上的本地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_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

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

第七步:将Redis Slave升级为Master

设置复制的主要原因是以最小的数据丢失和停机时间处理故障。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.

要禁用复制并将当前服务器提升为主状态,请使用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从站需要与应用层协调。这意味着在很大程度上实现取决于应用程序环境,因此很难建议具体的操作。

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

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

在将服务恢复到原始主服务器之后,您可以允许它作为指向新升级主服务器的从服务器重新加入,或者允许它作为主服务器恢复工作(如果需要)。

结论

我们已经建立了一个由两台服务器组成的环境,一台作为Redis主服务器,另一台作为从服务器复制数据。这在系统或网络发生故障时提供冗余,并且出于性能原因可以帮助在多个服务器之间分配读取操作。这是设计Redis配置以适应您正在运行的应用程序和基础架构需求的良好教程,但不是关于该主题的详尽教程。

要了解有关将Redis用于满足应用程序需求的更多信息,请查看我们的其他Redis教程,更多Linux教程请前往腾讯云+社区学习更多知识。

参考文献:《How To Configure Redis Replication on Ubuntu 16.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏不想当开发的产品不是好测试

nohup命令

背景 很多时候我们需要在后台运行一些命令,如启动flask,之前是通过命令行后加上&使其在后台运行,但加&这种模式,日志记录有一些问题,然后当终端关闭的时候也会...

2708
来自专栏JavaEdge

SpringBoot+Security 发送短信验证码在core模块下properties包中创建SmsCodeProperties在ValidateCodeProperties中new一个SmsCo

2956
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Apache或Nginx加密Tomcat 8连接

Apache Tomcat是一个Web服务器和servlet容器,旨在为Java应用程序提供服务。Tomcat经常用于生产企业部署和较小的应用程序需求,既灵活又...

4663
来自专栏FreeBuf

TinyShop缓存文件获取WebShell之0day

TinyShop是一款电子商务系统(网店系统),适合企业及个人快速构建个性化网上商店。系统是基于Tiny(自主研发)框架开发的,使系统更加的安全、快捷、稳定、高...

2449
来自专栏Petrichor的专栏

apt-get指令

apt-cache search package #搜索包(相当于yum list | grep pkg) apt-cache show packag...

1771
来自专栏JAVA烂猪皮

Zookeeper的简介和应用场景

Zookeeper是一个分布式协调服务;就是为用户的分布式应用程序提供协调服务 A、zookeeper是为别的分布式程序服务的 B、Zookeeper本身就...

1421
来自专栏LeoXu的博客

JavaScript异步调用操作可增加finally回调

JavaScript异步调用操作(如远程服务、本地任务)的API一般只提供的执行成功(success)和执行失败(fail)的回调,其实还可以...

763
来自专栏JackeyGao的博客

Django小技巧09: 创建修改密码视图

就此而言, 使用函数式视图更容易实现。 因为PasswordChangeForm不从ModelForm继承。并且其构造函数使用user参数.

2171
来自专栏小尘哥的专栏

springboot2.x中的服务监控之邮件预警

以下以QQ邮箱为例(163等邮箱都大差不差) 登录后进入“邮箱设置”-->“帐户”--》往下拉--》开启POP3/SMTP

1372
来自专栏C/C++基础

Linux命令(40)——nohup命令

nohup的作用可以将程序以忽略挂起信号(SIGHUP)的方式运行。常见的用法是和&命令一同使用,将命令放置到后台运行,即使终端挂掉,进程会忽略挂起信号,继续运...

1132

扫码关注云+社区

领取腾讯云代金券