Redis变慢了
Redis变慢上一篇文章地址:Redis变慢了?之二 这篇文章继续Redis变慢情况的分析。
fork耗时
在 Redis 中,fork 是一个非常重要的操作,它被用于创建子进程。Redis 使用 fork 来执行持久化操作,比如 RDB 和 AOF 持久化。在执行持久化操作期间,Redis 会 fork 出一个子进程,由子进程来执行实际的持久化操作,而父进程则继续处理客户端请求和其他操作。当 Redis 执行 fork 操作时,它会使用 Copy-on-Write 技术来避免不必要的内存复制,从而提高性能和效率。
需要注意的是,在 Redis 中使用 fork 操作时需要格外小心,因为 fork 操作会将整个父进程的内存空间复制一份到子进程中。如果 Redis 实例的内存非常大,那么 fork 操作可能会导致非常高的内存占用和系统负载,甚至可能导致系统崩溃。因此,在使用 Redis 进行持久化操作时,需要注意控制 Redis 实例的内存使用,以避免出现问题。
查看fork执行时长的命令可以用
127.0.0.1:6379> info
这是可以看到返回的Redis实例信息中上一次fork耗时,单位是微秒
在主进程fork子进程期间,整个Redis实例阻塞无法处理客户端请求,耗时越久对业务系统的影响也就越大。
优化方案
针对fork耗时产生的原因,那么首先就是控制Redis实例的内存,控制在一个合适的范围,比如10G以下,实例内存越大耗时越长;合理配置持久化策略,比如在从库执行持久化操作,如果只是拿Redis做缓存提高业务响应效率的话也可以不用开启数据持久化;最后就是Redis实例不要部署在虚拟机上,虚拟机比物理机fork耗时更久。
AOF
Redis AOF(Append Only File)是一种持久化方式,它会将所有写入 Redis 服务器的操作以追加的方式写入一个文件中,以此来保证数据在服务器重启后不会丢失。
AOF策略
AOF 持久化有三种策略,也就是appendfsync的三种值:
always:每个写命令都立刻同步到磁盘,保证最高的数据安全性,但是会降低 Redis 的性能。
everysec:每秒同步一次到磁盘,性能和安全性的平衡。
no:只在服务器退出时同步到磁盘,性能最高但数据安全性最差。
对性能影响
针对这三种策略对性能有不同的影响:
always:每处理一次写操作就会执行一次写入磁盘,由于都是在主线程执行,会拖慢Redis性能。
no:每次写操作只处理内存,刷盘由操作系统决定,有丢失数据的风险,如果是缓存数据可以设置为no。
everysec:主线程写完就返回,刷盘操作放在后台线程执行,每个1秒执行一次刷盘。虽然是最合适的刷盘方案,但是如果后台线程刷盘时IO负载很高,而主线程写操作继续,后台子线程由于磁盘负载过高,导致 fsync 发生阻塞,迟迟不能返回,那主线程在执行 write 系统调用时,也会被阻塞住,直到后台线程 fsync 执行完成后,主线程执行 write 才能成功返回。
简单说就是Redis 的 AOF 后台子线程刷盘操作,撞上了子进程 AOF fork,因此
# AOF rewrite 期间,AOF 后台子线程不进行刷盘操作no-appendfsync-on-rewrite yes
最后
后续有时间会继续探索Redis 变慢原因方面的问题...