# Draveness - 为什么 Numa 会影响程序的延迟 (Highlights) ![rw-book-cover|256](https://readwise-assets.s3.amazonaws.com/static/images/article2.74d541386bbf.png) ## Metadata **Cover**:: https://readwise-assets.s3.amazonaws.com/static/images/article2.74d541386bbf.png **Source**:: #from/readwise **Zettel**:: #zettel/fleeting **Status**:: #x **Authors**:: [[Draveness]] **Full Title**:: 为什么 Numa 会影响程序的延迟 **Category**:: #articles #readwise/articles **Category Icon**:: 📰 **Document Tags**:: #from/pocket **URL**:: [draveness.me](https://draveness.me//whys-the-design-numa-performance) **Host**:: [[draveness.me]] **Highlighted**:: [[2020-11-15]] **Created**:: [[2022-09-26]] ## Highlights - NUMA 引入了本地内存和远程内存,CPU 访问本地内存的延迟会小于访问远程内存; - NUMA 的内存分配与内存回收策略结合时会可能会导致 Linux 的频繁交换分区(Swap)进而影响系统的稳定性; - CPU 最早会通过前端总线(Front-side bus)、北桥(Northbridge)和内存总线(Memory bus)访问内存槽中的内存,所有的 CPU 会通过相同的总线访问相同的内存以及 I/O 设备,计算机中的所有资源都是共享的,这种架构被称作对称多处理器架构(Symmetric Multi-Processor、SMP),也被称为一致存储器访问结构(Uniform Memory Access、UMA)。 - 总线和北桥两个模块成为了系统的瓶颈 - CPU 架构的设计者使用如下所示的多个 CPU 模块解决了这个问题 - 通过 `numactl` 命令查看机器上的 NUMA 节点 - 可以使用 `numactl` 命令控制进程使用的 CPU 和内存。 - `numactl` 提供了 `cpunodebind` 和 `physcpubind` 两种策略为进程分配 CPU,这两种策略分别提供了不同粒度的绑定方法: - `cpunodebind` — 将进程绑定到某几个 NUMA 节点上; - `physcpubind` — 将进程绑定到某几个物理 CPU 上; - `numactl` 还提供四种不同的内存分配策略,分别是:`localalloc`、`preferred`、`membind` 和 `interleave`: - `localalloc` — 总是在当前节点上分配内存; - `preferred` — 倾向于在特定节点上分配内存,当指定节点的内存不足时,操作系统会在其他节点上分配; - `membind` — 只能在传入的几个节点上分配内存,当指定节点的内存不足时,内存的分配就会失败; - `interleave` — 内存会在传入的节点上依次分配(Round Robin),当指定节点的内存不足时,操作系统会在其他节点上分配; - Jeremy Cole 的文章 [The MySQL “swap insanity” problem and the effects of the NUMA architecture](https://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/) 就曾经分析过 NUMA 架构下 MySQL 可能出现的问题 - 当某些数据必须要在 NUMA 节点 0 的内存上分配时,就会导致 NUMA 节点 0 中的内存被交换到了文件系统上为新的内存请求让出位置 - Linux 中的 `zone_reclaim_mode` 可以允许工程师设置在 NUMA 节点内存不足时内存的回收策略,在默认情况下该模式都会处于关闭状态[6](#fn:6),如果我们在 NUMA 系统中通过该配置启用了激进的内存回收策略,可能会影响程序的性能 - 想要解决该问题,我们需要使用上一节提到的 `numactl` 将内存的分配策略改为 `interleave`