高可用Redis(七):Redis持久化 (6)

在linux系统中,有一种显式复制的机制:copy-on-write,父子进程会共享相同的物理内存页,当父进程有写请求的时候,会创建一个父本,此时才会消耗一定的内存。在这个过程中,子进程会共享fork时,父进程的内存的快照

Redis在做BGSAVE或者AOF操作fork产生子进程的过程中,如果父进程的内存页有大量的写入操作时子进程的内存开销会非常大,因为子进程会做一个父本

如果父进程没有多少写入操作时,fork操作不会占用过多的内存资源,可以在Redis的日志中看到

内存开销优化:

1.在单机部署Redis时,不要产生大量的重写,这样内存开销也会比较小

2.尽量主进程写入量比较小时,执行BGSAVE或者AOF操作

3.linux系统优化:

echo never > /sys/kernel/mm/transparent_hugepage/enabled

4.2.3 硬盘开销

AOF和RDB文件的写入,会占用硬盘的IO及容量,可以使用iostat命令和iotop命令查看分析

硬盘开销优化:

1.不要和硬盘高负载服务部署在一起,如存储服务,消息队列等

2.修改Redis配置文件:在AOF重写期间不要执行AOF操作,以减少内存开销

no-appendfsync-on-rewrite = yes

3.根据硬盘写入量决定磁盘类型:例如使用SSD

4.单机多部署模式持久化时,文件目录可以考虑分盘。即对不同的Redis实例以端口来进行区分,持久化文件也以端口来区分

4.3 AOF追加阻塞

高可用Redis(七):Redis持久化

AOF一般都是一秒中执行一次

AOF追加阻塞流程

1.主线程负责写入AOF缓冲区 2.AOF同步线程每秒钟执行一次同步硬盘操作,同时还会记录一次最近一次的同步时间 3.主线程会对比上次AOF同步时间,如果距离上次同步时间在2秒之内,则返回主线程 4.如果距离上次AOF同步时间超过2秒,则主线程会阻塞,直到同步完成

AOF追加阻塞是保证AOF文件安全性的一种策略

为了达到每秒刷盘的效果,主线程会阻塞直到同步完成

这样就会产生两个问题:

因为主线程是在负责Redis日常命令的处理,所以Redis主线程不能阻塞,而此时Redis的主线程被阻塞
如果AOF追加被阻塞,每秒刷盘的策略并不会每秒都执行,可能会丢失2秒的数据

AOF阻塞定位:

如果AOF追加被阻塞,可以通过命令查看:

127.0.0.1:6379> info persistence # Persistence loading:0 rdb_changes_since_last_save:1 rdb_bgsave_in_progress:0 rdb_last_save_time:1539409132 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:-1 rdb_current_bgsave_time_sec:-1 aof_enabled:0 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_delayed_fsync:100 # AOF被阻塞的历史次数,无法看到某次AOF被阻塞的时间点

单机多实例部署中持久化的优化可以参考硬盘开销的优化策略

5.Redis持久化总结 RDB是Redis内存数据到硬盘的快照,用于持久化 save通常会阻塞Redis BGSAVE不会阻塞Redis,但是fork新进程会阻塞Redis SAVE自动配置满足任一条件就会被执行

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzsxz.html