主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点?>>> (master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave以读为主。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
127.0.0.1:6379> info replication # 查看当前库的主从信息 # Replication role:master # 单机的reids默认都是主机 connected_slaves:0 master_failover_state:no-failover master_replid:1aa0f71da90b39d6d6d07ed7f539922bb4a75584 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
主从复制的作用主要包括:
一般来说,要将Redis运用于工程项目中,只使用一台Redis是万万不能的(宕机,一主二从)﹐原因如下:
电商网站上的商品,一般都是一次上传,无数次浏览的,说专业点也就是"多读少写"。对于这种场景,我们可以使如下这种架构:
主从复制,读写分离!80%的时候都在读操作!为了减缓服务器压力!架构中经常使用!一主二从
只配置从库
127.0.0.1:6379> info replication # 查看当前库的主从信息 # Replication role:master # 单机的reids默认都是主机 connected_slaves:0 # 从机数量 master_failover_state:no-failover master_replid:1aa0f71da90b39d6d6d07ed7f539922bb4a75584 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
复制三个配置文件 redis.conf,然后修改配置信息
端口
主机密码
pid名字
log日志名字
dump.db名字
修改完毕后我们可以启动三个进程
我这里用的docker启动的 启动命令如下
docker run -itd -p 63879:6379 --name redis6379 -v /usr/local/docker/redis79.conf:/etc/redis/redis79.conf -v /usr/local/docker/data:/data redis redis-server /etc/redis/redis79.conf
只需要修改对应的名字就可以了
如果运行这个命令出现以下错误
这个意思就是你给启动容器的命名已经存在了需要把之前的那个移除就可以了(这里我也是刚学不知道会不会有影响,我的redis没啥东西,如果redis里面有东西的不推荐这个)
docker rm -f 3b8b10501c941b6b37d3422ec330038fb768447fe7425d171ec2481961b05c6e
这样启动三个容器就可以得到三个进程了
默认情况下每台redis服务器都是主节点,我们一般情况下只需要配置从机就好了
一主(79)二从(80,81)
这里有一个坑 如果是阿里云服务器,这里的ip需要换成内网ip,127.0.0.1可能出现问题,从机连接主机日志显示拒绝连接。
这个命令需要在从机上面输入
slaveof ip(默认127.0.0.1,阿里云是内网IP) 6379
注:如果主机设置了密码的话需要在从机的配置文件中添加masterauth 主机密码
属性
主机:79
127.0.0.1:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=172.17.0.1,port=6380,state=online,offset=5852,lag=1 slave1:ip=172.17.0.1,port=6381,state=online,offset=5852,lag=0 master_failover_state:no-failover master_replid:c24d687ead4f9219cad468616cd8b0d524583f49 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:5852 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:5852
从机:80
127.0.0.1:6380> info replication # Replication role:slave master_host:172.25.3.87 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_read_repl_offset:5908 slave_repl_offset:5908 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:c24d687ead4f9219cad468616cd8b0d524583f49 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:5908 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:5908 127.0.0.1:6380> role 1) "slave" 2) "172.25.3.87" 3) (integer) 6379 4) "connected" 5) (integer) 5908
从机:81
127.0.0.1:6381> info replication # 查看信息 # Replication role:slave master_host:172.25.3.87 master_port:6379 master_link_status:up master_last_io_seconds_ago:10 master_sync_in_progress:0 slave_read_repl_offset:5992 slave_repl_offset:5992 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:c24d687ead4f9219cad468616cd8b0d524583f49 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:5992 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1499 repl_backlog_histlen:4494
在真实的开发中主从配置应该在配置文件中配置,只有在配置文件中进行配置后才是永久的,而我使用的是命令进行配置的,是临时的
细节
主机可以设置值,从机不能写只能读 ,主机里面写的值都会被从机保存下来
主机写:
从机只能读,不能写
测试:如果主机宕机了,从机还是会连接到主机的,只不过没有写操作了,还可以照样读取,主机回来,正常写正常读。
但是如果从机关机重启,因为我们是命令设置的,一旦重新启动,就会变回主机,无法获取在宕机期间主机写的值。但是只要变成从机就可以里立马到主机的值。
复制原理
Slave启动成功连接到master后会发送一个sync同步命令
Master接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,并完成一次完全同步。
全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
但是只要是重新连接master,一次完全同步(全量复制)将被自动执行。我们的数据从机一定可以看到
链路模式(套娃)
这时候也可以完成我们的主从复制
如果老大没了,我们需要手动选取一个老大出来、
谋朝篡位
这时候我们可以使用Slave no one
命令将从节点变成主节点,如果诸暨店回来了,我们就需要重新连接
自动选取老大的模式
概述
主从切换技术的方法是︰当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。Redis从2.8开始正式提供了Sentinel (哨兵)架构来解决这个问题。
谋朝篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
这里哨兵模式有两个作用:
当一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此可以使用哨兵进行监控, 各个哨兵之间还会进行监控,这就形成了多哨兵模式。
以上过程:假设主服务器宕机,哨兵1先检测到结果,但是系统并不会马上进行failover过程,仅仅是哨兵1主观认为主服务器不可以用,这个现象称为主观下线,当后面的哨兵也检测到主服务器不可用,并且数量达到一定时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover故障转移操作。
操作转移成功后。就会发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这一过程称为 客观下线
测试
我们目前状态是一主二从
## 自定义集群名,其中 172.17.0.1 为 redis-master 的 ip,6379 为 redis-master 的端口,1 为最小投票数(因为有 1 台 Sentinel 所以可以设置成 1) sentinel monitor myredis 172.17.0.1 6379 1
这个1 ,代表主机挂了,slave投票看让谁接替成为主机,票数最多的就会成为主机
启动
===启动redis命令== docker run -it -d -p 6379:6379 --name redis6379 -v /usr/local/docker/redis79.conf:/etc/redis/redis79.conf -v /usr/local/docker/data:/data redis redis-server /etc/redis/redis79.conf docker run -it -d -p 6380:6380 --name redis6380 -v /usr/local/docker/redis80.conf:/etc/redis/redis80.conf -v /usr/local/docker/data:/data redis redis-server /etc/redis/redis80.conf docker run -it -d -p 6381:6381 --name redis6381 -v /usr/local/docker/redis81.conf:/etc/redis/redis81.conf -v /usr/local/docker/data:/data redis redis-server /etc/redis/redis81.conf docker run -it -d -p 6377:6377 --name redis6377 -v /usr/local/docker/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/data:/data -v /usr/local/docker/sentinel.conf:/etc/redis/sentinel.conf redis redis-server /etc/redis/redis.conf
root@8eb4c8dee583:/usr/local/bin# redis-server /etc/redis/sentinel.conf --sentinel # 我启动哨兵命令 62:X 17 May 2022 09:37:31.305 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 62:X 17 May 2022 09:37:31.305 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=62, just started 62:X 17 May 2022 09:37:31.305 # Configuration loaded 62:X 17 May 2022 09:37:31.306 * monotonic clock: POSIX clock_gettime _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.6 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in sentinel mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 2678 | `-._ `._ / _.-' | PID: 62 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 62:X 17 May 2022 09:37:31.306 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 62:X 17 May 2022 09:37:31.309 # Sentinel ID is 300518c6dfa0977984c123487e52b2a0f71633af 62:X 17 May 2022 09:37:31.309 # +monitor master myredis 172.17.0.1 6379 quorum 1 62:X 17 May 2022 09:37:31.311 * +slave slave 172.17.0.1:6381 172.17.0.1 6381 @ myredis 172.17.0.1 6379 62:X 17 May 2022 09:37:31.313 * +slave slave 172.17.0.1:6380 172.17.0.1 6380 @ myredis 172.17.0.1 6379
当我们的主节点挂了之后 哨兵会自动选举一个从节点当主机 这里选举的是 80从节点
哨兵日志:
如果此时主机回来了,只能归并到新的主机下当从机,这就是哨兵模式的规则
哨兵模式
优点:
缺点:
哨兵模式的全部配置
# Example sentinel.conf # 哨兵sentinel实例运行的端口 默认26379 port 26379 # 哨兵sentinel的工作目录 dir /tmp # 哨兵sentinel监控的redis主节点的 ip port # master-name 可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。 # quorum 配置多少个sentinel哨兵统一认为master主节点失联 那么这时客观上认为主节点失联了 # sentinel monitor <master-name> <ip> <redis-port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 2 # 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提供密码 # 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码 # sentinel auth-pass <master-name> <password> sentinel auth-pass mymaster MySUPER--secret-0123passw0rd # 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒 # sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds mymaster 30000 # 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。 # sentinel parallel-syncs <master-name> <numslaves> sentinel parallel-syncs mymaster 1 # 故障转移的超时时间 failover-timeout 可以用在以下这些方面: #1. 同一个sentinel对同一个master两次failover之间的间隔时间。 #2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。 #3.当想要取消一个正在进行的failover所需要的时间。 #4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了 # 默认三分钟 # sentinel failover-timeout <master-name> <milliseconds> sentinel failover-timeout mymaster 180000 # SCRIPTS EXECUTION #配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。 #对于脚本的运行结果有以下规则: #若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10 #若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。 #如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。 #一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。 #通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,一个是事件的类型,一个是事件的描述。如果sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无法正常启动成功。 #通知脚本 # shell编程 # sentinel notification-script <master-name> <script-path> sentinel notification-script mymaster /var/redis/notify.sh # 客户端重新配置主节点参数脚本 # 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。 # 以下参数将会在调用脚本时传给脚本: # <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port> # 目前<state>总是“failover”, # <role>是“leader”或者“observer”中的一个。 # 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通信的 # 这个脚本应该是通用的,能被多次调用,不是针对性的。 # sentinel client-reconfig-script <master-name> <script-path> sentinel client-reconfig-script mymaster /var/redis/reconfig.sh # 一般都是由运维来配置!