关于什么是cpu的亲和性的问题,大家自己去搜吧,不想在这里阐述了这讲义了。

简单说,就是让进程不要可哪跑,给定一个cpu core的范围,这样可以减少cs上下文切换后cpu cache miss的情况,节省了主存复制到cpu cache的时间。

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新.   http://xiaorui.cc/?p=4542

最开始接触cpu亲和性绑定是nginx上,我想大家一定都有在nginx配置过worker_cpu_affinity。 nginx 的 worker_cpu_affinity 参数就是用来绑定cpu core的,worker是顺序绑定的。

那么python需要做cpu亲和性绑定么? 那要看场景吧,不管你是c、golang、python语言,如果只是个没流量没任务的服务,那么无所谓了。  在高频流量服务下,还是很推荐cpu亲和性绑定的。 说下经验,爬虫系统和即时通信系统是采用python和golang写的, 任务量很大,流量也很大….  在python多进程配置了cpu亲和性之后, 系统的上下文少了一些,毕竟线程单元不会被迁移到别的core上,也就不会因为cache失效问题引发syscall。

另外我们通过ps aux进程的sys内核态时间,也可以看到优化cpu绑定的效果… … 

如果在命令行下获取进程的cpu绑定信息?


意思是说,pid绑定了0-15核,可以说默认的配置。

在终端下配置进程cpu绑定。

启动脚本并绑定cpu core

 

详细的查看进程所在的cpu核心上, PSR 是cpu id编号, 随便写个脚本会发现psr id不定期会变化

top -p 187090 , 按下P,然后按下f, 然后按 j (开启smp查看), 然后回车. 在每个进程信息里看到一个 P ,这个P就是psr。 

批量查看脚本:

到此为止,我们说完了如何在终端下查看配置cpu亲和性。 但其实也可以在程序内部实现绑定,当然难度不在于绑定,不管你是c、golang、python,都是通过系统系统的方式来实现绑定的,下面说说CPU亲和性在用户态的使用

linux的CPU亲和性在用户态表现为一个cpu_set_t掩码的形式,用户可以调用两个函数设置和获取掩码:


sched_setaffinity是设置指定pid亲和性掩码的,mask是传入的参数;sched_getaffinity则是获取指定pid亲和性掩码的,mask是获取的参数。

cpusetsize可以通过sizeof cpu_set_t算出来。cpu_set_t 是一个掩码数组,一共有1024位,每一位都可以对应一个cpu核心,以下宏,都是对这个掩码进行操作的。如果需要,一个进程是可以绑定多个cpu的。


而mask的表现是如此的:如果是0X23,转换成二进制则为00100011,则表明进程绑定在0核、1核和5核上。

绑核需要注意是,子进程会继承父进程的绑核关系。


那么python多进程内部如何实现cpu绑定?当然你如果不想这么折腾,完全可以在外部做cpu绑定。

python在3.4之后在os模块里加入了cpu_affinity方法,但是参数不太友好,pid绑定的cpu核是掩码,而不是taskset那样易懂的核心数。

推荐使用该模块,https://github.com/algodirect/affinity/blob/master/affinity/src/affinity/__init__.py

他比python3.4内置的os.sched_setaffinity 多了这么一个参数及返回值的处理。

如果你是python2.7 可以使用Pyobject实现的cpu affinity模块,一老外写的…   简单看了下实现的代码,通过Python.h构建方法,通过include sched.h系统调用。

https://pypi.python.org/pypi?%3Aaction=search&term=affinity&submit=search

那么,如何在项目里合理给进程池配置cpu亲和性绑定?

我这边的进程管理模型是参考nginx master worker原理实现的。 但是跟nginx 工作进程区别在于,nginx的worker是一种工作类型,处理的逻辑是一模一样。既然都一样了,那么nginx可以按照worker pid list顺序的绑定cpu核心。 但我这边的架构是worker分组的,也就是说,有很多种的worker group,每种worker的cpu消耗不一致。

那么首先,我们要避免多个cpu密集的任务集中在一个cpu上。  首先我们预先知道那种任务进程会消耗cpu,那么可以统一的先把cpu密集的pid收集起来,最后在一个个的配置cpu亲和性。
那么剩下的无关紧要的管理进程,可以按照区间的方式配置。 避免某个cpu密集任务把cpu打满,你的其他进程虽然无关紧要,但也不能太可怜了,所以24core的cpu,配置0-3, 5-8 以此类推…. 

总结:

用python构建的高频服务还是少数,在python里推荐大家使用多进程加协程池模型,该模型配置cpu亲和性是有效果的…. 还有cpu亲和度绑定是否有必要,看你的项目了。

END



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品

评论已关闭。