文章目录

  • redis为什么不用多线程?
  • 为什么单线程Redis还这么快?
  • 并非真正的单线程
  • IO多路复用
  • 纯内存访问
  • 高效的数据结构
  • 那单线程有哪些性能问题呢?


redis为什么不用多线程?

主要是两个原因:

  • 没必要
    Redis Server本身可能出现的性能瓶颈点无非就是网络IO、CPU、内存。但是CPU不是Redis的瓶颈点,所以没必要使用多线程来执行指令。
  • 多线程副作用大
    如果采用多线程,意味着对于redis的所有指令操作,都必须要考虑到线程安全问题,也就是说需要加锁来解决,这种方式带来的性能影响反而更大。

为什么单线程Redis还这么快?

并不是真正的单线程,很多地方也用到了子进程来加快速度
io多路复用、内存访问、高效的数据结构等等优化进一步加速。

并非真正的单线程

Redis的网络IO和键值对读写是由一个线程来完成的,但Redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。

所以严格来说,Redis并不是单线程,只是网络IO和键值对读写占主要,所以我们才不严谨的把Redis称为单线程而已。

IO多路复用

纯内存访问

高效的数据结构

那单线程有哪些性能问题呢?

Redis单线程处理IO请求性能瓶颈主要包括2个方面:

1、任意一个请求在server中一旦发生耗时,后面的请求都要等前面这个耗时请求处理完成,自己才能被处理到。耗时的操作包括以下几种:

  • 操作bigkey
    写入、删除 一个bigkey在分配内存时需要消耗大量的时间
  • 使用复杂度过高的命令
    例如SORT/SUNION/ZUNIONSTORE,或者O(N)命令,但是N很大
  • 大量key集中过期
    Redis的过期机制也是在主线程中执行的,大量key集中过期会导致处理一个请求时,大量时间花在了删除过期key
    解决:Redis在4.0推出了lazy-free机制,把bigkey释放内存的耗时操作放在了异步线程中执行,降低对主线程的影响。
  • 淘汰策略
    淘汰策略也是在主线程执行的,当内存超过Redis内存上限后,每次写入都需要淘汰一些key,也会造成耗时变长;
  • AOF刷盘开启always机制
    每次写入都需要把这个操作刷到磁盘,写磁盘的速度远比写内存慢,会拖慢Redis的性能;
  • 主从全量同步生成RDB
    虽然采用fork子进程生成数据快照,但fork这一瞬间也是会阻塞整个线程的,实例越大,阻塞时间越久;

2、并发量非常大时,单线程读写客户端IO数据存在性能瓶颈,虽然采用IO多路复用机制,但是读写客户端数据依旧是同步IO,只能单线程依次读取客户端的数据,无法利用到CPU多核。