关于Redis的坑

By Gavin     @2019-12-11     1090 views

Redis经常在业务中当作缓存使用,甚至来拿做队列和排行榜等。一般在量级小的时候都没啥问题(或者说没发现有问题),但是QPS和数据量大之后,在所难免的会有各种坑

  • Redis的主进程是单线程的,如果被阻塞则会影响其他客户端的请求

  • Redis有AOF和RDB两种持久化策略

AOF导致服务延迟(不稳定)

AOF fsync文件的配置如下

# 每要写进AOF的指令都会fsync,会非常慢,但是很安全
appendfsync always

# 每秒fsync一次,足够快,但是故障会丢失1秒的数据
appendfsync everysec

# 从不fsync,更快但是更不安全,一般Linux会每几十秒刷一次,故障丢的数据就更多了
appendfsync no

AOF rewrite的配置如下

# 如果和上次rewrite相比超过percentage这个百分比,则rewrite
# 前提是AOF文件的大小大于min-size
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
  1. 如果AOF文件生成策略太激进比如说 appendfsync always,会经常需要写磁盘。QPS太高(更新等操作)的时候也要写很多的内容。但是AOF是在时间循环中做的,所以如果时间长会影响正常操作(也有可能磁盘也会刚不住,但是一般都还好,毕竟append)

  2. 同理QPS比较高,写入比较多的时候,也会时常触发AOF rewrite,AOF rewrite的时候,为了不影响服务,会fork子进程来处理,两个进程共享的内存页在发生写操作的时候,会发生 copy on write ,这个时候高QPS会导致很大的延迟和更高的内存占用

如果确定只是缓存不持久化,并且AOF已经影响到性能(更新QPS太高,或者更新流量比较大),可以关闭AOF

RDB导致服务延迟(不稳定)

RDB快照生成策略配置如下

# 如果有超过1000个key改动,则每60s保存一次
save 60 1000

同理Redis为了保存RDB快照的时候不影响服务,也是fork子进程处理,此时类似AOF问题中的第2项,会导致延迟和更高的内存占用

同理,如果不需要持久化,也可以关闭RDB快照来提升服务稳定性

挂新从库导致服务延迟(不稳定)

因为新的从库需要从主库同步数据,此时会优先使用RDB文件创建从库然后再逐步追赶进度。所以即使关闭了自动生成RDB文件,挂新从库的时候也会自动生成RDB文件,同RDB导致的不稳定类似

主要参考内容

Redis Persistence

Redis Latency

Gavin's Daily

© 2019-2020 Gavin's GoBlog