NUMA架构的优缺点及内核性能优化

  numa把一台计算机分成多个节点(node),每个节点内部拥有多个CPU,节点内部使用共有的内存控制器,节点之间是通过互联模块进行连接和信息交互。因此节点的所有内存对于本节点所有的CPU都是等同的,对于其他节点中的所有CPU都不同。因此每个CPU可以访问整个系统内存,但是访问本地节点的内存速度最快(不经过互联模块),访问非本地节点的内存速度较慢(需要经过互联模块),即CPU访问内存的速度与节点的距离有关,该距离成为Node Distance。


查看当前numa的节点情况:
numactl --hardware

节点之间的距离(Node Distance)指从节点1上访问节点0上的内存需要付出的代价的一种表现形式。
Numa内存分配策略有一下四种:
缺省default:总是在本地节点分配(当前进程运行的节点上)。
绑定bind:强制分配到指定节点上。
交叉interleavel:在所有节点或者指定节点上交叉分配内存。
优先preferred:在指定节点上分配,失败则在其他节点上分配。
查看当前系统numa策略:
numactl --show
因为numa默认的内存分配策略是优先在进程所在CPU的本地内存中分配,会导致CPU节点之间内存分配不均衡,
当某个CPU节点内存不足时,会导致swap产生,而不是从远程节点分配内存,这就是swap insanity现象。
MySQL服务器为什么需要关闭numa?
MySQL是单进程多线程架构数据库,当numa采用默认内存分配策略时,MySQL进程会被并且仅仅会被分配到numa的一个节点上去。
假设这个节点的本地内存为10GB,而MySQL配置20GB内存,超出节点本地内存部分(20GB-10GB)Linux会使用swap而不是使用其他节点的物理内存。
在这种情况下,能观察到虽然系统总的可用内存还未用完,但是MySQL进程已经开始在使用swap了。
如果单机只运行一个MySQL实例,可以选择关闭numa,关闭nuam有两种方法:
1.硬件层,在BIOS中设置关闭;
2.OS内核,启动时设置numa=off。
修改/etc/grub.conf文件,在kernel那行追加numa=off;
[root@node130 ~]#  vim /boot/grub/grub.conf
title Red Hat Enterprise Linux (2.6.32-358.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=UUID=cb7d8bdc-28a5-4dbd-b04a-3ad9ee3e6bba rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet numa=off
保存后重启服务器,再次检查numa只剩下一个节点就成功了:
[root@node130 ~]# numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0
node 0 size: 2047 MB
node 0 free: 1514 MB
node distances:
node   0
  0:  10

IO调度
在不同场景下选择不同的IO调度器:
在完全随机访问环境下,由于CFQ可能会造成小IO的相应延时增加,所以应设置为deadline,这样更稳定。
对于SSD设备,采用NOOP或者deadline也可以获取比默认调度器更好的性能。
查看当前系统支持的IO调度算法:
[root@node130 Desktop]# dmesg|grep -i scheduler
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
查看当前设备(/dev/sda)使用的IO调度算法:
[root@node130 Desktop]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]

修当前块设备(/dev/sda)使用的IO调度算法,修改IO调度算法后直接生效:
echo "deadline">> /sys/block/sda/queue/scheduler

永久修改IO调度算法,可以通过修改内核引导参数,增加elevator=调度算法:
vim /boot/grub/menu.lst
kernel /boot/                                root=LABEL=/ elevator=deadline

[root@node130 Desktop]# vim /etc/grub.conf

title Red Hat Enterprise Linux (2.6.32-358.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=UUID=28d9f713-f49d-49ae-9e63-401986d11ab2 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet numa=off elevator=deadline

交换分区

swappiness是Linux的一个内核参数,用户控制Linux物理内存进行swap页交换的相对权重,尽量减少系统的页缓存被从内存中清除的情况。取值范围是0~100,vm.swappiness的值越低,Linux内核会尽量不进行swap交换页的操作,vm.swappiness的值越高,Linux会越多的使用swap空间。Linux系统默认值是60,当系统需要内存时,有60%的概率使用swap。对于大多数桌面系统,设置为100可以提高系统的整体性能;对于数据库应用服务器,设置为0,可以提高物理内存的使用率,进而提高数据库服务的响应性能。

[root@node130 ~]# vim /etc/sysctl.conf
vm.swappiness=0

sysctl -p 生效
[root@node130 ~]# sysctl -a|grep swap
vm.swappiness = 0

原文连接:https://www.cnblogs.com/songyuejie/p/6795312.html

### 开源协议栈 mTCP 的优缺点 #### 优点 - **高性能** mTCP 是专门为高性能网络应用场景设计的用户空间 TCP/IP 协议栈。由于其运行在用户空间而非内核空间,因此能够显著减少上下文切换开销,提高 CPU 缓存命中率,并支持更高的并发连接数[^4]。 - **低延迟** 用户空间的设计使其可以绕过操作系统内核中的队列和缓冲区管理机制,从而大幅降低数据传输过程中引入的延迟。此外,mTCP 支持零拷贝技术和批量事件处理,进一步优化了 I/O 操作效率[^5]。 - **灵活性与可扩展性** mTCP 提供了一组类似于 Berkeley Sockets 的 API 接口,便于开发者快速上手并将其集成到现有的应用程序中。同时,作为开源项目,mTCP 可以根据具体需求进行裁剪或增强,满足不同业务场景的要求[^7]。 - **NUMA 架构优化** 针对现代多核处理器系统的特点,mTCP 对内存访问模式进行了针对性调整,在 NUMA (Non-Uniform Memory Access) 环境下表现出更好的性能稳定性[^8]。 - **易于调试与维护** 相较于复杂的内核态实现,mTCP 更加紧凑且模块化程度更高,这不仅降低了开发门槛也方便后续迭代升级工作开展[^9]。 #### 缺点 - **较高的开发成本** 虽然提供了友好的 API 层面封装,但对于初次接触该领域的人来说仍然存在一定学习曲线。另外如果要充分利用其全部潜力,则可能需要深入了解底层工作机制甚至参与核心代码修改活动[^10]。 - **有限的功能覆盖范围** 当前版本主要集中精力放在提升基础通信服务品质上面,对于某些高级特性比如 QoS(Quality of Service), VLAN(Virtual Local Area Network)标签处理等方面的支持相对薄弱[^11]。 - **兼容性和稳定性考量** 尽管官方声称已经经过充分测试验证,但在极端条件下仍可能存在未预见的问题。特别是在跨平台移植时需格外小心谨慎对待可能出现的各种异常状况[^6]。 - **资源占用问题** 如果不加以适当控制的话,大量短生命周期连接频繁建立销毁可能导致不必要的计算资源浪费现象发生。因此建议结合实际情况合理规划资源配置方案[^12]。 --- ```cpp // 示例:初始化 mtcp_context 并创建 socket #include <mtcp_api.h> int main(int argc, char *argv[]) { struct mtcp_conf mcfg; struct mtcp_epoll_event events[MAX_EVENTS]; mtcp_init(&mcfg); int sock = mtcp_socket(mctx, AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("Socket creation failed"); return EXIT_FAILURE; } // ...其余逻辑省略... } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值