生产中使用Redis往往非单机部署,虽然根据前文已经对redis做了数据持久化处理,但是如果Redis服务宕机,所有的数据操作都将直接进入数据库,如果操作量很大,则相当于出现缓存穿透的现象。故生产中使用Redis一般采取【主从+哨兵】或【主从+读写分离】模式部署。本章节主要讲解【主从】模式,文末将对几种模式做简单比较。
1,主从架构实现及原理
普通的主从架构非常简单,即我们常理解的一主一从或一主多从架构(下文将提供更优化的主从架构),如下图。Redis的数据操作通过主节点操作,再将数据同步到各从节点上。
1.1,主从搭建
主从架构的搭建也非常容易,只需将redis从服务的配置修改即可,本节案例在一台服务器搭建主从。
1,复制主节点redis.conf文件
cp /opt/redis/redis.conf /opt/redis/config/redis-6380.conf
2,修改redis-6380.conf文件
bind 0.0.0.0 // 主节点设置,否则:Error condition on socket for SYNC: Connection refused
port 6380 // 端口
daemonize yes // 后台进程
pidfile /var/run/redis-6380.pid // 后台进程时,redis会把pid进程号写入pidfile配置的文件
logfile "redis-6380.log" // 从节点日志
replicaof 主节点IP 主节点端口 // 表明数据来源的主节点
replica-read-only yes // 配置从节点只读
2,启动从节点
redis-server redis-6380.conf
从节点启动时,会自动同步主节点数据,最终数据是否同步完成(主从数据是否一致),可同过主节点的【info replication】查看,如下图:
1.2,主从工作原理(全量数据同步原理)
1,当作为slave的Redis服务启动后,slave会与master创建一个长连接,用于数据和命令从master传输给slave。连接创建好后,slave向master发送数据同步请求。
2,master收到请求后,对当前时刻的内存数据做持久化(调用【bgsave】),生成RDB文件(当前时刻持久化数据文件),持久化期间master的写操作放在内存的复制缓存区(repl buffer)。
3,master持久化做完后,将RDB文件发送给slave,slave接受并加载数据至内存(此时的master还在接受写操作并记录至repl buffer)。
4,slave加载完成后通知master,master再将repl buffer中的写操作发送给slave,slave接受后执行命令集。
至此主从数据同步完成,后续master节点的所有写操作都将通过长连接直接发送给slave执行一次。
1.3,部分数据同步原理
1.2说的是从节点第一次启动,发送的数据同步请求是【全量数据同步】请求。因全量同步的数据量较大,发送和同步时间较长,故当从节点在同步主节点发来的RDB数据时宕机,或在后续系统使用中宕机,在从节点再次重启时,无需再次进行全量数据同步。Redis提供了部分数据同步机制,原理如下:
1,当主节点有了从节点并创建好连接后,主节点会在内存中创建一块【复制积压缓冲区】(repl_backlog_buffer),即一个FIFO的队列,默认大小1M。该缓冲区的作用是,当主节点有修改数据的操作时,除了将该操作发送给从节点,也会记录在该缓冲区。并更新主节点的同步数据偏移量,即1.1图中的【master_repl_offset】;
2,从节点每秒钟上报自身的的复制偏移量给主节点;
3,当从节点宕机并重启后,向主节点发送【部分数据同步 】请求,该请求中包含从节点当前的,如果主节点的【复制积压缓冲区 】的偏移量包含从节点发送的【复制数据偏移量 】,则直接从【复制数据偏移量 】开始向从节点传输数据,如果不包含,则升级为【全量数据同步】。
2,主从架构优化
上面描述的简单【主-从】架构有个明显的缺点,为保证数据稳定性,如果使用【一主多从】架构,从节点在启动时,主从数据同步会使得主节点压力过大。可以将【一主多从】(即:主-从)优化为【主-从-从】架构,即从节点的主节点也是从节点,如图:
从节点的数据同步压力给到从节点,主节点只需同步少量从节点即可。
注意:上述【主-从】或【主-从-从】架构,生产中是可以直接使用的。一般主从架构都是为了减轻单节点压力,比如读写分离:主节点写,从节点读。但单纯的主从架构读写分离有明显的弊端:
1,数据同步不及时,读取的可能是过期数据;
2,主节点宕机,需人为提高从节点等级变为主节点。
故Redis在主从架构下提供了【哨兵】机制,解决了这些问题,将在下章讲解。