(一)耗时长命令造成阻塞
1. keys、sort,save等命令
keys命令用于查找所有符合给定模式 pattern 的 key,时间复杂度为O(N), N 为数据库中 key 的数量。当数据库中的个数达到千万时,这个命令会造成读写线程阻塞数秒;类似的命令有sunion sort等操作;实际需求中一定要使用keys、sort等操作怎么办?
解决方案:
在架构设计中,有“分流”一招,可以看我《高并发之应用限流思路》,简单来说:将请求类型进行分类设计,可以理解为设计不同的通道,处理快的请求和处理慢的请求分离来开。这在redis的设计中体现的非常明显,redis的纯内存操作,epoll非阻塞IO事件处理,不耗时的放在另外一个线程中。而持久化,AOF重写、Master-slave同步数据,耗时的操作就单开一个进程来处理。
同理,既然需要使用keys这些耗时的操作,就将它们剥离出去,单开一个redis slave结点,专门用于keys、sort等耗时的操作,这些查询一般不会是线上的实时业务。
2. smembers命令
smembers命令用于获取集合全集,时间复杂度为O(N),N为集合中的数量;
如果一个集合中保存了千万量级的数据,一次取回也会造成事件处理线程的长时间阻塞;
解决方案:
和sort等命令不一样,smembers是线上实时应用场景中使用频率非常高的一个命