1、生成RDB快照和AOF重写都会fork子线程来执行,但是fork子线程时会阻塞主线程,fork的实现与内存中的数据直接相关,redis内存中的数据越多则fork阻塞的时间就越长。
2、redis的fork操作采用写时复制技术,虽然不用全量拷贝主线程内存中的数据,但是会复制主线程的空间内存也表,10GB大约需要20MB的内存页表。
3、
优化主要从cpu、内存、磁盘这几个方面着手:
cpu:
1、redis持久化会通过子线程完成,这个过程属于cpu密集型操作,所以不要做绑定单核cpu操作,减少子线程和主线程的竞争。
2、不要和cpu密集型服务部署在一起。
3、对于redis单机多实例部署,通过外部程序轮询控制RDB和AOF重写操作,避免同一时间多个实例同时执行,造成cpu资源的激烈竞争
内存:
1、避免大量写入时执行重写操作,这样会造成主线程维护大量页副本,造成内存消耗。
2、单机多实例部署时,尽量同一时刻只有一个子线程在工作(生成RBD或者AOF重写)。
3、当linux开启了THP(transparent huge page)技术,虽然会加快fork的速度,但是复制页的单位从原来的4KB变为2MB,当AOF重写期间写请求并发量很高的时候内存消耗很大。
硬盘:
1、不要和高硬盘负载的应用部署在一起,比如消息队列等。
2、可以设置aof-rewrite-incremental-fsync参数控制aof重写时批量写入到磁盘的数据量,防止单次刷盘数据过多造成磁盘阻塞。
3、AOF重写期间会消耗大量硬盘IO,可以开启配置no-appendfsync-on-rewrite。标识在AOF重写期间不执行fsync操作,但是这样在极端情况下可能会丢失整个AOF重写期间的数据。
4、对于单机多实例步数,可以把不同实例的aof文件分盘存储,分摊磁盘的IO压力。