Redis核心技术与实战
蒋德钧
中科院计算所副研究员
新⼈⾸单¥19.9
7553 人已学习
课程目录
已更新 23 讲 / 共 50 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 这样学Redis,才能技高一筹
免费
基础篇 (10讲)
01 | 基本架构:一个键值数据库包含什么?
02 | 数据结构:快速的Redis有哪些慢操作?
03 | 高性能IO模型:为什么单线程Redis能那么快?
04 | AOF日志:宕机了,Redis如何避免数据丢失?
05 | 内存快照:宕机后,Redis如何实现快速恢复?
06 | 数据同步:主从库如何实现数据一致?
07 | 哨兵机制:主库挂了,如何不间断服务?
08 | 哨兵集群:哨兵挂了,主从库还能切换吗?
09 | 切片集群:数据增多了,是该加内存还是加实例?
10 | 第1~9讲课后思考题答案及常见问题答疑
实践篇 (10讲)
11 | “万金油”的String,为什么不好用了?
12 | 有一亿个keys要统计,应该用哪种集合?
13 | GEO是什么?还可以定义新的数据类型吗?
14 | 如何在Redis中保存时间序列数据?
15 | 消息队列的考验:Redis有哪些解决方案?
16 | 异步机制:如何避免单线程模型的阻塞?
17 | 为什么CPU结构也会影响Redis的性能?
18 | 波动的响应延迟:如何应对变慢的Redis?(上)
19 | 波动的响应延迟:如何应对变慢的Redis?(下)
20 | 删除数据后,为什么内存占用率还是很高?
加餐篇 (2讲)
加餐(一)| 经典的Redis学习资料有哪些?
加餐(二)| Kaito:我是如何学习Redis的?
Redis核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

17 | 为什么CPU结构也会影响Redis的性能?

蒋德钧 2020-09-16
你好,我是蒋德钧。
很多人都认为 Redis 和 CPU 的关系很简单,就是 Redis 的线程在 CPU 上运行,CPU 快,Redis 处理请求的速度也很快。
这种认知其实是片面的。CPU 的多核架构以及多 CPU 架构,也会影响到 Redis 的性能。如果不了解 CPU 对 Redis 的影响,在对 Redis 的性能进行调优时,就可能会遗漏一些调优方法,不能把 Redis 的性能发挥到极限。
今天,我们就来学习下目前主流服务器的 CPU 架构,以及基于 CPU 多核架构和多 CPU 架构优化 Redis 性能的方法。

主流的 CPU 架构

要了解 CPU 对 Redis 具体有什么影响,我们得先了解一下 CPU 架构。
一个 CPU 处理器中一般有多个运行核心,我们把一个运行核心称为一个物理核,每个物理核都可以运行应用程序。每个物理核都拥有私有的一级缓存(Level 1 cache,简称 L1 cache),包括一级指令缓存和一级数据缓存,以及私有的二级缓存(Level 2 cache,简称 L2 cache)。
这里提到了一个概念,就是物理核的私有缓存。它其实是指缓存空间只能被当前的这个物理核使用,其他的物理核无法对这个核的缓存空间进行数据存取。我们来看一下 CPU 物理核的架构。
因为 L1 和 L2 缓存是每个物理核私有的,所以,当数据或指令保存在 L1、L2 缓存时,物理核访问它们的延迟不超过 10 纳秒,速度非常快。那么,如果 Redis 把要运行的指令或存取的数据保存在 L1 和 L2 缓存的话,就能高速地访问这些指令和数据。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Redis核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏新⼈⾸单¥19.9
立即订阅
登录 后留言

