3 可异步执行的阻塞点
在分析阻塞式操作的异步执行的可行性前,先了解异步执行对操作的要求。
若一个操作能被异步执行,说明它不是Redis主线程关键路径上的操作。
3.1 关键路径操作
客户端把请求发给Redis后,等Redis返回数据结果:
- 主线程接收到操作1后,由于操作1无需给客户端返回具体数据,所以,主线程可将其移交给后台子线程处理,同时只需给客户端返回“OK”。 操作1就不属关键路径操作,因其不用给客户端返回具体数据,所以可由后台子线程异步执行
- 子线程执行操作1时,客户端又向Redis实例发送操作2,而此时,客户端需使用操作2返回的具体数据结果。若操作2不返回结果,则客户端将一直处等待状态。 该操作需把结果返给客户端,所以是关键路径操作,主线程须立即执行完该操作。
那Redis的写操作(如SET,HSET,SADD)属于关键路径吗?这需要客户端根据业务需要区分:
- 若客户端依赖操作返回值的不同而处理不同业务逻辑,则HSET、SADD算关键路径,而SET操作不算关键路径 因为HSET和SADD操作,若field或member不存在,Redis返回1,否则返0。而SET操作返回的结果都是OK
- 若客户端不关心返回值,只关心数据是否写成功,则SET/HSET/SADD都不算关键路径,多次执行这些命令都是幂等的,这时可放到异步线程
- 若Redis设置maxmemory,但未设置淘汰策略,这三个操作也都算关键路径 因为若Redis内存超过maxmemory,再写入数据时,Redis返回的结果是OOM error,这种情况下,客户端需要感知有错误发生才行
3.2 各阻塞点分析
3.2.1 集合全量查询和聚合操作
Redis读肯定都是关键路径操作,因为客户端发起读请求后,就会等待返回读取数据,再处理后续。 所以,都涉及读操作,无法异步!
推荐使用SCAN命令,分批读取数据,再在客户端进行聚合计算;
3.2.2 删除操作
无需给客户端返回具体数据,所以不算关键路径操作。“大K删除”、“清空数据库”同理,都可用后台子线程异步执行。
3.2.3 AOF日志同步写
为保证数据可靠性,Redis实例需保证AOF日志中的操作记录已落盘,这个操作虽需实例等待,但并不会返回具体数据结果给实例。所以,也可使用一个子线程执行AOF日志同步写。
3.2.4 从库加载RDB文件
从库想对客户端提供数据存取服务,须将RDB文件加载完成。所以,这也属于关键路径操作,必须让从库主线程执行。把主库的数据量大小控制在2~4GB左右,以保证RDB文件能以较快的速度加载。
综上,可使用Redis异步子线程机制实现大K删除,清空数据库及AOF日志同步写。