我几乎都在使用python程序:
我这样做的原因是因为我可以重用代码来提供不同类型的服务。
从前一段时间以来,我注意到这些脚本在我的服务器上占用了很高的CPU负担。我采取了几个步骤来缓解这个问题:
cached_property
进行后期初始化(请参阅here和here),以便只需要初始化所需的对象(包括import
相关模块)web.py
实现,包装我的类)。然后通过简单的curl
调用(例如nagios)触发服务。这大大减少了负载,从超过20个CPU负载变为远低于1。对于具有大量相互依赖性的复杂程序,python启动似乎非常耗费资源。
我想知道人们在这里采取了哪些策略来提高python软件的性能。
答案 0 :(得分:3)
一个简单的一次性改进是使用PyPy代替标准的CPython用于长期存在的脚本和守护进程(对于短期脚本,它不太可能有所帮助,实际上可能有更长的启动时间)。除此之外,听起来你已经对短期系统脚本进行了一次最大的改进,这就是为了避免为频繁调用的脚本启动Python解释器的开销。
例如,如果你从另一个脚本中调用一个脚本并且它们都在Python中,那么你应该考虑将另一个脚本作为模块导入并直接调用它的函数,而不是使用subprocess
或类似的。 / p>
我理解并不总是可以这样做,因为一些用例依赖于调用外部脚本 - 例如,Nagios检查在任何时候都要保持驻留是很棘手的。您使实际检查脚本成为简单HTTP请求的方法似乎足够合理,但我采用的方法是使用passive checks并运行外部服务来定期更新状态。这允许服务生成检查结果作为守护进程驻留,而不是要求Nagios为每个检查调用脚本。
此外,请观察您的系统,看看缓慢是否真的是CPU过载或IO问题。您可以使用vmstat
等实用程序来监视您的IO使用情况。如果你是IO绑定,那么优化你的代码不一定会有很大帮助。在这种情况下,如果您正在处理大量文本文件(例如日志文件),那么您可以将它们存储为gzip并使用Python的gzip
模块直接访问它们。这会增加CPU负载,但会降低IO负载,因为您只需要从磁盘传输压缩数据。您也可以使用相同的方法直接以gzip格式编写输出文件。
我担心我不是特别熟悉web2py
,但你可以调查一下,如果数据的新鲜度并不是完全关键,那么将缓存层放在前面是否容易。尝试并确保您的服务器和客户端都正确使用条件请求,这将减少请求处理时间。如果他们使用的是后端数据库,您可以调查memcached之类的内容是否会有所帮助。如果您遇到相当大量的请求或者每个请求的处理成本都很高,这些措施只会给您带来真正的好处。
我还应该补充一点,通常以其他方式减少系统负载偶尔会带来惊人的好处。我曾经有一个运行Apache的相对较小的服务器,我发现移动到nginx帮助了一个惊人的数量 - 我相信它部分更有效的请求处理,但主要是它释放了一些内存,文件系统缓存可以用来进一步提高IO-约束操作。
最后,如果开销仍然存在问题,那么请仔细分析最昂贵的脚本并优化热点。这可能会改进你的Python代码,或者它可能意味着将代码推送到C扩展,如果这是你的选择。通过将数据路径代码推送到C扩展中以进行大规模日志处理和类似任务(一次讨论数百GB的日志),我获得了一些出色的性能。然而,这是一种重型且耗时的方法,应该留给您真正需要提速的少数几个地方。这也取决于你是否有一个熟悉C的人可以做到这一点。