精选留言(9)

  • Kaito
    这篇文章收获很大!对于CPU结构和如何绑核有了进一步了解。其实在NUMA架构下,不光对于CPU的绑核需要注意,对于内存的使用,也有很多注意点,下面回答课后问题,也会提到NUMA架构下内存方面的注意事项。

    在一台有2个CPU Socket(每个Socket 8个物理核)的服务器上,我们部署了有8个实例的Redis切片集群(8个实例都为主节点,没有主备关系),采用哪种方案绑核最佳?

    我更倾向于的方案是:在两个CPU Socket上各运行4个实例,并和相应Socket上的核绑定。这么做的原因主要从L3 Cache的命中率、内存利用率、避免使用到Swap这三个方面考虑:

    1、由于CPU Socket1和2分别有自己的L3 Cache,如果把所有实例都绑定在同一个CPU Socket上,相当于这些实例共用这一个L3 Cache,另一个CPU Socket的L3 Cache浪费了。这些实例共用一个L3 Cache,会导致Cache中的数据频繁被替换,访问命中率下降,之后只能从内存中读取数据,这会增加访问的延迟。而8个实例分别绑定CPU Socket,可以充分使用2个L3 Cache,提高L3 Cache的命中率,减少从内存读取数据的开销,从而降低延迟。

    2、如果这些实例都绑定在一个CPU Socket,由于采用NUMA架构的原因,所有实例会优先使用这一个节点的内存,当这个节点内存不足时,再经过总线去申请另一个CPU Socket下的内存,此时也会增加延迟。而8个实例分别使用2个CPU Socket,各自在访问内存时都是就近访问,延迟最低。

    3、如果这些实例都绑定在一个CPU Socket,还有一个比较大的风险是:用到Swap的概率将会大大提高。如果这个CPU Socket对应的内存不够了,也可能不会去另一个节点申请内存(操作系统可以配置内存回收策略和Swap使用倾向:本节点回收内存/其他节点申请内存/内存数据换到Swap的倾向程度),而操作系统可能会把这个节点的一部分内存数据换到Swap上从而释放出内存给进程使用(如果没开启Swap可会导致直接OOM)。因为Redis要求性能非常高,如果从Swap中读取数据,此时Redis的性能就会急剧下降,延迟变大。所以8个实例分别绑定CPU Socket,既可以充分使用2个节点的内存,提高内存使用率,而且触发使用Swap的风险也会降低。

    其实我们可以查一下,在NUMA架构下,也经常发生某一个节点内存不够,但其他节点内存充足的情况下,依旧使用到了Swap,进而导致软件性能急剧下降的例子。所以在运维层面,我们也需要关注NUMA架构下的内存使用情况(多个内存节点使用可能不均衡),并合理配置系统参数(内存回收策略/Swap使用倾向),尽量去避免使用到Swap。
    2020-09-16
    10
    38
  • test
    课后问题:我会选择方案二。首先一个实例不止有一个线程需要运行,所以方案一肯定会有CPU竞争问题;其次切片集群的通信不是通过内存,而是通过网络IO。
    2020-09-16
    2
  • 土豆白菜
    老师,我也想问下比如azure redis 能否做这些优化
    2020-09-16
    1
  • 游弋云端
    有两套房子,就不用挤着睡吧,优选方案二。老师实验用的X86的CPU吧,对于ARM架构来讲,存在着跨DIE和跨P的说法,跨P的访问时延会更高,且多个P之间的访问存在着NUMA distances的说法,不同的布局导致的跨P访问时延也不相同。
    2020-09-16
    1
  • zhou
    在 NUMA 架构下,比如有两个 CPU Socket:CPU Socket 1 和 CPU Socket 2,每个 CPU Socket 都有自己的内存,CPU Socket 1 有自己的内存 Mem1,CPU Socket 2 有自己的内存 Mem2。

    Redis 实例在 CPU Socket 1 上执行,网络中断处理程序在 CPU Socket 2 上执行,所以 Redis 实例的数据在内存 Mem1 上,网络中断处理程序的数据在 Mem2上。

    因此 Redis 实例读取网络中断处理程序的内存数据(Mem2)时,是需要远端访问的,比直接访问自己的内存数据(Mem1)要慢。
    2020-09-16
    1
  • Lemon
    get到了许多知识点,干货满满!
    2020-09-21
  • 那时刻
    请问老师,您文中提到我们仔细检测了 Redis 实例运行时的服务器 CPU 的状态指标值,这才发现,CPU 的 context switch 次数比较多。再遇到这样的问题的时候,排查的点有哪些呢?
    2020-09-16
  • 写点啥呢
    请问蒋老师,文章的例子代码是硬编码了子进程绑定的CPU编号,这样因为不知道运行时主进程绑定的CPU还是会有一定竞争的风险。那么有没有可以避免这种情况的方案,能够动态根据主进程绑定的情况分配子进程应该使用的CPU编号的实现呢?
    2020-09-16
  • jacky
    绑核用的都是逻辑核编号吧,那么在云虚机进行相关操作也是一样的了?
    2020-09-16
收起评论
9
返回
顶部