暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[译文] Redis 高可用架构与 Sentinel

原创 Ashraf Sharif 2021-09-06
1003

Redis Sentinel 是一个专用流程,用于自动化和简化 Redis 复制故障转移和切换。如果没有 Sentinel,您还可以使用SLAVEOF 或 REPLICAOF 命令手动管理 Redis 复制。Sentinel 需要多个实例,并作为一组决策者工作,然后再决定哪个节点启动或关闭以及何时应触发故障转移。简单来说,Sentinel 是 Redis 的复制故障转移管理器。

在本示例中,我们将使用 Sentinel 部署一个简单的高可用 Redis 架构,如下图所示:

image.png

我们将在两个不同的节点上有两个 Redis 实例——1 个主节点和 1 个副本(或从节点)。Sentinel 将位于这 2 个节点上,另外还有一个节点位于我们的一个 Web 服务器上。

Redis 复制部署

通常,人们会在 Web/应用程序服务器上共同定位一个 Redis 实例,并通过本地主机或通过 UNIX 套接字文件访问它。这可以被认为是将 Redis 合并到应用程序中的最直接的方式。

对于可扩展且高度可用的设置应用程序,Redis 应以集中方式部署,或部署到称为缓存层的不同层中。这允许 Redis 实例作为应用程序的专用缓存提供程序协同工作,将应用程序与本地 Redis 依赖项分离。

在部署 Redis Sentinel 之前,我们必须部署一个由两个或多个 Redis 实例组成的 Redis 复制。让我们从在 redis1 和 redis2 两台服务器上安装 Redis 开始:

sudo add-apt-repository ppa:redislabs/redis sudo apt-get -y update sudo apt-get -y install redis redis-sentinel net-tools

接下来,我们需要确保/etc/redis/redis.conf 中存在以下配置行:

对于 redis1(主):

bind 127.0.0.1 192.168.44.71 protected-mode no supervised systemd masterauth SuperS3cr3tP455 masteruser masteruser user masteruser +@all on >SuperS3cr3tP455

对于 redis2(副本):

bind 127.0.0.1 192.168.44.72 protected-mode no supervised systemd replicaof 192.168.44.71 6379 masterauth SuperS3cr3tP455 masteruser masteruser user masteruser +@all on >SuperS3cr3tP455

一些解释:

  • bind:列出您希望 Redis 侦听的所有 IP 地址。为了使 Sentinel 正常工作,Redis 必须可以远程访问。因此,我们必须列出 Sentinel 将与之通信的接口。
  • protected-mode:必须将其设置为“no”以允许 Redis 为远程连接提供服务。这也是 Sentinel 所必需的。
  • 受监督:我们使用安装程序包提供的默认 systemd 单元文件。对于 Ubuntu 20.04,它使用 systemd 作为服务管理器,所以我们在这里指定 systemd。
  • replicaof:这仅适用于从节点。对于原始拓扑,我们将redis2作为replica,redis1作为master。
  • masterauth:用户 masteruser 的密码。
  • masteruser:主用户的用户名。
  • user:我们在这里创建主用户。用户应没有限制(+@all)和密码。此用户将用于 Redis 以管理 Sentinel 的复制和故障转移。

重新启动 Redis 以应用更改并在启动时启用它:

$ sudo systemctl restart redis-server $ sudo systemctl enable redis-server

验证 Redis 是否在两个接口上的端口 6379 上运行。以下示例是 redis2 的输出:

$ sudo netstat -tulpn | grep -i redis tcp 0 0 192.168.44.72:6379 0.0.0.0:* LISTEN 15992/redis-server tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 15992/redis-server

验证复制是否有效。在 redis1 上:

(redis1) $ redis-cli info replication # Replication role:master connected_slaves:1 slave0:ip=192.168.44.72,port=6379,state=online,offset=154,lag=1 master_failover_state:no-failover master_replid:e1a86d60fe42b41774f186528661ea6b8fc1d97a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:154 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:154

注意角色、 connected_slaves 和 slave{i} 键。这表明redis1是master。另请注意,一个副本可以是另一个副本的主节点 - 这也称为链式复制。

在 redis2 上:

(redis2) $ redis-cli info replication # Replication role:slave master_host:192.168.44.71 master_port:6379 master_link_status:up master_last_io_seconds_ago:2 master_sync_in_progress:0 slave_repl_offset:140 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:e1a86d60fe42b41774f186528661ea6b8fc1d97a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:140 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:140

注意角色,master_host、master_link_status和master_repl_offset。这两个节点之间的复制延迟可以由两个服务器上的 master_repl_offset 值决定。

Redis Sentinel部署

