目录
第一部分—— Redis:复制,第1部分——概述 复制与分片、哨兵与集群、Redis拓扑。
介绍
当我们决定摆脱memcached时,整个故事就开始了。
目前,我们已经在我们的后端服务器上运行memcahced和Redis。
并且memcached,Redis实例作为独立应用程序运行,即它们没有连接任何类型的复制,这导致了一个问题:
- 我们有三个后端主机,它们托管在AWS应用负载平衡器后面
- ALB 启用了Sticky Sessions,但它正在使用我们的移动应用程序(iOS / Android)忽略的cookie
- 当客户端向后端发出请求时——有时,它可以获取已在Redis中的另一个后端主机上删除/更新的缓存数据或 memcached
我们有这个方案,因为我们从一个旧的基础设施迁移我们的后端应用程序,其中只使用了一个主机并且仍然没有时间更新它,尽管它在我们的主机上很长一段时间了。
目前,为了解决这些问题,我们在后端有一堆“黑客”,它会进行额外的检查以确保数据是最新的,现在为了摆脱它们,我们决定:
- 完全摆脱memcached,因为Redis可以用于现在memcached使用的功能
- 在所有主机上配置Redis复制
这样的设置将在下面的内容中描述。
第一个示例——使用基本的主从复制和第二个示例——哨兵设置和配置。
这里将使用Debian 9的AWS EC2实例。
要与Redis主机一起使用,将使用三个域名——redis-0.setevoy.org.ua用于主服务器,redis-1.setevoy.org.ua和redis-2.setevoy.org.ua用于其两个从服务器。
最小设置中的从机只能是一个,但这里的第二个例子将是哨兵——让我们从一开始就有三个。
基本主从复制
这样,从机将成为主机的只读从机,保留将添加到主机中的相同数据。
主机将向其从机发送所有数据更新——新密钥到期等。
如果主机和从机之间的链路断开——从机将尝试重新连接到主机并进行部分同步以从先前同步被中断的位置更新数据。
如果不能进行这种部分同步——从机将要求主机进行完全同步,并且主机将执行其数据完整快照,该快照将被发送到该从机,此后,将恢复通常的同步。
这里有几点需要注意:
- 一个主机可以拥有多个从机
- 从机可以接受来自其他从机的连接,使得复制节点的“级联”——顶部的主机,中间的从机和底部的从机
- 强烈建议在主服务器上启用数据持久性以避免数据丢失——请参阅主服务器关闭持久性时的复制安全性
- 默认情况下,从机将以只读模式工作,请参阅只读从机
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 yes和appendfilename "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——设置主服务器的主机和端口
- 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
授权:
127.0.0.1:6379> auth foobared
OK
禁用slave-role:
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哨兵
现在让我们将哨兵添加到我们的复制中,它将监视Redis节点并自动执行角色切换。
整个计划将是下一个:
这里:
- M1 =主机
- R1 =复制 1 /从机1
- R2 =复制 2 /从机2
- S1 =哨兵 1
- S2 =哨兵 2
- S3 =哨兵 3
M1和S1——将对应redis-0,R 1和S2——对应redis -1,R 2和S3——对应redis-2。
运行哨兵
要运行哨兵守护程序,redis-server只能使用单独的配置——/etc/redis/哨兵.conf。
首先,让我们在Redis Master主机上创建这样的配置文件:
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是哨兵的实例编号来决定
- 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端口检查哨兵的状态:
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——它有两个从机
- 哨兵s=1——目前只运行一个哨兵实例
您可以在这里获得一些基本信息,例如——主机的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"
现在使用与我们在主机和哨兵日志中执行的配置相同的配置重复两个从机上的哨兵启动,您必须看到连接的新实例:
...
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
哨兵s=3——好的。
此外,哨兵将在需要时执行自己的设置更新:
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
这是添加的哨兵myid fdc750c7d6388a6142d9e27b68172f5846e75d8c以及#CONFIG REWRITE生成的整个块。
Redis 哨兵自动故障转移
现在让我们来看看如果主机会失败将会发生什么。
您可以通过调用kill -9或使用redis-cli和以及DEBUG以秒为单位发送命令来手动执行此操作,以使主机“关闭”或通过发送信号来杀死主机。
root@redis-0:/home/admin# redis-cli -a foobared DEBUG sleep 30
哨兵登录主机:
...
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
...
哨兵执行从机到主机的重新配置。
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.
让我们杀死一个节点,看看哨兵现在会做什么:
root@redis-0:/home/admin# redis-cli -a foobared DEBUG SEGFAULT
Error: Server closed the connection
日志:
...
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 masters | 列出所有主机及其状态 |
sentinel master | 一个主机的身份 |
sentinel slaves | 列出所有从机及其状态 |
sentinel sentinels | 列出所有哨兵实例及其状态 |
sentinel failover | 手动运行故障转移 |
sentinel flushconfig | 强制哨兵重写其在磁盘上的配置 |
sentinel monitor | 添加一个新的主机 |
sentinel remove | 从被检测中移除主机 |
相关链接
原文地址:https://www.codeproject.com/Articles/1328499/Redis-Replication-Part-2-Master-Slave-Replication