用PyPy加速Python代码

用PyPy加速Python代码

事情背景

我们业务服务使用了Metric+Graphite+Grafana这套业务指标收集系统,Graphite 可以实时收集、存储、显示时间序列类型的数据(time series data)。它主要有三个部分构成:

  1. graphite webapp —— 基于 Django 的网页应用程序。
  2. carbon —— 基于 Twisted 的进程,用来接收数据;
  3. whisper —— 专门存储时间序列类型数据的小型数据库;

线上业务众多数据收集量很大,采用了分布式的收集方案即前端carbon-relay按业务前缀转发到后端的容器和物理机carbon服务上,部署在容器的服务指标使用carbon-aggregator做聚合收集,部署在物理机的服务指标使用carbon-cache做收集。通过grafana配置graphite-web(这个graphite-web去连接后端多个carbon的graphite-web)来生成服务指标面板,根据业务需求配置图表展示和指标异常预警。

graphite-web去连接后端多个carbon的graphite-web这边经常出现下面的这种连接异常,出现问题时候graphite-web的Django进程使用CPU达到100%(单核跑满),grafana侧读取graphite数据为空从而触发很多的无效报警,给业务同学带来不好的体验。

排查优化

grafana配置的graphite-web源要访问后端全部carbon节点的graphite-web,先提升graphite-web访问本地whisper的速度,这块参考官方文档中的CARBONLINK_HOSTS配置,直接访问本地CACHE_QUERY_PORT,如下:

CARBONLINK_HOSTS = ['127.0.0.1:port']

graphite-web源访问后端全部carbon节点的graphite-web这条链路进行优化,查看网友的实践方案

参考:Graphite的百万Metrics实践之路 存储使用SSD、carbon-aggregator做聚合这些都已经实现,使用全套go方案重新的架构https://github.com/grobian/改起来也不现实,作者提到一个使用PyPy代替Python的方案,看起来可行。

PyPy 的官网https://speed.pypy.org ,看介绍比cpython还快

参考:用 PyPy 让你的 Python 代码运行得更快!本地mac上验证PyPy比Python快了35倍

mac上的Python是3.10版本,线上机器用的是Python2.7的版本,测试也有10倍的提升

安装PyPy

替换graphite机器(centos7.9)默认的Python

1、安装pypy
bunzip2 pypy2.7-v7.3.17-linux64.tar.bz2 
tar -xvf pypy2.7-v7.3.17-linux64.tar 
cp -r pypy2.7-v7.3.17-linux64  /usr/local/

2、安装依赖的库
yum install gcc-c++ libstdc++-devel  lapack-devel lapack -y
/usr/local/pypy2.7-v7.3.17-linux64/bin/pypy -m ensurepip
/usr/local/pypy2.7-v7.3.17-linux64/bin/pypy -m pip install --upgrade pip
/usr/local/pypy2.7-v7.3.17-linux64/bin/pip install tagging parse cairocffi  django==1.7.0 twisted==15.5.0 whisper numpy wheel 
/usr/local/pypy2.7-v7.3.17-linux64/bin/pip install scipy
/usr/local/pypy2.7-v7.3.17-linux64/bin/pip install django-tagging

3、替换Python
ln -s /usr/local/pypy2.7-v7.3.17-linux64/bin/pypy python2

这样带来一个问题,yum就没有办法用了,需要修复一下yum依赖的Python配置

1.vim /usr/bin/yum
将#!/usr/bin/python改成#!/usr/bin/python2.7(默认python版本)

2.vim /usr/libexec/urlgrabber-ext-down
将#!/usr/bin/python改成#!/usr/bin/python2.7(默认python版本)

前面文章中提到PyPy 只适用于长时间运行的程序,刚好这个graphite-web就属于这类应用,替换后graphite-web的Django进程使用CPU维持在20%上下,网络连接也比之前减少了很多。

写在最后

使用PyPy替换Python带来的性能提升可以暂时满足我们的需求,持续运行了一个多月未再出现之前的异常情况,后续再出现架构瓶颈的话需要考虑其他的方案。

留下回复

error: Content is protected !!