CPU架构

  • 一个 CPU 处理器中一般有多个物理核。
  • 每个物理核都拥有私有的一级缓存( L1 cache)和私有的二级缓存(L2 cache)。
  • 不同的物理核还会共享一个共同的三级缓存
  • 每个物理核通常都会运行两个超线程,也叫作逻辑核。同一个物理核的逻辑核会共享使用 L1、L2 缓存
  • 不同处理器间通过总线连接

问题

1、多CPU:如果应用程序先在一个 Socket(CPU处理器) 上运行,并且把数据保存到了内存,然后被调度到另一个 Socket 上运行,此时,应用程序再进行内存访问时,就需要访问之前 Socket 上连接的内存,这种访问属于远端内存访问。和访问 Socket 直接连接的内存相比,远端内存访问会增加应用程序的延迟。(NUMA)

2、多核:Redis 主线程的运行时信息需要被重新加载到另一个 CPU 物理核上,而且,此时,另一个 CPU 物理核上的 L1、L2 缓存中并没有 Redis 实例之前运行时频繁访问的指令和数据,所以,这些指令和数据都需要重新从 L3 缓存,甚至是内存中加载。

3、Redis 实例和网络中断程序的数据交互:网络中断处理程序从网卡硬件中读取数据,并把数据写入到操作系统内核维护的一块内存缓冲区。内核会通过 epoll 机制触发事件,通知 Redis 实例,Redis 实例再把数据从内核的内存缓冲区拷贝到自己的内存空间。可能存在跨CPU拷贝内存数据。

优化

1、把 Redis 实例和 CPU 物理核绑定了,让一个 Redis 实例固定运行在一个 CPU 物理核上
2、把操作系统的网络中断处理程序和 CPU 物理核绑定。Redis 实例绑定在同一个物理核上。
3、使用源码优化方案,既可以实现 Redis 实例绑核,避免切换核带来的性能影响,还可以让子进程、后台线程和主线程不在同一个核上运行,避免了它们之间的 CPU 资源竞争。

注:NUMA架构下,先给每个 CPU Socket 中每个物理核的第一个逻辑核依次编号,再给每个 CPU Socket 中的物理核的第二个逻辑核依次编号。