注:本文以windows下的redis为例 Linux下的同理基本都一样
1.持久化机制
为了解决一旦断电或者宕机,内存数据库中的数据将会全部丢失这个缺点,Redis提供了将内存数据持久化到硬盘,以及用持久化文件来恢复数据的功能。Redis 支持两种形式的持久化,一种是RDB快照(snapshotting),另外一种是AOF(append-only-file)。
(1)RDB是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中所有键值对数据)。恢复时是将快照文件直接读到内存里,RDB持久化有两种触发机制,分别是自动触发和手动触发。在redis.windows.conf(linux就是redis.conf)文件的SNAPSHOTTING 下有个自动触发rdb持久化的策略:
其中分别表示900s内,如果至少有一个key值变化,则保存到rdb;300s内,至少有10个key变化就保存;60s内至少有10000个key变化就保存。如果只需要redis的缓存功能那么就可以关掉rdb持久化,使用空串停用,如:save “”“”。
在这个配置下面还有几个关于rdb持久化的配置:
stop-writes-on-bgsave-error yes:默认yes,表示在后台通过rdb保存数据失败之后是否停止向redis写入数据(接收数据)。这样可以让用户意识到后台持久化失败了,避免后面数据不能持久化。
rdbcompression yes:默认yes,表示存储的rdb快照是否进行压缩存储,如果关闭则快照会比较大。
rdbchecksum yes:默认yes,存储之后是否对数据进行校验,若希望提升redis性能可以关闭。
dbfilename dump.rdb:存储的rdb快照文件名。
dir ./:设置快照存放路径,必须是目录,默认和当前配置文件在同一目录。
手动触发rdb快照保存可以使用save和bgsave命令。save会阻塞当前redis,redis不能处理其他命令直到rdb过程完成,而bgsave会在后台异步进行保存(redis会执行fork操作创建一个子进程),阻塞只会在fork短时间内,redis内部rdb自动保存都是采用bgsave命令。
将备份文件dump.rdb放到配置文件指定的目录(默认是和redis配置文件同一目录)下,启动redis就会自动将数据加载到内存中。
(2)AOF 持久化是通过保存Redis服务器所执行的写命令来记录数据库状态。在redis的配置文件中APPEND ONLY MODE的下有关于AOF持久化的相关配置。
appendonly:表示是否开启AOF持久化,因为redis默认的是rdb方式,打开aof需要改为yes。
appendfilename:aof文件名。
appendsync:aof持久化策略配置。no表示不执行fsync,有系统保证数据同步到磁盘,速度最快但不安全;always表示每次写入都要执行fsync,以保证数据完全同步到磁盘,效率低;everysec则是每秒保存一次,可能会丢失者1s数据,兼顾安全和效率。
no-appendfsync-on-rewrite:设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据。默认值为no。
auto-aof-rewrite-percentage:默认值为100。aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。
auto-aof-rewrite-min-size:64mb。设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写。
aof-load-truncated:aof文件可能在尾部是不完整的(宕机或者断电等),如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。默认值为 yes
AOF文件不完整需要恢复可以使用命令:redis-check-aof --fix 进行修复。aof文件过大的时候也需要重写,和rdb的bgsave模式相似,都是创建子进程,设置重写缓冲区,在重写完成之后再将缓冲区文件写入aof文件。
总结
AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而已。
AOF 文件使用 Redis 命令追加的形式来构造,因此,即使 Redis 只能向 AOF 文件写入命令的片断,使用 redis-check-aof 工具也很容易修正 AOF 文件。
AOF 文件的格式可读性较强,这也为使用者提供了更灵活的处理方式。例如,如果我们不小心错用了 FLUSHALL 命令,在重写还没进行时,我们可以手工将最后的 FLUSHALL 命令去掉,然后再使用 AOF 来恢复数据。
对于具有相同数据的的 Redis,AOF 文件通常会比 RDB文件体积更大。
虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能。但在 Redis 的负载较高时,RDB 比 AOF 具好更好的性能保证。
RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,因此从理论上说,RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在 RDB 没有存在。
详见:https://www.cnblogs.com/ysocean/p/9114268.html
2.主从复制
复制三份配置文件,分别更改端口号,并且配置文件的名字以端口号区分。
之后再更改每份配置文件:rdb文件名(dbfilename)、log日志文件名(logfile),之后使用下面三个命令启动三个redis服务端。
redis-server.exe redis.windows.conf redis-server.exe redis.windows-10087.conf redis-server.exe redis.windows-10088.conf
随后启动三个redis客户端如下:
通过info replication查看各个节点信息。
此时都是master节点,接着设置slave节点。使用slaveof命令把10087和10088设为slave。
此时设为slave节点之后再使用info replication命令查看就发现role已经变为了slave了。现再在master节点写,在slave读。
可以看见现在主从关系已经成功建立了。注:(1)如果master以前还存在一些key,那么slave节点也是会有的,因为master会全量复制到slave。(2)默认从节点是不能够执行写命令的,配置文件中slave-read-only默认是yes。(3)主节点down掉之后,另外两个slave角色依然不变,并且在master恢复之后,仍然是master并且有两个slave节点。
3.哨兵模式(win下面没有哨兵文件,因此在linux下操作的)
哨兵模式就是不时地监控redis是否按照预期良好地运行(至少是保证主节点是存在的),若一台主机出现问题时,哨兵会自动将该主机下的某一个从机设置为新的主机,并让其他从机和新主机建立主从关系(如果监控主机发生故障,就根据投票数自动将从库转化为主库)。首先启动多个redis,并配置主从关系,下面再配置哨兵监控master。
(1)在配置文件目录下面使用touch命令新建sentinel.conf文件,然后配置内容:
sentinel monitor 被监控主机名(自己起) ip地址 端口 得票数 如:sentinel monitor my6379 127.0.0.1 6379 1。1表示当主机挂掉之后得票数>=1便成为主机。
(2)启动哨兵监控
使用命令:./redis-sentinel /mrliu_project/redis/sentinel.conf 注:/mrliu_project/redis/sentinel.conf 是配置文件所在目录
(3)exit退出master主机,之后查看哨兵控制台打印的日志,会发现在重新选择master。
注:在redis稳定版之后,挂掉的主机在选举之后重新连接上,会设置为新选举的msater的从节点。================================================================================================
补充:具体操作
启动三台带有redis的服务器133,132,130
分别更改redis.conf文件,并指定配置启动redis-server和redis-sentinel
进入redis的src目录:./redis-server ../redis.config ./redis-sentinel ../sentinel.conf(哨兵配置需要自己touch)
133启动一个master和哨兵的服务器,
132启动两个redis服务(两份配置文件),分别设为133的slave
130启动一个redis服务,设为133的slave
redis-config更改了一些目录和端口等,我大概改了如下内容:
daemonize yes
logfile
port
# bind 127.0.0.1 注释掉了
protected-mode no //关闭了
注意(出现设置了slaveof之后发现主机一直未down可能是如下原因):
(1)每个启动的redis服务需要注释掉bind(代表可以访问的主机),不然其他redis服务器不能感知到该redis服务的存在
(2) 每个redis服务需要更改protected-mode 为no,
(3)每台linux服务器需要打开端口,不然直接关闭firewall或者是iptables也行,命令systemctl stop firewalld和service iptables stop。 永久关闭防火墙使用disable。
(4)建议redis-server都配置为守护进程,daemon设为yes即可。
哨兵需要自建配置文件,在redis的src目录下使用 ./redis-sentinel ../sentinel_liu.conf 启动,其中后面的是自己的哨兵配置文件,简易配置如下:
port 26379
sentinel monitor liu_master 192.168.15.130 6379 1//监控的主机,后面代表超过机票就成为leader
sentinel down-after-milliseconds liu_master 10000//可选,多久没心跳就认为down
sentinel failover-timeout liu_master 10000//可选,代表每次选举间隔
几台服务器如下:
之后进入133使用info确认从节点有三个,
之后查看哨兵启动日志
注:sdown代表哨兵主观任务下线,(后面是master断开之后的日志)odown是客观下线,当出现odown的时候,哨兵将不会监控该服务,任务确实下线了,然后开始选举。
断开133的master,观察哨兵日志
可以进入133的客户端,使用shutdown关掉,也可以在redis的src目录下使用./redis-cli shutdown关,也可以杀redis进程关。
哨兵日志如下(我这儿选了这么多次原因是其他机器防火墙开着,所以关了就选举成功了):
出现failover-end即是选举成功了,switch代表切换master到了130服务器节点,随后发现 +fix-slave-config日志,代表将132的6379redis服务和132的6380redis服务设为了130的slave节点,这时候130成为master,132的两个redis服务是slave节点。
重新上线之前断开的133master,查看哨兵日志
发现新上线的133设为了130redis服务的slave,下面去130服务器登上redis客户端输入info验证
发现回归后的master变为了新选举的master的slave节点。