65.9K
CodeProject 正在变化。 阅读更多。
Home

Redis:复制,第二部分 – 主从复制和 Redis Sentinel

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2019 年 3 月 30 日

CPOL

7分钟阅读

viewsIcon

7905

Redis 复制设置示例,包含基本的主从复制和 Redis Sentinel

第一部分 – Redis:复制,第一部分 – 概述。复制与分片。Sentinel 与 Cluster。Redis 拓扑

整个故事始于我们决定摆脱 memcached

目前,我们的后端服务器上运行着 memcached 和 Redis。

memcached 和 Redis 实例都作为独立应用程序运行,即它们没有连接到任何类型的复制,这会导致一个问题

  • 我们有三个后端主机,位于 AWS Application Load Balancer 后面
  • ALB 启用了 粘性会话,但它使用的是我们的移动应用程序(iOS/Android)忽略的 cookie
  • 因此,当客户端向后端发出请求时 – 有时,它可能会获得已在 Redis 或 memcached 的另一个后端主机上被删除/更新的缓存数据

自从我们从只有一个主机且尚未更新的旧基础设施迁移了后端应用程序以来,我们一直采用这种方案,尽管它早已在我们的计划中。

目前,为了解决这些问题,我们在后端有一堆“技巧”,它们会进行额外的检查以确保数据是最新的,现在为了摆脱它们,我们决定

  1. 完全摆脱 memcached,因为 Redis 可以用于 memcached 现在使用的功能
  2. 在所有主机上配置 Redis 复制

下面的帖子将描述这样的设置。

第一个示例 – 使用基本的 Master-Slave 复制,第二个示例 – Sentinel 的设置和配置。

这里将使用带有 Debian 9 的 AWS EC2 实例。

为了与 Redis 主机协同工作,将使用三个域名 – redis-0.setevoy.org.ua 作为主节点,redis-1.setevoy.org.uaredis-2.setevoy.org.ua 作为其两个从节点。

在最小的设置中,可以只有一个从节点,但由于第二个示例将是 Sentinel – 让我们从一开始就设置三个。

基本主从复制

通过这种方式,从节点将是主节点的只读副本,保留添加到主节点上的相同数据。

主节点会将所有数据更新发送给其从节点 – 新的键过期等。

如果主节点和从节点之间的链接断开 – 从节点将尝试重新连接到主节点并进行部分同步,以更新从上一个同步中断的地方开始的数据。

如果无法进行部分同步 – 从节点将请求主节点进行完全同步,主节点将执行其数据全快照并将其发送给该从节点,之后,将恢复正常的同步。

这里有几点需要注意

  • 一个主节点可以有多个从节点
  • 从节点可以接受来自其他从节点的连接,形成一种“级联”复制节点 – 顶层是主节点,中间是(一个或多个)从节点,底层是(一个或多个)从节点
  • 强烈建议在主节点上启用数据持久化以避免数据丢失 – 请参阅 主节点关闭持久化时的复制安全性
  • 从节点默认将以只读模式工作,请参阅 只读从节点

Redis 主节点配置

安装 Redis

root@redis-0:/home/admin# apt -y install redis-server

编辑 /etc/redis/redis.conf,并在 bind 中设置要监听的接口

...
bind 0.0.0.0
...

您可以在此处指定多个 IP,用空格分隔

...
bind 127.0.0.1 18.194.229.23
...

其他有价值的选项

  • port 6379 – 很明显,但请记住
  • slave-read-only yes – 从节点将以只读模式工作,不影响主节点
  • requirepass foobared – 主节点授权密码
  • appendonly yesappendfilename "appendonly.aof" – 降低数据丢失的风险,请参阅 Redis 持久化

重启服务

root@redis-0:/home/admin# systemctl restart redis

使用 -a 加上密码进行检查

root@redis-0:/home/admin# redis-cli -a foobared ping

PONG

检查数据复制状态

root@redis-0:/home/admin# redis-cli -a foobared info replication

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

添加新数据

root@redis-0:/home/admin# redis-cli -a foobared set test 'test'

OK

取回数据