Redis Sentinel 基本上是相同的 redis-server 进程,使用“ --sentinel”标志和不同的配置文件和端口运行。对于生产使用,强烈建议至少有 3 个 Sentinel 实例,以便在执行自动故障转移时进行准确观察。因此,我们将在我们拥有的 2 个 Redis 节点以及我们的 Web 服务器之一 192.168.44.70(如架构图中所示)上安装 Sentinel。

在选定的 Web 服务器上安装redis-sentinel 包(Sentinel 已经安装在我们的 Redis 主机上):

$ sudo add-apt-repository ppa:redislabs/redis $ sudo apt-get -y update $ sudo apt-get -y install redis-sentinel net-tools

默认情况下,Sentinel 配置文件位于/etc/redis/sentinel.conf。确保设置了以下配置行:

应用服务器,192.168.44.70:

bind 192.168.44.70 port 26379 sentinel monitor mymaster 192.168.44.71 6379 2 sentinel auth-pass mymaster SuperS3cr3tP455 sentinel auth-user mymaster masteruser sentinel down-after-milliseconds mymaster 10000

redis1, 192.168.44.71:

bind 192.168.44.71 port 26379 sentinel monitor mymaster 192.168.44.71 6379 2 sentinel auth-pass mymaster SuperS3cr3tP455 sentinel auth-user mymaster masteruser sentinel down-after-milliseconds mymaster 10000

redis2, 192.168.44.72:

bind 192.168.44.72 port 26379 sentinel monitor mymaster 192.168.44.71 6379 2 sentinel auth-pass mymaster SuperS3cr3tP455 sentinel auth-user mymaster masteruser sentinel down-after-milliseconds mymaster 10000

重新启动redis-sentinel 守护进程以应用更改:

$ sudo systemctl restart redis-sentinel $ sudo systemctl enable redis-sentinel

确保 redis-sentinel 在端口 26379 上运行。在 redis2 上,您应该看到如下内容:

$ sudo netstat -tulpn | grep -i redis tcp 0 0 192.168.44.72:26379 0.0.0.0:* LISTEN 20093/redis-sentine tcp 0 0 192.168.44.72:6379 0.0.0.0:* LISTEN 15992/redis-server tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 15992/redis-server

通过查看日志文件/var/log/redis/redis-sentinel.log 来验证 Sentinel 是否正在观察我们的 Redis 复制链接。确保您看到以下几行:

20093:X 19 Jun 2021 12:06:39.780 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 20093:X 19 Jun 2021 12:06:39.780 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=20093, just started 20093:X 19 Jun 2021 12:06:39.780 # Configuration loaded 20093:X 19 Jun 2021 12:06:39.781 * monotonic clock: POSIX clock_gettime 20093:X 19 Jun 2021 12:06:39.781 * Running mode=sentinel, port=26379. 20093:X 19 Jun 2021 12:06:39.784 # Sentinel ID is 0f84e662fc3dd580721ce56f6a409e0f70ed341c 20093:X 19 Jun 2021 12:06:39.784 # +monitor master mymaster 192.168.44.71 6379 quorum 2 20093:X 19 Jun 2021 12:06:39.786 * +slave slave 192.168.44.72:6379 192.168.44.72 6379 @ mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 12:06:41.163 * +sentinel sentinel 6484e8281246c950d31e779a564c29d7c43aa68c 192.168.44.71 26379 @ mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 12:07:20.205 * +sentinel sentinel 727151aabca8596dcc723e6d1176f8aa01203ada 192.168.44.70 26379 @ mymaster 192.168.44.71 6379

我们可以通过redis-cli获取更多关于 Sentinel 进程的信息,并连接到 Sentinel 端口 26379:

(app)$ redis-cli -h 192.168.44.72 -p 26379 sentinel masters 1) 1) "name" 2) "mymaster" 3) "ip" 4) "192.168.44.71" 5) "port" 6) "6379" 7) "runid" 8) "a9158eb1d25a8291b3808e5ddfe87bd24cceb550" 9) "flags" 10) "master" 11) "link-pending-commands" 12) "0" 13) "link-refcount" 14) "1" 15) "last-ping-sent" 16) "0" 17) "last-ok-ping-reply" 18) "80" 19) "last-ping-reply" 20) "80" 21) "down-after-milliseconds" 22) "10000" 23) "info-refresh" 24) "10063" 25) "role-reported" 26) "master" 27) "role-reported-time" 28) "90348" 29) "config-epoch" 30) "0" 31) "num-slaves" 32) "1" 33) "num-other-sentinels" 34) "2" 35) "quorum" 36) "2" 37) "failover-timeout" 38) "180000" 39) "parallel-syncs" 40) "1"

注意“num-slaves”值为1,“num-other-sentinels”值为2,表示我们总共有3个Sentinel节点(一个用于这个节点+两个其他节点)。至此,我们的Redis Sentinel配置就完成了。

故障转移测试

