介绍
redis支持复制的功能以实现当一台服务器的数据更新后,自动将新的数据同步到其它数据库。
把数据库分为主数据库master和从数据库slave,当主数据库可以进行读写操作,从数据库一般是只读的,当主数据库数据变化的时候会自动同步给从数据库。
为什么需要复制
- 可以实现读写分离,从而提高系统业务处理性能。
- 方便在主数据库奔溃时的数据恢复
配置
复制的配置方式非常简单,只需要在从数据库上配置 slaveof <masterip> <masterport>
即可。主数据库不用作任何改变。
测试环境的搭建
- 方法一:安装三个虚拟机,并分别安装redis。
- 方法二:在同一台虚拟机上运行多个redis实例,但是要通过配置文件进行区分。
- 复制一份redis.conf并命名于
redis_6378.conf
- 修改复制出来的配置文件中的内容
port 6378
unixsocket /tmp/redis_6378.sock
pidfile /var/run/redis_6378.pid
logfile "log_6378.log"
dbfilename dump_6378.rdb
appendfilename "appendonly_6378.aof"
- 复制一份redis.conf并命名于
假设你和我一样有两个redis实例,主实例端口为6378,从实例端口为6379。你需要在 redis_6379.conf
中配置主实例的地址以完成复制的配置。(如果你安装了三台虚拟机,则通过IP就可以做区分。)
redis_6379.conf
# slaveof <masterip> <masterport>
slaveof 127.0.0.1 6378
- 保存配置文件并重启redis实例,在日志中可以看到配置成功的信息。
5581:S 04 Jul 10:55:40.606 * Connecting to MASTER 127.0.0.1:6378
5581:S 04 Jul 10:55:40.606 * MASTER <-> SLAVE sync started
5581:S 04 Jul 10:55:40.607 * Non blocking connect for SYNC fired the event.
5581:S 04 Jul 10:55:40.607 * Master replied to PING, replication can continue...
5581:S 04 Jul 10:55:40.607 * Partial resynchronization not possible (no cached master)
5581:S 04 Jul 10:55:40.613 * Full resync from master: 268a828c8f410ce4abeda4f8425bd846bb568170:1
5581:S 04 Jul 10:55:40.664 * MASTER <-> SLAVE sync: receiving 76 bytes from master
5581:S 04 Jul 10:55:40.664 * MASTER <-> SLAVE sync: Flushing old data
5581:S 04 Jul 10:55:40.664 * MASTER <-> SLAVE sync: Loading DB in memory
5581:S 04 Jul 10:55:40.665 * MASTER <-> SLAVE sync: Finished with success
复制的基本操作命令
info replication
查看复制节点的相关信息slaveof host port
可在运行期间修改slave节点的信息,如果该数据库已经是某个主数据库的从数据库,那么会停止和原主数据库的同步关系,转而和新的主数据库同步。slaveof no one
使当前数据库停止与其他数据库的同步,转成主数据库
复制的基本原理
- slave启动时会向master发送sync命令(2.8版后发送psync以实现增量复制)
- 主数据库接到sync请求后在后台保存快照,也就是实现RDB持久化,并将保
存快照期间接收到的命令缓存起来。 - 快照完成后主数据库会将快照文件和所有缓存的命令发送给从数据库
- 从数据库接收后会载入快照文件并执行缓存的命令,从而完成复制的初始化。
- 在数据库使用阶段主数据库会自动把每次收到的写命令同步到从服务器。
配置文件中复制部分
slaveof
指定某一个redis作为另一个redis的从服务器,通过指定IP和端口来设置主redis。建议为从redis设置一个不同频率的快照持久化的周期,或者为从redis配置一个不同的服务端口。masterauth
如果主redis设置了验证密码的话(使用requirepass来设置),则在从redis的配置中要使用masterauth来设置校验密码,否则主redis会拒绝从redis的访问请求。slave-serve-stale-data
设置当从redis失去了与主redis的连接,或者主从同步正在进行中时,redis该如何处理外部发来的访问请求。
- 如果设置为yes(默认)则从redis仍会继续响应客户端的读写请求。
- 如果设置为no,则从redis会对客户端的请求返回
SYNC with master in progress
,当然也有例外,当客户端发来INFO请求和SLAVEOF请求,从redis还是会进行处理。 - 从redis2.6版本之后,默认从redis为只读。
slave-read-only
设置从Redis为只读repl-ping-slave-period
设置从redis会向主redis发出PING包的周期,默认是10秒。repl-timeout
设置主从同步的超时时间,要确保这个时限比repl-ping-slave-period
的值要大,否则每次主redis都会认为从redis超时。repl-disable-tcp-nodelay
设置在主从同步时是否禁用TCP_NODELAY,如果开启,那么主redis会使用更少的TCP包和更少的带宽来向从redis传输数据。但是这可能会增加一些同步的延迟,大概会达到40毫秒左右。如果关闭,那么数据同步的延迟时间会降低,但是会消耗更多的带宽。repl-backlog-size
设置同步队列长度。队列长度(backlog)是主redis中的一个缓冲区,在与从redis断开连接期间,主redis会用这个缓冲区来缓存应该发给从redis的数据。这样的话,当从redis重新连接上之后就不必重新全量同步数据,只需要同步这部分增量数据即可。repl-backlog-ttl
设置主redis要等待的时间长度,如果主redis等了这么长时间之后,还是无法连接到从redis,那么缓冲队列中的数据将被清理掉。设置为0,则表示永远不清理。默认是1个小时。slave-priority
设置从redis优先级。在主redis持续工作不正常的情况,优先级高的从redis将会升级为主redis。而编号越小优先级越高。当优先级被设置为0时,这个从redis将永远也不会被选中。默认的优先级为100。min-slaves-to-write
设置执行写操作所需的最少从服务器数量,如果至少有这么多个从服务器, 并且这些服务器的延迟值都少于min-slaves-max-lag
秒, 那么主服务器就会执行客户端请求的写操作。min-slaves-max-lag
设置最大连接延迟的时间。min-slaves-to-write和min-slaves-max-lag中有一个被置为0,则这个特性将被关闭。默认情况下min-slaves-to-write为0,而min-slavesmax-lag为10。
乐观复制策略
Redis采用乐观复制的策略,容忍在一定时间内主从数据库的内容不同,保存最终的数据会是一样的。这个策略保证了性能,在复制的时候,主数据库并不阻塞,照样处理客户端的请求。
Redis提供了配置来限制只有当数据库至少同步给指定数量的从数据库时,主数据库才可写,否则返回错误。配置是:min-slaves-to-write、min-slavesmax-lag。
无硬盘复制
当复制发生时主数据库会在后台保存RDB快照,即使你关闭了RDB它也会这么做,这样就会导致一些问题。
- 如果主数据库关闭了RDB,现在强行生成了RDB,那么下次主数据库启动的时候,可能会从RDB来恢复数据,这可能是旧的数据。
- 由于要生成RDB文件,在硬盘性能不高的时候会对性能造成一定影响,因此从2.8.18版本引入了无硬盘复制选项
repl-diskless-sync
。
哨兵(sentinel)
- Redis提供了哨兵工具来实现监控Redis系统的运行情况,主要实现:
- 监控主从数据库运行是否正常
- 当主数据库出现故障时,自动将从数据库转换成为主数据库
- 使用Redis-sentinel,redis实例必须在非集群模式下运行
开启哨兵功能
- 找到
sentinel.conf
文件并设置被监控主数据库 sentinel monitor (监控的主数据库的名字) 127.0.0.1 6378 1
1
表示选举主数据库的最低票数- 这个文件的内容在运行期间会被sentinel动态修改,一般追回到文件的最后面。
- 可以同时监控多个主数据库,一行一个配置即可。
- 如果监控的主数据库故障,则哨兵将从slave中选举master,后续原来的master服务恢复后会作为slave处理。