之前有一个 redis 的线上事故,原因是有个脚本删除了一个 redis 的大 key ,这个 key 是一个 zset 数据结构,里面有 1000w+ 数据,导致 cpu 100%.
问题是:如果不手动删除 key ,而是设置一个过期时间,那么到了过期时间这个 key 失效了也会引发同样的问题吗?
解决:
zset元素数量多的时候,实现上是 map+skiplist ,因为非数组结构(非连续内存),所以没法像操作单个元素那样删除所有元素,而是需要遍历删除每个节点,元素多,一个 op 整体删除肯定要阻塞其他请求较长时间。
你可以分批删除,比如 zremrangebyrank 一次删除 N 个,多次之间间隔 sleep 下(或者单次 op RTT 本来就有网络往返时间,一般不 sleep 也可以,看你们主业务的需要),因为是要删除的数据,删除慢点应该也无所谓,N 和是否需要 sleep 自己把握就行。
4.0+ unlink 也可以,但是 unlink redis 线程之间通知之类的会多消耗一点,如果你们业务量大对 redis 的请求很频繁,用业务服务分批删、能替 redis 节省点性能可能对整个集群更划算,根据你们实际业务来判断