cpu隔离

SMP (Symmetrical Multi-Processing):指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。SMP意为对称多处理系统,内有许多紧耦合多处理器,这种系统的最大特点就是共享所有资源。另外与之相对立的标准是MPP (Massively Parallel Processing),意为大规模并行处理系统,这样的系统是由许多松耦合处理单元组成的,要注意的是这里指的是处理单元而不是处理器。每个单元内的CPU都有自己私有的资源,如总线、内存、硬盘等。在每个单元内都有操作系统和管理数据库的实例复本。这种结构最大的特点在于不共享资源 [更多...]


CPU affinity:中文唤作“CPU亲和力”,是指在CMP架构下,能够将一个或多个进程绑定到一个或多个处理器上运行。[更多...]


一、在Linux上修改进程的“CPU亲和力”


在Linux上,可以通过 taskset 命令进行修改,安装taskset工具。


# yum install util-linux-ng

对运行中的进程,文档上说可以用下面的命令,把CPU#1 #2 #3分配给PID为2345的进程:


# taskset -cp 1,2,3 2345

但我尝试没奏效,于是我关掉了MySQL,并用taskset将它启动:


# taskset -c 1,2,3 /etc/init.d/mysql start

对于其他进程,也可如此处理(nginx除外,详见下文)。之后用top查看CPU的使用情况,原来空闲的#1 #2 #3,已经在辛勤工作了。




二、配置nginx绑定CPU


刚才说nginx除外,是因为nginx提供了更精确的控制。


在conf/nginx.conf中,有如下一行:


worker_processes  1;

这是用来配置nginx启动几个工作进程的,默认为1。而nginx还支持一个名为worker_cpu_affinity的配置项,也就是说,nginx可以为每个工作进程绑定CPU。我做了如下配置:


worker_processes  3;

worker_cpu_affinity 0010 0100 1000;

这里0001、0010、0100、1000是掩码,分别代表第1、2、3、4颗cpu核心。


重启nginx后,3个工作进程就可以各自用各自的CPU了。


三、刨根问底


如果自己写代码,要把进程绑定到CPU,该怎么做?可以用sched_setaffinity函数。在Linux上,这会触发一次系统调用。

如果父进程设置了affinity,之后其创建的子进程是否会有同样的属性?我发现子进程确实继承了父进程的affinity属性。

四、Windows?


在Windows上修改“CPU亲和力”,可以通过任务管理器搞定。






* 个人感觉,Windows系统中翻译的“处理器关系”比“CPU亲和力”容易理解点儿


—————–


进行了这样的修改后,即使系统负载达到3以上,不带缓存打开blogkid.net首页(有40多次查询)依然顺畅;以前一旦负载超过了1.5,响应就很慢了。效果很明显。


linux taskset命令详解


SYNOPSIS

      taskset [options] [mask | list ] [pid | command [arg]...]

OPTIONS

      -p, --pid

              operate on an existing PID and not launch a new task

      -c, --cpu-list

              specifiy  a  numerical  list of processors instead of a bitmask.

              The list may contain multiple items,  separated  by  comma,  and

              ranges.  For example, 0,5,7,9-11.

      -h, --help

              display usage information and exit

      -V, --version

              output version information and exit


# taskset -p -c 0 16380  或者  taskset -cp 0 16380


# ps -e -o psr,pid,cmd |grep 29165  查验 


psr : 进程当前被分配的处理器


---------------------------------------------------------------


使CPU隔离,专门用于某个服务或进程:


为客户提供一个有2个逻辑CPU计算能力的一个客户机。要求CPU资源独立被占用,不受宿主机中其他客户机的负载水平的影响。为了满足这个需求,可以分为如下两个步骤来实现。




第一步,启动宿主机时隔离出两个逻辑CPU专门供一个客户机使用。在Linux内核启动的命令行加上“isolcpus=”参数,可以实现CPU的隔离,让系统启动后普通进程默认都不会调度到被隔离的CPU上执行。例如,隔离了cpu2和cpu3的grub的配置文件如下:


title Red Hat Enterprise Linux Server (3.5.0)


root (hd0,0)


kernel /boot/vmlinuz-3.5.0 ro root=UUID=1a65b4bb-cd9b-4bbf-97ff-7e1f7698d3db isolcpus=2,3


