REDIS - 主从复制(三) 2021-08-22 19:53 本文介绍了使用redis时如何搭建主从环境。主从复制是指多个redis服务联合起来,有的作为主服务,有的作为从服务;从服务从主服务获取数据,且主服务能读写,从服务只能读。 > 以下基于redis-6.2.1版本,系统为centos7 64位 > > 官方文档:http://www.redis.cn/documentation.html ### 1、创建配置文件 进入myredis目录,创建一个配置文件,写入必要内容,然后拷贝出另外两份,并修改内容。 ```shell cd /myredis/ vim redis6379.conf //写入以下内容 include /myredis/redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb //写入内容end cp redis6379.conf redis6380.conf cp redis6379.conf redis6381.conf //修改redis6380.conf里面6379的改为6380 vim redis6380.conf //修改redis6381.conf里面6379的改为6381 vim redis6381.conf ``` 最终得到三份文件:  ### 2、启动redis服务 在/myredis目录下启动三台redis服务器,并查看机器信息: redis-server redis6379.conf redis-server redis6380.conf redis-server redis6381.conf  检查是否启动成功:ps -ef | grep redis  分别连接三台redis,并查看主从复制相关信息: redis-cli -p 6379 info replication  redis-cli -p 6380 info replication  redis-cli -p 6381 info replication  启动的redis服务端默认都是master主库。 此时可以在6379上面存一写数据,等会主从配置好后看是否会同步过去:set name hanxu  这个时候查看6380和6381,上面都是没有数据的:  ### 3、配置从库 > slaveof ip port 成为某个实例的从服务器 在6380和6381客户端连接上执行命令:slaveof 127.0.0.1 6379 ,返回OK  此时,主机(6379)上之前的数据都会被同步到两台从机(6380、6381)上,可以keys *看下我们之前在6379上面存的name hanxu有没有被同步过来:  可以看到之前的数据都自动同步到了两条从库上。 ### 4、主从效果 > 主机写数据,从机即可读到主机的数据。主机可读写,从机只能读。 这时再在主机(6379)上写数据,在从机(6380、6381)就可以读取到:  而在从机上写数据,就会报错:(error) READONLY You can't write against a read only replica.  主从复制效果图:  ### 5、主从原理 当一个正常redis服务执行slaveof ip port,会尝试连接对应ip port(主redis服务),连接上主服务后,从机就会向主机发送数据同步消息,请求同步数据。 主机收到同步消息后,会把主服务器数据进行一次持久化,存为磁盘rdb文件;然后把rdb文件发送给从服务器,从服务器就可以拿到rdb文件读取以完成数据全量同步。 此后,每次主服务器进行写操作后,会将命令传给从服务器以完成增量数据同步。 主从数据同步过程:  **总结:1、从连接并发起请求,主全量推送数据;2、主增量同步写命令。** 所以主从复制是主进行同步的,从只是负责发起请求。 问题和思考: 由于主进行数据同步,当从服务器很多的时候,主进行数据同步的压力就会很大,需要向每个从机发送数据同步文件或命令。那为什么不多来几个主机,分担下压力呢?实际是不能的,如果有多个redis服务都是主服务器,那么从服务器就不知道以哪个主服务器的数据为准了。但是这个思想是可取的,所以就变了个法子——在从机中搞几个可以同步数据的服务器,作为从机的小领导,分担主机同步数据的压力。这些机器仍然是从机,不能写数据,只不过他们可以给其他从机同步数据。这就是后面要说的薪火相传。 ### 6、主从特性 #### 特性①、一主二仆 > 一主二仆突出的是主和仆的关系,即主服务器无论如何是主,从服务器无论如何是从。 > > 主机down后从机不上位,从机正常读。主机重新启动后,仍是主机,主从关系不改变。 > > 而从机down后,再次启动后变成了主机,不过并没有机器slave它。此时需要再次执行slave ip port让他slave于主机。(通过配置文件将salve ip port写入redis.conf中,这样从机即使down掉,重启之后仍然立即是主机的slave。可以实现真正的“一主二仆”效果) 在主机执行shutdown, exit, 主机宕机,观察从机info replication信息:从机还是从机,但是检测到了主机down的信息。  待主机重启后,还是恢复master的位置,它仍然有两个slave从机:  并且再次进行数据储存,从机仍会正常从主机获取到数据。 从机down后,主机能检测到从机down了,其他的从机和主机的主从复制正常。从机重启后,就是master了,不过并没有机器slave它。  待执行slaveof 127.0.0.1 6379后,重新成为master的从机。重新读取所有数据。  可以将slaveof 127.0.0.1 6379写入redis6380.conf配置文件中,这样以这个配置文件启动的redis,就永远是6379端口的机器的从机(每次启动自动变从机)。当主机down掉时,从机只能读取已有的数据。 #### 特性②、薪火相传 > 从服务器可以从主服务器读取数据,也可以从从服务器读取数据。以减轻主服务器同步数据的压力。 当一台主机有多台从机的话,主机向从机同步数据的压力会很大;为了减轻压力,可以改变一下从机的指向:让某个或某几个从机当“小领导”,“小领导”们直接从主机同步数据;而其余从机slave这些“小领导”,从他们这里同步数据。就像公司各部门分层,老板不可能同时管那么多人,于是就挑几个作为直属下属,下属分别有自己的团队,团队志中可能又有其他小领导。 要注意的是从机不管怎样仍然是从机,他们都不能写数据,只有主机可以写数据。从机有了这些划分,只是让他们同步数据的来源变了,从而减轻主机同步数据的压力。 (这里只用三台服务做演示,并不是说实际业务中一台主只有一个从,一个从下面只有另一个从。可能有多个。)  将6380变为“小领导”,6381从6380同步数据:在6381的客户端执行:slaveof 127.0.0.1 6380,然后查看主从信息:info replication。可以看到他现在已经是6380的从机了,其他都没有变: 在6380客户端执行info replication命令,查看主从信息,可以看到他现在仍是从机;只不过他一边是6379的从机,另一边有一个从服务器连接上了他,并从他这同步数据。下面是前后的info replication对比:  薪火相传指的是这里的“数据”是“火”,“火”一代代传下去。 #### 特性③、反客为主 > 若主服务器挂掉出事故后,为了迅速恢复服务,可以让某个具有从机的从服务器作为新的主机,从而快速恢复整个主从redis服务模式。 当主服务器挂掉后,在从机上面执行slaveof no one,就能把它变成主机。其他从服务器的主从关系不会有任何改变。这个要结合薪火相传一起使用才有效果: (主)6379->(从)6380->(从)6381,当63797挂掉后,在6380上面执行slaveof no one,就能使它变成主机。这样(主)6380->(从)6381就又构建成了一个小型的主从复制。 若是不结合薪火相传:(主)6379->(从)6380,(主)6379->(从)6381。当6379挂掉后,在6380上面执行slaveof no one,它变成了主机,但是也没有其他从机slave它,这样还是一个无效的主从复制区域。 第一台6379的服务上面显示只有一个slave是6380:  第二胎6380服务上面显示它slave于6379,同时6381slave它。  最后一台6381服务上面显示它slave于6380  这样就形成了(主)6379->(从)6380->(从)6381这样的模式,我们此时将6379宕掉:执行shutdown命令,然后exit退出redis客户端:  然后查看(从)6380->(从)6381的主从信息:执行info replication:发现6380的connected_slaves:0 同时6391的master_link_status:down 就是说当真正的master 6379停掉后,6381也不能从6380那里继续同步数据了。  两台从仍可以继续读数据。 在6380上执行slaveof no one,返回OK;再查看info replication,发现它变成了master,6381是它的slave;进行set test 111数据写操作测试,成功了。而6381上也正常同步到了数据:  ### 7、哨兵模式 上述“反客为主”时,需要有人手动执行命令,这样未免太过僵硬。为了使整个redis主从服务自给自足,达到一定的“高可用”程度,可以让这个模式自动起来,这就是哨兵模式。 单独启动一个redis应用作为哨兵服务,它还是用redis启动,但已不再提供正常的redis读写服务了,而是提供哨兵服务。 步骤: > 在搭建哨兵前,先将之前的服务全部停掉。在任意目录下执行redis-cli -p 6379 shutdown,redis-cli -p 6380 shutdown,redis-cli -p 6381 shutdown > > ps -ef | grep redis检查是否没有redis服务在启动 #### ①、启动主从服务 启动服务: redis-server /myredis/redis6379.conf redis-server /myredis/redis6380.conf redis-server /myredis/redis6381.conf  redis-cli -p 6379 redis-cli -p 6380 redis-cli -p 6381 三个都是master:(如果不是这样,那就把你的redis6379.conf,redis6380.conf,redis6381.conf三个配置文件检查一下,还原成我们上面1的步骤中的内容。)  主从配置: 6380上执行:slaveof 127.0.0.1 6379 6381上执行:slaveof 127.0.0.1 6380  达成了(主)6379->(从)6380->(从)6381这样的模式 #### ②、哨兵配置 在/myredis目录下新建sentinel.conf(名字不能错)配置文件,内容为:sentinel monitor mymaster 127.0.0.1 6379 1 ```shell cd /myredis/ vim sentinel.conf //写入内容 并保存退出 sentinel monitor mymaster 127.0.0.1 6379 1 //启动哨兵 redis-sentinel /myredis/sentinel.conf ``` mymaster 是哨兵名称,127.0.0.1 6379是监控的服务,1指的是至少有多少个哨兵同意迁移的数量。  #### ③、模拟 将6379服务shutdown:redis-cli -p 6379 shutdown,观察哨兵日志,大概10~15秒左右会检测并选出新的master  这里哨兵选出了6380作为代替6379的master `+switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380` 再次查看三台机器信息:  6379宕掉了;6380作为了master,并能正常写数据;6381作为salve从6380正常同步数据。 #### 选举策略 哨兵如何从剩余的从机中选取一台机器作为master呢? 有三个选举策略,依次为(优先级1>2>3): - 1、**选择优先级靠前的**,优先级在配置文件中为replica-priority 100(这个配置的值为100和值为80,就选100的那台,由于我们这个值是在公共的redis.conf中,所以这里的三台数值一样) - 2、**选择数据和主机最相近的**(也叫偏移量最小的。主从复制有延迟,当主挂掉后,从服务器复制出来的数据不一定一样。谁有的多选谁) - 3、**选择runid最小的**(启动时生成40位的随机runid) 注意:一旦新的master被选举出来,即使老的master重新启动了,那老的master也会成为新master的从机(因为是哨兵发送命令让这个机器作为从机的,所以这个过程会有延迟)。  可以看到6379启动后,显示作为普通机器,然后又立即变成了从机。 --END--
发表评论