复制的基本原理(全量同步)
1.slave启动时会向master发送sync命令。
2.主数据库接收到sync请求后在后台保存快照,也就是实现RDB持久化,并将保存快照期间接收到的命令缓存起来
3.快照完成后主数据库会将快照文件和所有缓存的命令发送给从数据库
4.从数据库接收后会载入快照文件并执行缓存的命令, 从而完成复制
5.在数据库使用阶段主数据库会自动把每次收到的写命令同步到从服务器
增量同步
redis增量复制是指slave初始化后开始工作时主服务器发生的写操作同步到从服务器的过程。增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
主从刚刚连接时,进行全量同步;全量同步结束后,进行增量同步,如果有需要,slave在任何时候都可以发起全量同步。redis策略是无论如何首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
redis服务器崩溃时数据恢复
1)RDB方式
RDB方式的持久化时通过快照(snapshot)完成的,当符合一定条件时redis会自动将内存中的所有数据进行快照并存储到硬盘上。快照条件在配置文件里配置,由时间和改动的键的个数构成。
save 900 1
redis使用fork函数复制一份当前进程的副本;父进程继续接受并处理客户端命令,子进程开始将内存中的数据写入硬盘中的临时文件;子进程写完所有数据后该临时文件替换旧的RDB文件,快照完成;当执行fork时,操作系统会使用写时复制策略,即fork函数发生一刻父子进程共享同一内存数据,当父进程更改其中某个数据时,操作系统会将该数据复制一份以保障子进程数据不受影响,所以新的RDB文件存储的是执行fork一刻的内存数据。
除了自动快照,可以手动发送save或bgsave命令让redis执行快照。前者是由主进程进行快照,会阻塞其他请求,后者通过fork子进程进行快照操作。
一旦redis异常退出,就会丢失最后一次快照以后更改的所有数据。设置合理的快照发生时间,将数据损失控制在能够接受的范围。如果数据很重要无法承担任何损失,可以使用AOF持久化。
2)AOF方式
默认情况下redis没开启AOF方式持久化,可通过redis.cnf开启appendonly yes开启。在启动redis的时候,会逐个执行AOF中的命令将数据载入到内存。载入速度比RDB慢一些。
开启AOF后每执行一条会更改redis数据的命令,都会将该命令写入硬盘的AOF文件,AOF文件保存位置和RDB文件位置相同,都是通过dir参数设置。默认appendonly.aof
aof方式追加log文件可能导致体积过大,系统重启时aof的方式则加载数据会非常慢。另外每条命令都要写log,reids的读写性能也会有所下降。
redis允许同时开启AOF和RDB,即保证数据安全又使得备份操作容易。重启redis后redis会使用AOF文件来恢复数据,AOF方式持久化可能丢失的数据更少。
断点续传
从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份
master node会在内存中创建一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制
但是如果没有找到对应的offset,那么就会执行一次resynchronization
无磁盘化复制
master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了
repl-diskless-sync
repl-diskless-sync-delay,等待一定时长再开始复制,因为要等更多slave重新连接过来
过期key处理
slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。
异步复制
master每次接收到写命令之后,先在内部写入数据,然后异步发送给slave node