root@redis-0:/home/admin# redis-cli -a foobared get test

"test"

好的 – 这里一切正常。

Redis 从节点配置

在剩下的两个主机上,进行从节点配置。

对两者来说都将是相同的 – 只需重复即可。

安装 Redis

root@redis-1:/home/admin# apt -y install redis-server

编辑 /etc/redis/redis.conf

...
slaveof redis-0.setevoy.org.ua 6379
...
masterauth foobared
...
requirepass foobared
...

这里

  • slaveof – 设置主节点的 IP 地址和端口
  • masterauth – 主节点的认证密码
  • requirepass – 此副本的认证密码

重启服务

root@redis-1:/home/admin# systemctl restart redis

检查其状态

root@redis-1:/home/admin# redis-cli -a foobared info replication

Replication

role:slave

master_host:redis-0.setevoy.org.ua

master_port:6379

master_link_status:up

master_last_io_seconds_ago:5

master_sync_in_progress:0

...

检查日志

root@redis-1:/home/admin# tail -f /var/log/redis/redis-server.log

16961:S 29 Mar 10:54:36.263 * Connecting to MASTER redis-0.setevoy.org.ua:6379

16961:S 29 Mar 10:54:36.308 * MASTER <-> SLAVE sync started

16961:S 29 Mar 10:54:36.309 * Non blocking connect for SYNC fired the event.

16961:S 29 Mar 10:54:36.309 * Master replied to PING, replication can continue...

16961:S 29 Mar 10:54:36.310 * Partial resynchronization not possible (no cached master)

16961:S 29 Mar 10:54:36.311 * Full resync from master: 93585eeb7e32c0550c35f8d4935c9a18c4177ab9:1

16961:S 29 Mar 10:54:36.383 * MASTER <-> SLAVE sync: receiving 92 bytes from master

16961:S 29 Mar 10:54:36.383 * MASTER <-> SLAVE sync: Flushing old data

16961:S 29 Mar 10:54:36.383 * MASTER <-> SLAVE sync: Loading DB in memory

16961:S 29 Mar 10:54:36.383 * MASTER <-> SLAVE sync: Finished with success

与主节点的连接已建立,同步已完成 – 好的,检查数据

root@redis-1:/home/admin# redis-cli -a foobared get test

"test"

数据存在 – 这里也一切正常。

更改从节点 => 主节点角色

如果主节点发生故障 – 您需要切换一个从节点来成为新的主节点。

如果您尝试在当前的从节点上添加任何数据 – Redis 将会报错,因为从节点处于只读模式

...
slave-read-only yes
...

尝试添加一些内容

root@redis-1:/home/admin# redis-cli -a foobared set test2 'test2'

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

现在连接到从节点

root@redis-1:/home/admin# redis-cli

Authorize

127.0.0.1:6379> auth foobared

OK

禁用从节点角色

127.0.0.1:6379> slaveof no one

OK

现在检查其状态

127.0.0.1:6379> info replication

Replication

role:master

connected_slaves:0

master_repl_offset:1989

repl_backlog_active:0

repl_backlog_size:1048576

再次添加一个新键

127.0.0.1:6379> set test2 'test2'

OK

并取回它

127.0.0.1:6379> get test2

"test2"

请记住,由于我们直接在 Redis 节点上进行了这些更改 – 在其重启后,它将再次成为从节点,因为它仍在其 /etc/redis/redis.conf 文件中通过 slaveof 参数设置。

Redis Sentinel

现在让我们在复制中添加 Sentinel,它将监控 Redis 节点并自动执行角色切换。

整体方案如下

这里

  • M1 = 主节点
  • R1 = 副本 1 / 从节点 1
  • R2 = 副本 2 / 从节点 2
  • S1 = Sentinel 1
  • S2 = Sentinel 2
  • S3 = Sentinel 3

M1 和 S1 – 将在 redis-0 上,R1 和 S2 – 在 redis-1 上,R2 和 S3 – 在 redis-2 上。

运行 Sentinel

要运行 Sentinel 守护进程,可以使用 redis-server 加上单独的配置文件 – /etc/redis/sentinel.conf

