一、Redis Replication
复制的配置很简单:>slaveof <主数据库IP> <端口>
默认情况下从库是只读的,不能进行修改,需要修改需要设置配置文件中的slave-read-only为no
master不可用,sentinel会根据slave-priority优先级选举master
2)原理(执行步骤)
①从数据库向主数据库发送sync命令。
②主数据库接收sync命令后,执行BGSAVE命令(保存快照),创建一个RDB文件,在创建RDB文件期间的命令将保存在缓冲区中。
③当主数据库执行完BGSAVE时,会向从数据库发送RDB文件,而从数据库会接收并载入该文件。
④主数据库将缓冲区的所有写命令发给从服务器执行。
⑤以上处理完之后,之后主数据库每执行一个写命令,都会将被执行的写命令发送给从数据库。
二、redis sentinel
sentinel就是一个监视器
启动sentinel:
redis-sentinel /path/to/sentinel.conf
sentinel配置文件:
#格式:sentinel <option_name> <master_name> <option_value>;
该行的意思是:监控的master的名字叫做T1(自定义),地址为127.0.0.1:10086,行尾最后的一个2代表在sentinel集群中,多少个sentinel认为masters死了,才能真正认为该master不可用了。
sentinel monitor T1 127.0.0.1 10086 2
#sentinel会向master发送心跳PING来确认master是否存活,如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了(subjectively down, 也简称为SDOWN)。而这个down-after-milliseconds就是用来指定这个“一定时间范围”的,单位是毫秒,默认30秒。
sentinel down-after-milliseconds T1 15000
#发生切换之后执行的一个自定义脚本:如发邮件、vip切换等
##sentinel notification-script <master-name> <script-path> ##不会执行,疑问?
#sentinel client-reconfig-script <master-name> <script-path> ##这个会执行
2)原理
①sentinel集群通过给定的配置文件发现master,启动时会监控master。通过向master发送info信息获得该服务器下面的所有从服务器。
②sentinel集群通过命令连接向被监视的主从服务器发送hello信息(每秒一次),该信息包括sentinel本身的ip、端口、id等内容,以此来向其他sentinel宣告自己的存在。
③sentinel集群通过订阅连接接收其他sentinel发送的hello信息,以此来发现监视同一个主服务器的其他sentinel;集群之间会互相创建命令连接用于通信,因为已经有主从服务器作为发送和接收hello信息的中介,sentinel之间不会创建订阅连接。
④sentinel集群使用ping命令来检测实例的状态,如果在指定的时间内(down-after-milliseconds)没有回复或则返回错误的回复,那么该实例被判为下线。
⑤当failover主备切换被触发后,failover并不会马上进行,还需要sentinel中的大多数sentinel授权后才可以进行failover,即进行failover的sentinel会去获得指定quorum个的sentinel的授权,成功后进入ODOWN状态。如在5个sentinel中配置了2个quorum,等到2个sentinel认为master死了就执行failover。
⑥sentinel向选为master的slave发送SLAVEOF NO ONE
命令,选择slave的条件是sentinel首先会根据slaves的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从master接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程ID较小的。
⑦sentinel被授权后,它将会获得宕掉的master的一份最新配置版本号(config-epoch),当failover执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它sentinel,其它的sentinel则更新对应master的配置。
三、redis cluster搭建
1、创建集群目录
首先进入一个新目录,创建六个以端口号为名字的子目录。
1 2 3 | $ mkdir redis-cluster $ cd redis-cluster $ mkdir 9001 9002 9003 9004 9005 9006 |
2、添加集群配置文件
在文件夹9001~9006中各建一个redis.conf文件,修改对应文件夹的端口,内容如下:
1 2 3 4 5 | port 9001 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes |
-
cluster-enabled:用于开实例的集群模式
-
cluster-conf-file:设定了保存节点配置文件的路径,默认值为nodes.conf,节点配置文件无须人为修改,它由 Redis集群在启动时创建, 并在有需要时自动进行更新。
要让集群正常运作至少需要三个主节点,不过在刚开始试用集群功能时, 强烈建议使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。
3、添加redis服务文件
把编译好的redis-server文件复制到redis-cluster文件夹中。
4、启动集群实例
进入到9001~90066每个目录下,启动每个实例:
1 2 | $ cd 9001 $ ../redis-server ./redis.conf |
5、创建集群
现在我们已经有了六个正在运行中的Redis实例,接下来我们需要使用这些实例来创建集群,并为每个节点编写配置文件。通过使用Redis集群命令行工具redis-trib,编写节点配置文件的工作可以非常容易地完成:redis-trib位于Redis源码的src文件夹中,它是一个Ruby程序,这个程序通过向实例发送特殊命令来完成创建新集群,检查集群,或者对集群进行重新分片(reshared)等工作。
1 | $ ./redis-trib.rb create --replicas 1 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005 127.0.0.1:9006 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | >>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 Adding replica 127.0.0.1:9004 to 127.0.0.1:9001 Adding replica 127.0.0.1:9005 to 127.0.0.1:9002 Adding replica 127.0.0.1:9006 to 127.0.0.1:9003 M: bd330d41ffcc57a5a5d32e3f738ddf82c48cfed0 127.0.0.1:9001 slots:0-5460 (5461 slots) master M: 688b8cdbdc38fe6b9e81b410aae2f1c048f5907c 127.0.0.1:9002 slots:5461-10922 (5462 slots) master M: 33b757db6091e486af2032f1463d1fb07e8e89a7 127.0.0.1:9003 slots:10923-16383 (5461 slots) master S: b00b464e4deb93a661755923641d36cadf648fcd 127.0.0.1:9004 replicates bd330d41ffcc57a5a5d32e3f738ddf82c48cfed0 S: b3ec3a9c125cf168807231a16bacab946974d563 127.0.0.1:9005 replicates 688b8cdbdc38fe6b9e81b410aae2f1c048f5907c S: 06a207f7a4dd3023f88e01fad8635cb471d004eb 127.0.0.1:9006 replicates 33b757db6091e486af2032f1463d1fb07e8e89a7 Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join.... >>> Performing Cluster Check (using node 127.0.0.1:9001) M: bd330d41ffcc57a5a5d32e3f738ddf82c48cfed0 127.0.0.1:9001 slots:0-5460 (5461 slots) master 1 additional replica(s) S: 06a207f7a4dd3023f88e01fad8635cb471d004eb 127.0.0.1:9006 slots: (0 slots) slave replicates 33b757db6091e486af2032f1463d1fb07e8e89a7 S: b00b464e4deb93a661755923641d36cadf648fcd 127.0.0.1:9004 slots: (0 slots) slave replicates bd330d41ffcc57a5a5d32e3f738ddf82c48cfed0 M: 688b8cdbdc38fe6b9e81b410aae2f1c048f5907c 127.0.0.1:9002 slots:5461-10922 (5462 slots) master 1 additional replica(s) S: b3ec3a9c125cf168807231a16bacab946974d563 127.0.0.1:9005 slots: (0 slots) slave replicates 688b8cdbdc38fe6b9e81b410aae2f1c048f5907c M: 33b757db6091e486af2032f1463d1fb07e8e89a7 127.0.0.1:9003 slots:10923-16383 (5461 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. |
这表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运作正常。
6、查看集群节点
1 2 3 4 5 6 7 | 192.168.10.38:9001> cluster nodes bd330d41ffcc57a5a5d32e3f738ddf82c48cfed0 127.0.0.1:9001@19001 myself,master - 0 1511774435000 1 connected 0-5460 06a207f7a4dd3023f88e01fad8635cb471d004eb 127.0.0.1:9006@19006 slave 33b757db6091e486af2032f1463d1fb07e8e89a7 0 1511774436000 6 connected b00b464e4deb93a661755923641d36cadf648fcd 127.0.0.1:9004@19004 slave bd330d41ffcc57a5a5d32e3f738ddf82c48cfed0 0 1511774436557 4 connected 688b8cdbdc38fe6b9e81b410aae2f1c048f5907c 127.0.0.1:9002@19002 master - 0 1511774436557 2 connected 5461-10922 b3ec3a9c125cf168807231a16bacab946974d563 127.0.0.1:9005@19005 slave 688b8cdbdc38fe6b9e81b410aae2f1c048f5907c 0 1511774436657 5 connected 33b757db6091e486af2032f1463d1fb07e8e89a7 127.0.0.1:9003@19003 master - 0 1511774436000 3 connected 10923-16383 |
连接使用集群
1 | $ ./redis-cli -c -h 192.168.1.8 -p 9002 -a 123456 |
-c:cluster,连接到集群模式,否则key不落在本实例将会报错。
-h:host,指定连接主机。
-p:port,指定连接端口。
-a:auth,指定密码,集群模式需要指定,不然移动会认证失败。
1 2 3 4 | $ ./redis-cli -c -h 192.168.1.8 -p 9002 -a 123456 127.0.0.1:9002> set hnad 21233 -> Redirected to slot [2114] located at 127.0.0.1:9001 OK |
如上,键hnad被转移到实例9001。
主从复制不能同步问题解决
搭建一个3主3从的Redis Cluster集群发现从实例不能同步主实例的数据,但确认搭建的步骤和参数都没啥问题啊,官网也没有给出对应的问题解决方案。
解决方案
后来查各种资料发现,是因为主实例设置了密码,从实例配置中需要配置主实例的连接密码才能实现主从复制同步。
就是下面这个配置:
1 2 3 4 5 6 | # If the master is password protected (using the "requirepass" configuration # directive below) it is possible to tell the slave to authenticate before # starting the replication synchronization process, otherwise the master will # refuse the slave request. # # masterauth <master-password> |
翻译:
1 | 如果master是密码保护的,下面的配置就是可以告诉从实例在启动集群同步复制进程之前要经过认证,否则主实例会拒绝从实例的请求。 |
解决流程
所以,要解决不同步问题,先停止6个从实例,然后在每个实例的redis.conf文件中加入对应主备实例的认证密码,然后再启动各个从实例。如:
1 | masterauth 123456 |
然后主实例上的数据实时变化都会同步到从实例,问题解决。
参考文章:
https://www.cnblogs.com/zhoujinyi/p/5570024.html
http://www.javastack.cn/article/2018/redis-cluster-linux-install/