现象描述
在redis主节点执行flushall清除缓存数据的命令后,导致sentinel集群误判该节点odown,从而执行了failover。
测试准备
2C4G 一主一从redis * 1
8C16G 一主一从redis * 1
3节点sentinel集群 * 1
测试结果
使用redis-benchmark灌一定量的不同类型的数据
2C4G | |||
灌数据命令 | 内存使用 | flushall时间 | flush状态 |
./redis-benchmark -n 18000000 -r 18000000 -t set -d 100 -c 100 | 2.16G | 15s+ | ok |
./redis-benchmark -t lpush -r 30000000 -n 30000000 -P 8 -c 100 | 1.79G | 6s+ | ok |
./redis-benchmark -t sadd -r 40000000 -n 40000000 -P 8 -c 100 | 2.22G(灌入数据不止2.2,内存撑满了) | 24s+ | ok |
./redis-benchmark -r 20000000 -n 20000000 -P 8 -c 100 -q -t set,lpush,sadd | 2.22G(灌入数据不止2.2,内存撑满了) | 127s+ | odown |
./redis-benchmark -r 10000000 -n 10000000 -P 8 -c 100 -q -t set,lpush,sadd | 1.79G | 13s+ | ok |
8C16 | |||
灌数据命令 | 内存使用 | flushall时间 | flush状态 |
./redis-benchmark -n 50000000 -r 50000000 -t set -c 100 -P 16 | 3.09G | 43s+ | odown |
./redis-benchmark -n 50000000 -r 50000000 -c 100 -P 16 -t lpush | 2.98G | 10s+ | ok |
./redis-benchmark -n 50000000 -r 50000000 -c 100 -P 16 -t sadd | 2.61G | 30s+ | odown |
测试分析
原理分析:
flushall造成sentinel误判并执行failover的原因:redis是一个单线程DB,执行flushall会阻塞其他客户端操作,如果flushall执行时间超过了sentinel中的配置down-after-milliseconds(默认30s),sentinel持续发出的PING 30秒内得不到PONG回应,则会主观将该master置为sdown,当三个sentinel均认为该master为sdown后,会将该master置为odown,并执行failover。
从测试结果也可知,造成sentinel判断odown的均为flushall超过30s。
所以,当缓存数据量小于2G时,redis执行flushall是比较稳定的,当缓存数据量大于2G,建议使用DEL或其他方式代替flushall.
文章转载自数据库笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。