写点什么

异步机制和 CPU 架构对 Redis 性能的影响

用户头像
escray
关注
发布于: 2021 年 03 月 25 日
异步机制和CPU架构对 Redis 性能的影响

异步机制和 CPU 架构对 Redis 性能的影响,《Redis 核心技术与实战》学习笔记 10,部分已经作为留言发布,但是留言太多,排在后面的一般很难被大家看到,所以集中发布在这里,欢迎讨论。


题图和文中插图都来自极客时间《Redis 核心技术与实战》专栏

16 | 异步机制:如何避免单线程模型的阻塞?



Redis 实例运行时 4 大类交互对象的图非常漂亮,一图顶千言。


Redis 阻塞点


  1. 集合的全量查询、聚合

  2. bigkey 删除(释放内存)

  3. 清空数据

  4. AOF 日志同步写

  5. (从库)加载 RDB 文件

  6. Redis Cluster 同步迁移 bigkey (后续有解决方案)


关键操作(读操作)


  • 集合的全量查询和删除

  • 从库加载 RDB


pthread_create 子线程


  1. AOF 日志写操作

  2. 键值对删除

  3. 文件关闭


如果是 Redis 4.0 以前的版本,bigkey 删除的时候,如果是集合类型可以先使用 SCAN 命令读取(一部分)数据,然后再进行删除;如果是 Hash 类型,那么搭配使用 HSCAN 和 HDEL,把删除压力分摊到多次操作中。


集合全量查询和聚合操作也可以使用 SCAN 命令,分批读取数据,在客户端聚合

解决从库加载 RDB 文件的阻塞,可以把主库数据量控制在 2~4GB


对于课后题目 Redis 的写操作(SET、HSET、SADD)一般来说应该不在关键路径上。主要还是看业务的需要,如果是要求实时读取写入内容,那么写操作就在关键路径上;一般情况下,不要求,就不在关键路径上。


可以对照的是,对于关系型数据库,特别是记录日志的,写操作应该在关键路径上。


看了课代表 @Kaito 的回答,我也只好膜拜一下了,特别是对于 lazy free 的补充,我觉的完全可以放到专栏正文中去。

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


看到正文之前,我觉得 CPU 结构影响 Redis 性能主要应该是从存储的角度,比如 64 位和 32 位的问题。多核 CPU 会有影响么?


每个 CPU 物理核都有自己私有的 L1 cache 和 L2 cache,KB 级别,访问速度 10 ns(L1 应该更小一些、更快一点)。


应用程序访问内存在百纳秒级别。


不同物理核共享三级缓存 L3 Cache,几 MB 到 几十 MB。


每个物理核通常运行两个超线程,逻辑核,共享使用物理核的 L1、L2 缓存。



主流服务器一般会有多个 CPU 处理器(CPU Socket),而一个 CPU 处理器会有 10 到 20 多个物理核。每个处理器有自己的物理核(包括 L1、L2 缓存),L3 缓存以及连接的内存。



应用程序可以现在一个 CPU Socket 上运行,数据在 Socket 关联的内存上;然后可以被调度到另一个 Socket 上执行,应用程序访问之前那个 Socket 上连接的内存(远端内存访问),延迟增加。


非同一内存访问架构(Non-Uniform Memory Access,NUMA 架构)。


看到这里,我已经在幻想和面试官谈笑风生了。


通过 taskset 可以将 Redis 实例绑定在 CPU 核上,避免频繁的上下文切换 context switch。我有一点好奇,这里是“核” core 还是 CPU Socket ?从前文的说明应该是物理核。看到后来,发现这一部分是指单 CPU 多核的情况。


在 NUMA 架构下,网络中断处理程序和 Redis 实例如果分别绑在不同的 CPU Socket 中,其实就是在不同的 CPU 处理器上,那么就需要跨 CPU Socket 访问内存,也就是前面说的远端内存访问,内存访问延迟增加 18%。


结论呼之欲出,把网络中断程序和 Redis 实例绑在同一个 CPU Socket 上。


在 macOS 上没有 lscpu 命令,可以使用


sysctl -n machdep.cpu.brand_stringsysctl -a | grep machdep.cpusysctl -n hw.ncpusysctl -n hw.physicalcpusysctl -n hw.logicalcpu
复制代码


查看 CPU 信息,但是我没有找到逻辑核的编号,也可能 MacBook 笔记本不是 NUMA 架构?


对我来说,优化 Redis 源码距离我有点遥不可及,学习这篇文章最有价值的部分其实是前面关于 CPU 架构的部分。


对于课后题,如果这个服务器只是用作 Redis 部署的话,我选择在 2 个 CPU Socket 上各运行 4 个实例,并且和相应的 Socket 绑定,这样一来可以避免后台线程对主线程的 CPU 资源竞争。


@Kaito 课代表的主要思路是分别利用两个 CPU Socket 的 L3 Cache 以及各自连接的内存,以减少上下文切换。


发布于: 2021 年 03 月 25 日阅读数: 6
用户头像

escray

关注

Let's Go 2017.11.19 加入

在学 Elasticsearch 的项目经理

评论

发布
暂无评论
异步机制和CPU架构对 Redis 性能的影响