首先,让我们在 Redis 主节点上创建这样的配置文件

sentinel monitor redis-test redis-0.setevoy.org.ua 6379 2
sentinel down-after-milliseconds redis-test 6001
sentinel failover-timeout redis-test 60000
sentinel parallel-syncs redis-test 1
bind 0.0.0.0
sentinel auth-pass redis-test foobared

这里

  • monitor – 要监控的主节点地址,2 是 Sentinel 实例数量,用于做出决策
  • down-after-milliseconds – 主节点被视为出现故障后经过的时间
  • failover-timeout – 更改从节点=>主节点角色后等待的时间
  • parallel-syncs – 主节点更改后同步从节点的并行数量

运行它:

root@redis-0:/home/admin# redis-server /etc/redis/sentinel.conf --sentinel

...

10447:X 29 Mar 14:15:53.193 # WARNING: The TCP backlog setting of 511 cannot be enforced 
because /proc/sys/net/core/somaxconn is set to the lower value of 128.

10447:X 29 Mar 14:15:53.195 # Sentinel ID is e9fb72c8edb8ec2028e6ce820b9e72e56e07cf1e

10447:X 29 Mar 14:15:53.195 # +monitor master redis-test 35.158.154.25 6379 quorum 2

10447:X 29 Mar 14:15:53.196 * +slave slave 3.121.223.95:6379 3.121.223.95 6379 
@ redis-test 35.158.154.25 6379

10447:X 29 Mar 14:16:43.402 * +slave slave 18.194.45.17:6379 18.194.45.17 6379 
@ redis-test 35.158.154.25 6379

使用 26379 端口检查 Sentinel 的状态

root@redis-0:/home/admin# redis-cli -p 26379 info sentinel

Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

sentinel_simulate_failure_flags:0

master0:name=redis-test,status=ok,address=35.158.154.25:6379,slaves=2,sentinels=1

这里

  • master0:name=redis-test,status=ok – 主节点 UP
  • slaves=2 – 它有两个从节点
  • sentinels=1 – 目前只有一个 Sentinel 实例在运行

您可以在这里获得一些基本信息,例如 – 主节点的 IP

root@redis-0:/home/admin# redis-cli -p 26379 sentinel get-master-addr-by-name redis-test

1) "35.158.154.25"

2) "6379"

现在,在两个从节点上重复 Sentinel 的启动,使用与我们在主节点上相同的配置,在 Sentinel 的日志中,您应该会看到新的实例连接

...

10447:X 29 Mar 14:18:40.437 * +sentinel sentinel fdc750c7d6388a6142d9e27b68172f5846e75d8c 
172.31.36.239 26379 @ redis-test 35.158.154.25 6379

10447:X 29 Mar 14:18:42.725 * +sentinel sentinel ecddb26cd27c9a17c4251078c977761faa7a3250 
172.31.35.218 26379 @ redis-test 35.158.154.25 6379

...

再次检查状态

root@redis-0:/home/admin# redis-cli -p 26379 info sentinel

Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

sentinel_simulate_failure_flags:0

master0:name=redis-test,status=ok,address=18.194.229.23:6379,slaves=2,sentinels=3

sentinels=3 – 好的。

此外,Sentinel 将在需要时执行其自身的设置更新

root@redis-1:/home/admin# cat /etc/redis/sentinel.conf

sentinel myid fdc750c7d6388a6142d9e27b68172f5846e75d8c

sentinel monitor redis-test 35.158.154.25 6379 2

sentinel down-after-milliseconds redis-test 6001

bind 0.0.0.0

sentinel failover-timeout redis-test 60000

Generated by CONFIG REWRITE

port 26379

dir "/home/admin"

sentinel auth-pass redis-test foobared

sentinel config-epoch redis-test 0

sentinel leader-epoch redis-test 0

sentinel known-slave redis-test 18.194.45.17 6379

sentinel known-slave redis-test 3.121.223.95 6379

sentinel known-sentinel redis-test 172.31.35.218 26379 ecddb26cd27c9a17c4251078c977761faa7a3250

