1、RDB和AOF的优缺点
RDB 优点
1. RDB快照保存了某个时间点的数据,可以通过脚本执行redis指令bgsave(非阻塞,后台执行)或者save(会阻塞写操作,不推荐)命令自定义时间点备份,可以保留对个备份,当出现问题可以恢复到不同时间点的版本,很适合备份,并且此文件格式也支持有不少第三方工具可以进行后续的数据分析
比如:可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一填,也备份一个RDB文件。这样的话,即使遇上问题,也可以随时将数据还原到不同的版本
2. RDB可以最大化redis的性能,父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘I/O工作
3. RDB在大量数据,比如几个G的数据,恢复速度不AOF快
RDB 缺点
1.不能实时的保存数据,可能会丢失自上次执行RDB备份到当前的内存数据
2.当数据量非常大的时候,从父进程fork子进程进行保存RDB文件时需要一点时间,可能是毫秒或者秒,取决于磁盘的I/O性能
在数据集比较庞大时,fork()可能会非常耗时,造成服务器在一定时间内停止处理客户端,如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒或者更久,虽然AOF重写也需要进行fork(),但无论AOF重写的执行时间间隔有多长,数据的持久性都不会有任何损失
AOF 优点
1.数据安全性相对比较高,根据所使用的fsync
策略(fsync是同步内存中redis所有修改的文件到存储设备),默认是appendfsync everysec,即每秒执行一次fsync,在这种配置中,redis仍然可以保持良好的性能,并且就算发生故障停机,也最多值会丢失一秒钟的数据(fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)
2.由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中不需要seek,即使出现宕机现象,也不会破坏日志文件中已经存在的内容,然而本次操作只写入了一半数据就出现系统崩溃问题,不用担心,在redis下次启动之前,可以通过redis-check-aof工具来解决数据一致性问题
3.redis可以在AOF文件体积过大时,自动的在后台对AOF进行重写,重写后的AOF文件包含了恢复当前数据集所需要的最小命令集合,整个重写操作是绝对安全的,因为redis在创建新AOF文件的过程中,append模式不断的将修改的数据追加到现有的AOF文件里面,即使重写过程中发生停机,现有的AOF文件也不会丢失,而一旦新的AOF文件创建完毕,redis就会从旧AOF文件切换到新的AOF文件,并开始对新的AOF文件进行追加操作
4.AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,也可以通过该文件完成数据的重建
AOF文件有序的保存了对数据库执行的所有写入操作,这些写入操作以redis协议的格式保存,因此AOF文件的内容非常容易读懂,对文件进行分析(parse)也很轻松。导出(export)AOF文件也非常简单。如果你不小心执行了flushall命令,只要AOF文件未被重写,那么只要停止服务器,移除AOF文件末尾的flushall命令,并重启redis,就可以将数据集恢复到flushall执行之前的状态
AOF 缺点
1.即使有些操作是重复的也会全部记录,AOF的文件大小要大于RDB文件
2.AOF在恢复大量数据集时的速度比RDB恢复速度慢
3.根据fsync策略不同,AOF速度可能会慢于RDB
4.bug出现的可能性更多
2、master和slave同步过程
redis主从同步分为2种:全量同步和增量同步
- 从服务器连接主服务器,发送psync命令
- 主服务器收到psync命令后,开始执行bgsave命令生成RDB快照文件并使用缓冲区记录此后执行的所有写命令
- 主服务器bgsave执行完后,向所有从服务器发送RDB快照文件,并在发送期间继续记录被执行的写命令
- 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照至内存
- 主服务器快照发送完毕后,开始向从服务器发送缓冲区中的写命令
- 从服务器完成对快照的载入,开始接收命令请求,并执行来着主服务器缓冲区的写命令
- 后期同步会发送自己slave_repl_offset位置,只同步新增加的数据,不再全量同步
3、哨兵的使用和实现机制
哨兵(sentinel)是一个分布式系统,可以在一个构架中运行多个哨兵进程,这些进程使用留言协议(gossip protocols)来接收关于master主服务器是否下线的的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个slave作为新的master
每个哨兵进程会向其他哨兵、master、slave定时发送信息,以确定对方是否活着,如果发现对方在指定配置时间(此项可可配置)内未得到回应,则暂时认为对方已离线,也就是所谓的主观认为宕机(主观:是每个成员都具有的独自的而且可能相同也可能不同的意识)),subjective down,简称SDOWN
有主观宕机,对应的有客观宕机。当哨兵群众多数sentinel进程在对master主服务器作出SDOWN的判断,并且通过sentinel is-master-down-by-addr 命令相互交流,得出master server下线的判断,这种方式为客观宕机(客观:是不依赖于某种意识而已经实际存在的一切事物),objectively down简称ODOWN
通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为master服务器节点,然后自动修改相关配置,并开启故障转移(failover)
sentinel 机制可以解决master和slave角色的自动切换问题,但单个master的性能瓶颈问题无法解决,
redis sentinel中的sentinel节点个数应该大于或者等于3最好为奇数
客户端初始化时连接的sentinel节点集合,不再是具体的redis节点,但sentinel只配置中心不是代理
redis sentinel节点域普通redis没有区别,要实现读写分类依赖于客户端程序
安装前准备
准备三台服务器
master:10.0.0.8
slave:10.0.0.18,10.0.0.28
#第一步:实现主从
#在所有主从节点执行
[root@centos8 ~]#dnf -y install redis
[root@centos8 ~]#vim /etc/redis.conf
....
bind 0.0.0.0
masterauth 123456
requirepass 123456
......
#在从节点实现主从
[root@centos8 ~]#vim /etc/redis.conf
replicaof 10.0.0.8 6379
#在所有主从执行
[root@centos8 ~]#systemctl enable --now redis
#第二步 编辑哨兵的配置文件
[root@redis-master ~]#grep -vE "^#|^$" /etc/redis-sentinel.conf
....
sentinel monitor mymaster 10.0.0.8 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 3000
....
[root@redis-master ~]#scp /etc/redis-sentinel.conf 10.0.0.18:/etc/
[root@redis-master ~]#scp /etc/redis-sentinel.conf 10.0.0.28:/etc/
#第三步 启动哨兵
[root@redis-master ~]#systemctl enable --now redis-sentinel.service
[root@redis-slave1 ~]#systemctl enable --now redis-sentinel.service
[root@redis-slave2 ~]#systemctl enable --now redis-sentinel.service
4、redis cluster集群创建和使用
安装前准备
六台主机
10.0.0.8
10.0.0.18
10.0.0.28
10.0.0.38
10.0.0.48
10.0.0.58
#修改配置文件,启动
[root@centos8 ~]#vim /etc/redis.conf
....
bind 0.0.0.0
masterauth 123456
requirepass 123456
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-require-full-coverage no
....
[root@centos8 ~]#redis-cli -a 123456 --cluster create 10.0.0.8:6379 10.0.0.18:6379 10.0.0.28:6379 10.0.0.38:6379 10.0.0.48:6379 10.0.0.58:6379 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.38:6379 to 10.0.0.8:6379
Adding replica 10.0.0.48:6379 to 10.0.0.18:6379
Adding replica 10.0.0.58:6379 to 10.0.0.28:6379
M: 9e53fb8dcda2392765e2a55644b46a5f8f231289 10.0.0.8:6379
slots:[0-5460] (5461 slots) master
M: 0072153fa264ce6b64e1633e7fb0122e95804a71 10.0.0.18:6379
slots:[5461-10922] (5462 slots) master
M: 5e66e0c460398cc8638d272b7c35aac4e066f333 10.0.0.28:6379
slots:[10923-16383] (5461 slots) master
S: d76e9eb5c09a6899874390ed38bb2db3161db17d 10.0.0.38:6379
replicates 9e53fb8dcda2392765e2a55644b46a5f8f231289
S: a8a1e9f096ebda100948662f48ea82a27e68b2fd 10.0.0.48:6379
replicates 0072153fa264ce6b64e1633e7fb0122e95804a71
S: 5fc7dd628907e6ca8b9a72570d4db412f8fdd1ba 10.0.0.58:6379
replicates 5e66e0c460398cc8638d272b7c35aac4e066f333
Can I set the above configuration? (type 'yes' to accept): yes
[root@redis-node1 ~]#redis-cli -a 123456 CLUSTER INFO
Warning: Using a password with '-a' or '-u' option on the command line interface
may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6 #节点数
cluster_size:3 #三个集群
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:837
cluster_stats_messages_pong_sent:811
cluster_stats_messages_sent:1648
cluster_stats_messages_ping_received:806
cluster_stats_messages_pong_received:837
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1648
#查看任意节点的集群状态
[root@redis-node1 ~]#redis-cli -a 123456 --cluster info 10.0.0.38:6379
Warning: Using a password with '-a' or '-u' option on the command line interface
may not be safe.
10.0.0.18:6379 (99720241...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.28:6379 (d34da866...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.8:6379 (cb028b83...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
#查看集群node对应关系
[root@redis-node1 ~]#redis-cli -a 123456 CLUSTER NODES
Warning: Using a password with '-a' or '-u' option on the command line interface
may not be safe.
9875b50925b4e4f29598e6072e5937f90df9fc71 10.0.0.58:6379@16379 slave
d34da8666a6f587283a1c2fca5d13691407f9462 0 1582344815790 6 connected
f9adcfb8f5a037b257af35fa548a26ffbadc852d 10.0.0.38:6379@16379 slave
cb028b83f9dc463d732f6e76ca6bbcd469d948a7 0 1582344811000 4 connected
d04e524daec4d8e22bdada7f21a9487c2d3e1057 10.0.0.48:6379@16379 slave
99720241248ff0e4c6fa65c2385e92468b3b5993 0 1582344815000 5 connected
99720241248ff0e4c6fa65c2385e92468b3b5993 10.0.0.18:6379@16379 master - 0 1582344813000 2 connected 5461-10922
d34da8666a6f587283a1c2fca5d13691407f9462 10.0.0.28:6379@16379 master - 0 1582344814780 3 connected 10923-16383
cb028b83f9dc463d732f6e76ca6bbcd469d948a7 10.0.0.8:6379@16379 myself,master - 0 1582344813000 1 connected 0-5460
#经过算法计算,当前key的槽位需要写入指定的node
[root@redis-node1 ~]#redis-cli -a 123456 -h 10.0.0.8 SET key1 values1
Warning: Using a password with '-a' or '-u' option on the command line interface
may not be safe.
(error) MOVED 9189 10.0.0.18:6379 #槽位不在当前node所以无法写入