initrd /boot/initramfs-3.5.0.img


系统启动后,在宿主机中检查是否隔离成功,命令行如下:


[root@jay-linux ~]# ps -eLo psr | grep 0 | wc -l

106

[root@jay-linux ~]# ps -eLo psr | grep 1 | wc -l

107

[root@jay-linux ~]# ps -eLo psr | grep 2 | wc -l

4

[root@jay-linux ~]# ps -eLo psr | grep 3 | wc -l

4


[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==2) print $0}’

root        10    2    10  2 [migration/2]

root        11    2    11  2 [kworker/2:0]

root        12    2    12  2 [ksoftirqd/2]

root      245    2  245  2 [kworker/2:1]


[root@jay-linux ~]# ps –eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==3) print $0}’

root        13    2    13  3 [migration/3]

root        14    2    14  3 [kworker/3:0]

root        15    2    15  3 [ksoftirqd/3]

root      246    2  246  3 [kworker/3:1]

从上面的命令行输出信息可知,cpu0和cpu1上分别有106和107个线程在运行,而cpu2和cpu3上都分别只有4个线程在运行。而且,根据输出信息中cpu2和cpu3上运行的线程信息(也包括进程在内),分别有migration进程(用于进程在不同CPU间迁移)、两个kworker进程(用于处理workqueues)、ksoftirqd进程(用于调度CPU软中断的进程),这些进程都是内核对各个CPU的一些守护进程,而没有其他的普通进程在cup2和cpu3上运行,说明对其的隔离是生效的。


另外,简单解释一下上面的一些命令行工具及其参数的意义。ps命令显示当前系统的进程信息的状态,它的“-e”参数用于显示所有的进程,“-L”参数用于将线程(LWP,light-weight process)也显示出来,“-o”参数表示以用户自定义的格式输出(其中“psr”这列表示当前分配给进程运行的处理器编号,“lwp”列表示线程的ID,“ruser”表示运行进程的用户,“pid”表示进程的ID,“ppid”表示父进程的ID,“args”表示运行的命令及其参数)。结合ps和awk工具的使用,是为了分别将在处理器cpu2和cpu3上运行的进程打印出来。


第二步,启动一个拥有2个vCPU的客户机并将其vCPU绑定到宿主机中两个CPU上。此操作过程的命令行如下:


#(启动一个客户机)


[root@jay-linux kvm_demo]# qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize


VNC server running on ‘::1:5900’


#(查看代表vCPU的QEMU线程)