sentinel known-sentinel redis-test 172.31.47.184 26379 e9fb72c8edb8ec2028e6ce820b9e72e56e07cf1e

sentinel current-epoch 0

这里添加了 sentinel myid fdc750c7d6388a6142d9e27b68172f5846e75d8c 行,以及 #Generated by CONFIG REWRITE 之后的整个块。

Redis Sentinel 自动故障转移

现在让我们看看如果主节点出现故障会发生什么。

您可以通过调用 kill -9 手动执行此操作,或者使用 redis-cli 并发送带有秒数的 DEBUG 命令使主节点“下线”,或者发送信号来杀死主节点。

root@redis-0:/home/admin# redis-cli -a foobared DEBUG sleep 30

主节点上的 Sentinel 日志

...

10447:X 29 Mar 14:24:56.549 # +sdown master redis-test 35.158.154.25 6379

10447:X 29 Mar 14:24:56.614 # +new-epoch 1

10447:X 29 Mar 14:24:56.615 # +vote-for-leader ecddb26cd27c9a17c4251078c977761faa7a3250 1

10447:X 29 Mar 14:24:56.649 # +odown master redis-test 35.158.154.25 6379 #quorum 3/2

10447:X 29 Mar 14:24:56.649 # Next failover delay: 
I will not start a failover before Fri Mar 29 14:26:57 2019

10447:X 29 Mar 14:24:57.686 # +config-update-from sentinel 
ecddb26cd27c9a17c4251078c977761faa7a3250 172.31.35.218 26379 @ redis-test 35.158.154.25 6379

10447:X 29 Mar 14:24:57.686 # +switch-master redis-test 35.158.154.25 6379 3.121.223.95 6379

10447:X 29 Mar 14:24:57.686 * +slave slave 18.194.45.17:6379 18.194.45.17 6379 
@ redis-test 3.121.223.95 6379

10447:X 29 Mar 14:24:57.686 * +slave slave 35.158.154.25:6379 35.158.154.25 6379 
@ redis-test 3.121.223.95 6379

10447:X 29 Mar 14:25:03.724 # +sdown slave 35.158.154.25:6379 35.158.154.25 6379 
@ redis-test 3.121.223.95 6379

...

目前,我们对这里这两行感兴趣

...

10384:X 29 Mar 14:24:57.686 # +config-update-from sentinel 
ecddb26cd27c9a17c4251078c977761faa7a3250 172.31.35.218 26379 @ redis-test 35.158.154.25 6379

10384:X 29 Mar 14:24:57.686 # +switch-master redis-test 35.158.154.25 6379 3.121.223.95 6379

...

Sentinel 执行了从节点到主节点的重新配置。

35.158.154.25 – 是旧的主节点,现在已失效,而 3.121.223.95 是一个新的主节点,从从节点中选举产生 – 它运行在 redis-1 主机上。

尝试在这里添加数据

root@redis-1:/home/admin# redis-cli -a foobared set test3 'test3'

OK

而对旧主节点(现在变成从节点)的类似尝试将导致错误

root@redis-0:/home/admin# redis-cli -a foobared set test4 'test4'

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

让我们完全杀死一个节点,看看 Sentinel 现在会做什么

root@redis-0:/home/admin# redis-cli -a foobared DEBUG SEGFAULT

Error: Server closed the connection

Log

...

10447:X 29 Mar 14:26:21.897 * +reboot slave 35.158.154.25:6379 35.158.154.25 6379 
@ redis-test 3.121.223.95 6379

嗯 – Sentinel 刚刚重启了那个节点

Sentinel 命令

命令 描述
sentinel masters 列出所有主节点及其状态
sentinel master 一个主节点的状态
sentinel slaves 列出所有从节点及其状态
sentinel sentinels 列出所有 Sentinel 实例及其状态
sentinel failover 手动运行故障转移
sentinel flushconfig 强制 Sentinel 将其配置重写到磁盘
sentinel monitor 添加一个新主节点
sentinel remove 从监视中删除主节点

相关链接

类似帖子

© . All rights reserved.