我们现在可以通过简单地关闭 redis1(master) 上的 Redis 服务来测试故障转移:

$ sudo systemctl stop redis-server

10 秒后(down-after-milliseconds 值),您应该会在/var/log/redis/redis-sentinel.log 文件中看到以下输出:

20093:X 19 Jun 2021 13:07:43.581 # +sdown master mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:43.644 # +odown master mymaster 192.168.44.71 6379 #quorum 2/2 20093:X 19 Jun 2021 13:07:43.644 # +new-epoch 1 20093:X 19 Jun 2021 13:07:43.645 # +try-failover master mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:43.646 # +vote-for-leader 0f84e662fc3dd580721ce56f6a409e0f70ed341c 1 20093:X 19 Jun 2021 13:07:43.650 # 6484e8281246c950d31e779a564c29d7c43aa68c voted for 0f84e662fc3dd580721ce56f6a409e0f70ed341c 1 20093:X 19 Jun 2021 13:07:43.651 # 727151aabca8596dcc723e6d1176f8aa01203ada voted for 0f84e662fc3dd580721ce56f6a409e0f70ed341c 1 20093:X 19 Jun 2021 13:07:43.705 # +elected-leader master mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:43.705 # +failover-state-select-slave master mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:43.758 # +selected-slave slave 192.168.44.72:6379 192.168.44.72 6379 @ mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:43.758 * +failover-state-send-slaveof-noone slave 192.168.44.72:6379 192.168.44.72 6379 @ mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:43.842 * +failover-state-wait-promotion slave 192.168.44.72:6379 192.168.44.72 6379 @ mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:44.728 # +promoted-slave slave 192.168.44.72:6379 192.168.44.72 6379 @ mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:44.728 # +failover-state-reconf-slaves master mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:44.827 # +failover-end master mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:07:44.827 # +switch-master mymaster 192.168.44.71 6379 192.168.44.72 6379 20093:X 19 Jun 2021 13:07:44.827 * +slave slave 192.168.44.71:6379 192.168.44.71 6379 @ mymaster 192.168.44.72 6379 20093:X 19 Jun 2021 13:07:54.874 # +sdown slave 192.168.44.71:6379 192.168.44.71 6379 @ mymaster 192.168.44.72 6379

至此,我们唯一的slave,192.168.44.72,已经提升为master了。一旦我们的老主 (redis1) 重新上线,您应该会看到 Sentinel 报告的类似内容:

20093:X 19 Jun 2021 13:10:23.859 * +convert-to-slave slave 192.168.44.71:6379 192.168.44.71 6379 @ mymaster 192.168.44.72 6379

以上表示旧的 master 已经转换为 slave,现在从当前的 master redis2 复制。我们可以通过检查 redis2 上的复制信息来确认这一点:

(redis2)$ redis-cli info replication # Replication role:master connected_slaves:1 slave0:ip=192.168.44.71,port=6379,state=online,offset=1041068,lag=1 master_failover_state:no-failover master_replid:9db31b3b1010100cf187a316cfdf7ed92577e60f master_replid2:e1a86d60fe42b41774f186528661ea6b8fc1d97a master_repl_offset:1041350 second_repl_offset:991011 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1041350

如果我们想再次将 redis1 提升为 master 状态,我们可以简单地关闭 redis2 或使用 Sentinel 故障转移命令,如下所示:

(app)$ redis-cli -h 192.168.44.70 -p 26379 sentinel failover mymaster OK

一旦触发故障转移,Sentinel 将报告主升级如下:

20093:X 19 Jun 2021 13:13:34.608 # +new-epoch 2 20093:X 19 Jun 2021 13:13:35.716 # +config-update-from sentinel 727151aabca8596dcc723e6d1176f8aa01203ada 192.168.44.70 26379 @ mymaster 192.168.44.72 6379 20093:X 19 Jun 2021 13:13:35.716 # +switch-master mymaster 192.168.44.72 6379 192.168.44.71 6379 20093:X 19 Jun 2021 13:13:35.717 * +slave slave 192.168.44.72:6379 192.168.44.72 6379 @ mymaster 192.168.44.71 6379 20093:X 19 Jun 2021 13:13:45.756 * +convert-to-slave slave 192.168.44.72:6379 192.168.44.72 6379 @ mymaster 192.168.44.71 6379

之前的slave,redis1,被提升为新的master( +switch-master),redis2被转换为slave(+convert-to-slave)。我们现在回到开始时的原始拓扑。

最后的想法

如果您想要高可用的 Redis 复制设置,Redis Sentinel 是必备工具。它简化并自动化了 Redis 的复制故障转移和切换,并且设置起来相当容易。但是,如果您没有使用 Redis 并且因为我们也提到了数据库节点,那么您的数据库基础设施(包括数据库节点)也可以使用ClusterControl进行监控。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论