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)
到此,主从+哨兵的集群架构搭建完成
本文分享完毕,感谢支持点赞~~
标签:主从复制,Redis,redis,哨兵,master,usr,172.30,local 来源: https://www.cnblogs.com/mike666/p/14241418.html