欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

CPU结构对redis性能的影响

程序员文章站 2022-03-06 18:13:58
主流CPU结构一个CPU处理器中一般有多个运行核心,一个运行核心称之为一个物理核。每个物理核都可以运行应用程序。每个物理核都拥有私有的一级缓存,包括一级指令缓存和一级数据缓存,以及私有的二级缓存。因为L1和L2缓存是每个物理核私有的,所以物理核访问他们的速度非常块,不到10纳秒。但是受限于制造技术,这些L1和L2缓存的大小一般只有KB级别。不同的物理核还会共享一个共同的三级缓存,能存储的资源较多,能达到几MB到几十MB,这样当L1和L2缓存中没有命中时,可以访问L3。避免访问内存。现在主流的CPU...

主流CPU结构

  • 一个CPU处理器中一般有多个运行核心,一个运行核心称之为一个物理核。每个物理核都可以运行应用程序。每个物理核都拥有私有的一级缓存,包括一级指令缓存和一级数据缓存,以及私有的二级缓存
  • 因为L1和L2缓存是每个物理核私有的,所以物理核访问他们的速度非常块,不到10纳秒。但是受限于制造技术,这些L1和L2缓存的大小一般只有KB级别。
  • 不同的物理核还会共享一个共同的三级缓存,能存储的资源较多,能达到几MB到几十MB,这样当L1和L2缓存中没有命中时,可以访问L3。避免访问内存。
  • 现在主流的CPU处理器,每个物理核通常会运行两个超线程,也叫做逻辑核,同一个物理核的逻辑核共享使用L1和L2缓存。
    CPU结构对redis性能的影响
  • 主流的服务器上,通常拥有多个CPU处理器(也称为多CPU Socket),每个CPU处理器拥有自己的物理核(包括L1和L2缓存),L3缓存,以及连接的内存。不同处理器通过总线连接
    CPU结构对redis性能的影响
  • 在多 CPU 架构上,应用程序可以在不同的处理器上运行。如果应用先在一个Socket上运行,并且把数据保存到了内存,然后调度到另一个Socket上运行。此时再进行内存访问时,就需要访问之前Socket上连接的内存,这种访问属于远端内存访问,和访问Socket直连的内存相比会增加延迟。所以,这种架构也叫非统一内存访问架构(Non-Uniform Memory Access,NUMA 架构)

CPU多物理核对Redis性能的影响

  • 在一个CPU核上运行时,应用需要记录自身使用的软硬件资源信息(运行时信息),访问最频繁的指令和数据会被缓存到L1和L2缓存中,以提升速度。
  • 在多核CPU场景下,一旦应用程序被切换到新的物理核运行,那么运行时信息就需要重新加载到新的物理核上,L1和L2缓存也需要重新加载数据和指令,这会导致程序的运行时间增加。这种情况叫跨核上下文切换。每调度一次,一些请求就会受到运行时信息、指令和数据重新加载过程的影响,这就会导致某些请求的延迟明显高于其他请求。
  • 解决办法可以使用绑核。比如使用taskset命令将redis实例绑定到0号物理核。
taskset -c 0 ./redis-server

CPU 的 NUMA 架构(多CPU架构)对 Redis 性能的影响

  • 网络中断程序绑定的物理核最好和Redis实例绑定的物理核相同。
  • 来看下 Redis 实例和网络中断程序的数据交互:网络中断处理程序从网卡硬件中读取数据,并把数据写入到操作系统内核维护的一块内存缓冲区。内核会通过 epoll 机制触发事件,通知 Redis 实例,Redis 实例再把数据从内核的内存缓冲区拷贝到自己的内存空间。CPU结构对redis性能的影响
  • 如果网络中断处理程序和 Redis 实例各自所绑的 CPU 核不在同一个 CPU Socket 上,那么,Redis 实例读取网络数据时,就需要跨 CPU Socket 访问内存,这个过程会花费较多时间。
    CPU结构对redis性能的影响
  • 需要注意的是,在 CPU 的 NUMA 架构下,对 CPU 核的编号规则,并不是先把一个 CPU Socket 中的所有逻辑核编完,再对下一个 CPU Socket 中的逻辑核编码,而是先给每个 CPU Socket 中每个物理核的第一个逻辑核依次编号,再给每个 CPU Socket 中的物理核的第二个逻辑核依次编号。可以使用lscpu命令查看
  • 比如两个CPU Socket,每个Socket有6个物理核,每个物理核有2个逻辑核。
    • 先给1号cpu的1号物理核的第一个逻辑核编号0,再给1号cpu的2号物理核的第一个逻辑核编号1,直到给1号cpu的6号物理核的第一个逻辑核编号5。
    • 然后给2号cpu的1号物理核的第一个逻辑核编号6,直到给2号cpu的6号物理核的第一个逻辑核编号11。
    • 然后给1号cpu的1号物理核的第二个逻辑核编号12,直到然后给1号cpu的6号物理核的第二个逻辑核编号17。
    • 然后给2号cpu的1号物理核的第二个逻辑核编号18,直到然后给2号cpu的6号物理核的第二个逻辑核编号23。
    • 总结来讲就是先给每个物理核的第一个逻辑核编号,再给每个物理核的第二个逻辑核编号
lscpu

Architecture: x86_64
...
NUMA node0 CPU(s): 0-5,12-17
NUMA node1 CPU(s): 6-11,18-23
...
  • 将redis实例绑定到同一个物理核的两个逻辑核
taskset -c 0,12 ./redis-server
  • 和只绑一个逻辑核相比,把 Redis 实例和物理核绑定,可以让主线程、子进程、后台线程共享使用 2 个逻辑核,可以在一定程度上缓解 CPU 资源竞争。但是,因为只用了 2 个逻辑核,它们相互之间的 CPU 竞争仍然还会存在。
  • 更进一步减少CPU竞争的方法可以通过修改 Redis 源码,把子进程和后台线程绑到不同的 CPU 核上。

本文地址:https://blog.csdn.net/weixin_40108561/article/details/111942640

相关标签: redis