[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep

root      3963    1  3963  0 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963    1  3967  0 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963    1  3968  1 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 –daemonize

#(绑定代表整个客户机的QEMU进程,使其运行在cpu2上)


[root@jay-linux ~]# taskset -p 0×4 3963


pid 3963′s current affinity mask: 3


pid 3963′s new affinity mask: 4


#(绑定第一个vCPU的线程,使其运行在cpu2上)


[root@jay-linux ~]# taskset -p 0×4 3967


pid 3967′s current affinity mask: 3


pid 3967′s new affinity mask: 4


#(绑定第二个vCPU的线程,使其运行在cpu3上)


[root@jay-linux ~]# taskset -p 0×8 3968


pid 3968′s current affinity mask: 4


pid 3968′s new affinity mask: 8




#(查看QEMU线程的绑定是否生效,如下的第5列为处理器亲和性)


[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep

root      3963    1  3963  2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963    1  3967  2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963    1  3968  3 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 –daemonize

#(执行vCPU的绑定后,查看在cpu2上运行的线程)


[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==2) print $0}’

root        10    2    10  2 [migration/2]

root        11    2    11  2 [kworker/2:0]

root        12    2    12  2 [ksoftirqd/2]

root      245    2  245  2 [kworker/2:1]

root      3963    1  3963  2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963    1  3967  2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

#(执行vCPU的绑定后,查看在cpu3上运行的线程)


[root@jay-linux ~]# ps –eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==3) print $0}’

root        13    2    13  3 [migration/3]

root        14    2    14  3 [kworker/3:0]

root        15    2    15  3 [ksoftirqd/3]

root      246    2  246  3 [kworker/3:1]

root      3963    1  3968  3 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

由上面的命令行及其输出信息可知,CPU绑定之前,代表这个客户机的QEMU进程和代表各个vCPU的QEMU线程分别被调度到cpu0和cpu1上。使用taskset命令将QEMU进程和第一个vCPU的线程绑定到cpu2,将第二个vCPU线程绑定到cpu3上。绑定之后,即可查看到绑定的结果是生效的,代表两个vCPU的QEMU线程分别运行在cpu2和cpu3上(即使再过一段时间后,它们也不会被调度到其他CPU上去)。


对taskset命令解释一下,此处使用的语法是:taskset -p [mask] pid 。其中,mask是一个代表了处理器亲和性的掩码数字,转化为二进制表示后,它的值从最低位到最高位分别代表了第一个逻辑CPU到最后一个逻辑CPU,进程调度器可能将该进程调度到所有标为“1”的位代表的CPU上去运行。根据上面的输出,taskset运行之前,QEMU线程的处理器亲和性mask值是0×3(其二进制值为:0011),可知其可能会被调度到cpu0和cpu1上运行;而运行“taskset -p 0×4 3967”命令后,提示新的mask值被设为0×4(其二进制值为:0100),所以该进程就只能被调度到cpu2上去运行,即通过taskset工具实现了vCPU进程绑定到特定的CPU上。


上面命令行中,根据ps命令可以看到QEMU的线程和进程的关系,但如何查看vCPU与QEMU线程之间的关系呢?可以切换(“Ctrl+Alt+2”快捷键)到QEMU monitor中进行查看,运行“info cpus”命令即可(还记得3.6节中运行过的“info kvm”命令吧),其输出结果如下:


(qemu) info cpus


* CPU #0: pc=0xffffffff810375ab thread_id=3967


CPU #1: pc=0xffffffff812b2594 thread_id=3968


从上面的输出信息可知,客户机中的cpu0对应的线程ID为3967,cpu1对应的线程ID为3968。另外,“CPU #0”前面有一个星号(*),是标识cpu0是BSP(Boot Strap Processor,系统最初启动时在SMP生效前使用的CPU)。


总的来说,在KVM环境中,一般并不推荐手动地人为设置QEMU进程的处理器亲和性来绑定vCPU,但是,在非常了解系统硬件架构的基础上,根据实际应用的需求,是可以将其绑定到特定的CPU上去从而提高客户机中的CPU执行效率或者实现CPU资源独享的隔离性。


CPU中断请求隔离方法:


应该将中断绑定至那些非隔离的CPU上,从而避免那些隔离的CPU处理中断程序:


echo CPU_MASK > /proc/irq/ <irq number>/smp_affinity


[root@lopdb1 ~]# cat  /proc/irq/2/smp_affinity

7fffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff   


1. 不同的设备一般都有自己的IRQ号码(当然一个设备还有可能有多个IRQ号码)


通过命令:cat /proc/interrupts查看


如:cat /proc/interrupts | grep -e “CPU\|eth4″


2. 中断的smp affinity在cat  /proc/irq/$Num/smp_affinity


可以echo “$bitmask” > /proc/irq/$num/smp_affinity来改变它的值。


注意smp_affinity这个值是一个十六进制的bitmask,它和cpu No.序列的“与”运算结果就是将affinity设置在那个(那些)CPU了。(也即smp_affinity中被设置为1的位为CPU No.)


比如:我有8个逻辑core,那么CPU#的序列为11111111 (从右到左依次为#0~#7的CPU)


如果cat  /proc/irq/84/smp_affinity的值为:20(二进制为:00100000),则84这个IRQ的亲和性为#5号CPU。


每个IRQ的默认的smp affinity在这里:cat /proc/irq/default_smp_affinity


另外,cat  /proc/irq/$Num/smp_affinity_list 得到的即是CPU的一个List。


3. 默认情况下,有一个irqbalance在对IRQ进行负载均衡,它是/etc/init.d/irqbalance


在某些特殊场景下,可以根据需要停止这个daemon进程。


4. 如果要想提高性能,将IRQ绑定到某个CPU,那么最好在系统启动时,将那个CPU隔离起来,不被scheduler通常的调度。


可以通过在Linux kernel中加入启动参数:isolcpus=cpu-list来将一些CPU隔离起来。


参考文档:


https://www.kernel.org/doc/Documentation/IRQ-affinity.txt

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容