• Redis主从复制搭建和哨兵模式


    Redis主从复制原理是什么?


     1.设置了一个从服务器,在连接时它发送了一个SYNC命令,不管它是第一次连接还是再次连接都没有关系

    2.然后主服务器开始后台存储,并且开始缓存新连接进来的修改数据的命令。当后台存储完成后,主服务器把数据文件发送到从服务器,
    从服务器将其保存在磁盘上,然后加载到内存中。然后主服务器把刚才缓存的命令发送到从服务器。这是作为命令流来完成的,并且
    和Redis协议本身格式相同

    3.在Redis服务器工作时连接到Redis端口,发送SYNC命令,会看到一个批量的传输,并且主服务器接收的每一个命令都会通过telnet会话重新发送一遍

    4.当主从服务器之间的连接由于某些原因断开时,从服务器可以自动进行重连接。当有多个从服务器同时请求同步时,主服务器只进行一个后台存储

    5.当连接断开又重新连上之后,一般都会进行一个完整的重新同步,但是从Redis2.8开始,只重新同步一部分也可以

    主从复制的作用

    1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式

    2. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余

    3. 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量

    4. 读写分离:可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库的数量

    5. 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础

    服务器环境说明

    操作系统:Centos 7

    主服务器:172.30.93.122

    从服务器:172.30.93.123

    从服务器:172.30.93.124

    Redis版本:5.0.9

    安装Redis

    三台服务器安装都一样,配置文件有一些不同如下:

    [root@Redis-Node1 ~]# yum -y install tcl gcc gcc-c++  make zlib zlib-devel
    [root@Redis-Node1 ~]# wget https://download.redis.io/releases/redis-5.0.9.tar.gz
    [root@Redis-Node1 ~]# tar zxvf redis-5.0.9.tar.gz -C /usr/local/ && rm -rf redis-5.0.9.tar.gz 
    [root@Redis-Node1 ~]# cd /usr/local/redis-5.0.9/
    [root@Redis-Node1 /usr/local/redis-5.0.9]# make && make install PREFIX=/usr/local/redis
    [root@Redis-Node1 /usr/local/redis-5.0.9]# cp -rf redis.conf /usr/local/redis
    [root@Redis-Node1 /usr/local/redis-5.0.9]# cd /usr/local/redis
    [root@Redis-Node1 /usr/local/redis]# vim redis.conf 
       
    bind 172.30.93.122
    daemonize yes
    protected-mode no
    port 6379 logfile
    /usr/local/redis/logs/redis.log dir /usr/local/redis/data [root@Redis-Node1 /usr/local/redis]# [root@Redis-Node1 /usr/local/redis]# mkdir logs data [root@Redis-Node1 /usr/local/redis]# vim /etc/systemd/system/redis.service [Unit] Description=redis-server After=network.target [Service] Type=forking ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf PrivateTmp=true [Install] WantedBy=multi-user.target [root@Redis-Node1 /usr/local/redis]# [root@Redis-Node1 /usr/local/redis]# systemctl daemon-reload [root@Redis-Node1 /usr/local/redis]# ln -s /usr/local/redis/bin/redis-cli /usr/bin/redis [root@Redis-Node1 /usr/local/redis]# vim /etc/sysctl.conf net.core.somaxconn = 1024 vm.overcommit_memory = 1 [root@Redis-Node1 /usr/local/redis]# [root@Redis-Node1 /usr/local/redis]# sysctl -p [root@Redis-Node1 /usr/local/redis]# vim /etc/rc.local echo never > /sys/kernel/mm/transparent_hugepage/enabled [root@Redis-Node1 /usr/local/redis]# [root@Redis-Node1 /usr/local/redis]# source /etc/rc.local [root@Redis-Node1 /usr/local/redis]# systemctl start redis.service

    唯一不同的就是从服务器的配置文件需要修改一下内容,设置主节点的IP和端口

    从服务器:172.30.93.123配置文件内容:

    [root@Redis-Node2 /usr/local/redis]# vim redis.conf 
       
    bind 172.30.93.123
    daemonize yes
    protected-mode no
    port 6379
    logfile /usr/local/redis/logs/redis.log
    dir /usr/local/redis/data
    replicaof 172.30.93.122 6379
    
    [root@Redis-Node2 /usr/local/redis]#

    从服务器:172.30.93.124配置文件内容:

    [root@Redis-Node3 /usr/local/redis]# vim redis.conf 
       
    bind 172.30.93.124
    daemonize yes
    protected-mode no
    port 6379
    logfile /usr/local/redis/logs/redis.log
    dir /usr/local/redis/data
    replicaof 172.30.93.122 6379
    
    [root@Redis-Node3 /usr/local/redis]#

    检查节点同步

    主节点:

    [root@Redis-Node1 /usr/local/redis]# redis -h 172.30.93.122 -p 6379
    172.30.93.122:6379> INFO replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=172.30.93.123,port=6379,state=online,offset=16982,lag=0
    slave1:ip=172.30.93.124,port=6379,state=online,offset=16982,lag=0
    master_replid:2d051a800702dd2b2c33937a0ae4bbd8f1338285
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:16982
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:16982
    172.30.93.122:6379> set ops dev
    OK
    172.30.93.122:6379> 

    启动节点之后查看到已经有其他数据库的信息,有两个slave连接到master,并且创建数据看slave是否同步

    从节点:

    [root@Redis-Node2 /usr/local/redis]# redis -h 172.30.93.123 -p 6379
    172.30.93.123:6379> INFO replication
    # Replication
    role:slave
    master_host:172.30.93.122
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:7
    master_sync_in_progress:0
    slave_repl_offset:17316
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:2d051a800702dd2b2c33937a0ae4bbd8f1338285
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:17316
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:17316
    172.30.93.123:6379> 
    172.30.93.123:6379> get ops
    "dev"
    172.30.93.123:6379> 

    从节点

    [root@Redis-Node3 /usr/local/redis]# redis -h 172.30.93.124 -p 6379
    172.30.93.124:6379> INFO replication
    # Replication
    role:slave
    master_host:172.30.93.122
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:7
    master_sync_in_progress:0
    slave_repl_offset:17708
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:2d051a800702dd2b2c33937a0ae4bbd8f1338285
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:17708
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:17708
    172.30.93.124:6379> get ops
    "dev"
    172.30.93.124:6379> 

    可以看到两个从节点都是slave状态,并且数据已经同步数据库里。主从同步成功

    主从同步中需要注意几个问题

    1. 在上面的全量同步过程中,master会将数据保存在rdb文件中然后发送给slave服务器,但是如果master上的磁盘空间有效怎么办呢?那么此时全部同步对于master来说将是一份十分有压力的操作了。此时可以通过无盘复制来达到目的,由master直接开启一个socket将rdb文件发送给slave服务器。(无盘复制一般应用在磁盘空间有限但是网络状态良好的情况下)

    2. 主从复制结构,一般slave服务器不能进行写操作,但是这不是死的,之所以这样是为了更容易的保证主和各个从之间数据的一致性,如果slave服务器上数据进行了修改,那么要保证所有主从服务器都能一致,可能在结构上和处理逻辑上更为负责。不过你也可以通过配置文件让从服务器支持写操作。(不过所带来的影响还得自己承担哦)

    3. 主从服务器之间会定期进行通话,但是如果master上设置了密码,那么如果不给slave设置密码就会导致slave不能跟master进行任何操作,所以如果你的master服务器上有密码,那么也给slave相应的设置一下密码吧(通过设置配置文件中的masterauth);

    4. 关于slave服务器上过期键的处理,由master服务器负责键的过期删除处理,然后将相关删除命令已数据同步的方式同步给slave服务器,slave服务器根据删除命令删除本地的key

    哨兵模式

    Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是Redis的高可用性解决方案。sentinel是redis高可用的解决方案,sentinel系统可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。
    sentinel可以让redis实现主从复制,当一个集群中的master失效之后,sentinel可以选举出一个新的master用于自动接替master的工作,集群中的其他redis服务器自动指向新的master同步数据。一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换。
    Sentinel由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

    哨兵工作方式

    1.每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个PING命令
    2.如果一个实例(instance)距离最后一次有效回复PING命令的时间超过 own-after-milliseconds 选项所指定的值,则这个实例会被Sentinel标记为主观下线
    3.如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态
    4.当有足够数量的Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线
    5.在一般情况下,每个Sentinel 会以每10秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
    6.当Master被Sentinel标记为客观下线时,Sentinel 向下线的 Master 的所有Slave发送 INFO命令的频率会从10秒一次改为每秒一次
    7.若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。若Master重新向Sentinel 的PING命令返回有效回复,Master的主观下线状态就会被移除

    搭建哨兵模式

    由于哨兵模式是基于主从复制,所以我们就基于上面的环境搭建

    搭建的环境模式,一主两从三哨兵

    [root@Redis-Node1 ~]# cd /usr/local/redis/
    [root@Redis-Node1 /usr/local/redis]# vim sentinel.conf
    
    port 26379
    
    daemonize yes
    
    protected-mode no
    
    pidfile "/var/run/redis-sentinel.pid"
    
    logfile "/usr/local/redis/logs/sentinel.log"
    
    dir "/usr/local/redis/data"
    
    sentinel monitor mymaster 172.30.93.122 6379 2
    
    # redis主从密码,这里也需要设置
    # sentinel auth-pass mymaster redis2021
    
    sentinel down-after-milliseconds mymaster 3000 
    
    snetinel parallel-syncs mymaster 1 
    
    sentinel failover-timeout mymaster 180000
    
    sentinel deny-scripts-reconfig yes
    
    
    [root@Redis-Node1 /usr/local/redis]# vim /etc/systemd/system/redis-sentinel.service
    
    [Unit]
    Description=Redis sentinel Server
    After=network.target
    
    [Service]
    Type=forking
    PIDFile=/var/run/redis-sentinel.pid
    ExecStart=/usr/local/redis/bin/redis-sentinel /usr/local/redis/sentinel.conf --sentinel
    ExecStop=/usr/local/redis/bin/redis-cli -p 26379 shutdown
    Restart=on-failure
    [Install]
    WantedBy=multi-user.target
    
    [root@Redis-Node1 /usr/local/redis]# systemctl daemon-reload
    [root@Redis-Node1 /usr/local/redis]# systemctl start redis-sentinel

    三台服务器一起执行这些命令就可以了,其他 sentinel.conf 配置文件都是重新生成的(后期如果主的redis  master挂了,配置文件会自动修改)

    配置文件修改说明:
    
    //端口默认为26379 
    port:26379 
    
    //设置为后台启动
    daemonize:yes 
    
    //关闭保护模式,可以外部访问
    protected-mode:no 
    
    //PID文件路径
    pidfile "/var/run/redis-sentinel.pid"
    
    //日志文件路径 
    logfile "/usr/local/redis/logs/sentinel.log"
    
    //数据存放路径
    dir "/usr/local/redis/data"
    
    //指定主机IP地址和端口,并且指定当有2台哨兵认为主机挂了,则对主机进行容灾切换
    sentinel monitor mymaster 172.30.93.122 6379 2 
    
    //redis主从密码,这里也需要设置
    # sentinel auth-pass mymaster redis2021
    
    //这里设置了主机多少秒无响应,则认为挂了 
    sentinel down-after-milliseconds mymaster 3000 
    
    //主备切换时,最多有多少个slave同时对新的master进行同步,这里设置为默认的1
    snetinel parallel-syncs mymaster 1 
    
    //故障转移的超时时间,这里设置为三分钟 
    sentinel failover-timeout mymaster 180000 
    
    //避免了一个简单的安全问题,客户端可以将脚本设置为任何内容并触发故障转移以便执行程序
    sentinel deny-scripts-reconfig yes

    查看哨兵模式同步

    [root@Redis-Node1 ~]# redis -h 172.30.93.122 -p 6379
    172.30.93.122:6379> INFO replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=172.30.93.123,port=6379,state=online,offset=88409,lag=1
    slave1:ip=172.30.93.124,port=6379,state=online,offset=88409,lag=1
    master_replid:2d051a800702dd2b2c33937a0ae4bbd8f1338285
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:88691
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:88691
    172.30.93.122:6379> 
    172.30.93.122:6379> 
    172.30.93.122:6379> get ops
    "dev"
    172.30.93.122:6379> 
    [root@Redis-Node1 ~]# 
    [root@Redis-Node1 ~]# redis -h 172.30.93.122 -p 26379
    172.30.93.122: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=mymaster,status=ok,address=172.30.93.122:6379,slaves=2,sentinels=3
    172.30.93.122:26379>
    
    [root@Redis-Node1 ~]# 

    可以看到,哨兵已经监听到当前的主机IP端口和运行状态,并且有2台从机,3个哨兵。

    模拟故障

    [root@Redis-Node1 ~]# systemctl stop redis

    把Redis主的master停了之后,查看其他节点情况

    [root@Redis-Node2 /usr/local/redis]# redis -h 172.30.93.123 -p 6379
    172.30.93.123:6379> info replication
    # Replication
    role:slave
    master_host:172.30.93.122
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:0
    master_sync_in_progress:0
    slave_repl_offset:128437
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:2d051a800702dd2b2c33937a0ae4bbd8f1338285
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:128437
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:128437
    172.30.93.123:6379> info replication
    # Replication
    role:master
    connected_slaves:1
    slave0:ip=172.30.93.124,port=6379,state=online,offset=151174,lag=0
    master_replid:d20539eba07d1083084387dc8e15f55ce265476f
    master_replid2:2d051a800702dd2b2c33937a0ae4bbd8f1338285
    master_repl_offset:151174
    second_repl_offset:148600
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:151174
    172.30.93.123:6379> 

    现在我们去看三台服务器的情况,发现刚才的主机(172.30.93.122 6379)已经停机了,而哨兵(Sentinel)通过选举机制选举了从机(172.30.93.123 6379)作为了新的主机,还有一个从节点(172.30.93.124 6379)

    到此,主从+哨兵的集群架构搭建完成

    本文分享完毕,感谢支持点赞~~

  • 相关阅读:
    SpringCloud-服务注册与实现-Eureka创建服务注册中心(附源码下载)
    SpringCloud -创建统一的依赖管理
    Mysql、Oracle、SQLServer等数据库参考文档免费分享下载
    DevExpress的图形按钮菜单栏控件WindowsUIButtonPanel的布局、使用和设置按钮的点击事件
    Winform中设置ZedGraph鼠标滚轮缩放的灵敏度以及设置滚轮缩放的方式(鼠标焦点为中心还是图形中心点)
    Winform中设置多条Y轴时新增的Y轴刻度不显示问题解决
    Winforn中设置ZedGraoh的GraphPane恢复到初始比例大小
    Winform中设置ZedGraph多条Y轴时与多条曲线一一对应
    Winform中设置ZedGraph多条Y轴时坐标轴左右显示设置
    一、关于a标签伪类中的visited不起作用问题
  • 原文地址:https://www.cnblogs.com/mike666/p/14241418.html
Copyright © 2020-2023  润新知