首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

redis性能优化骚操作——绑核

一、现代CPU模式

现代一个CPU中,可以有多个运行核心(称之为物理核),每个物理核都有自己独立的一级缓存(L1)和二级缓存(L2)。并且每个物理核一般会有两个超线程(称之为逻辑核);同一个物理核下的两个逻辑核同享L1和L2缓存。并且现在机器主流都是多CPU处理器结构(CPU Socket),每个CPU拥有自己的L1和L2以及L3级缓存和自己所管理的内存空间;不同处理器之间通过总线进行连接。一台机器的cpu构造如下图所示:

二、cpu多核对redis的影响

因为我们的cpu存在上下文切换(context switch),每个物理核有自己独立的L1和L2级缓存,程序执行最频繁的指令和数据会被缓存到L1和L2级缓存中,一旦我们的程序被切换到另一个物理核时,对应的指令和数据需要被重新刷到对应的(L1、L2)缓存中,所以频繁进行上下文切换的话,程序就不能很好的利用L1和L2级缓存,就会增加程序的延时性。针对这个频繁切换cpu核进行操作,我们可以采用绑核操作,将一个redis实例只在对应的物理核上执行,不会切换到其他物理核上。

taskset -c 0 ./redis-server

三、多cpu对redis的影响

我们的程序被cpu执行都是通过时间片,一台机器上有多个应用时,某一时刻是有一个程序可以获取cpu去执行程序代码,所以当一个程序在一个CPU socket运行时,如果此时发生了CPU切换,程序被切换到另一个CPU socket上运行,此时程序在运行时读取内存数据时,需要读取到之前的cpu socket所管理的内存,这种访问属于远端内存访问。这种访问 Socket 直接连接的内存相比,远端内存访问会增加应用程序的延迟。

所以多cpu对redis的影响:

因为L1,L2缓存中的指令和数据可以提高访问速度,一旦发生了cpu的切换,同样的指令和数据需要重新加载到L1和L2缓存中,影响redis的性能。

因为每个cpu都有自身控制的内存,一旦发生cpu的切换,就会存在一个cpu需要访问另一个cpu所管理的内存,出现远端内存的访问情况,影响redis的响应时间。

首先我们的redis实例需要很好的网络性能,redis是如何和操作系统的网络中断程序进行交互的呢?

网络中断程序从网卡中读取数据,并将数据写入到操作系统的内核缓冲区中,内核会通过epoll机制触发事件,通知到redis实例,redis就会从内核中拉取数据,复制到自己的内存空间中。这个时候就会存在一个潜在影响性能的点,到redis实例和网络中断处理程序,在不同的CPU Socket中运行时,redis读取网络数据时,就需要跨CPU Socket运行,影响其性能,其流程如下:

所以为了避免redis跨cpu访问网络数据,需要将redis实例和网络中断程序,绑定在同一个CPU Socket中:

四、绑核存在的风险点

当我们将redis实例绑在一个cpu核上时,redis其后台线程和fork的子进程等都会和redis主线程抢占cpu资源,导致redis主线程变慢,影响性能。

针对这个问题:主要的解决方法有两种:

一个就是redis实例对应绑一个物理核,因为我们的cpu一个物理核有两个逻辑核,这样可以把我们的两个逻辑核都给用上,可以在一定程度上缓解cpu的资源竞争。

修改redis源代码,把子进程和后台线程绑到不同的CPU核上。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20201110A0I60300?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券