日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python性能解决_我们如何发现并解决Python代码中性能下降的问题

發(fā)布時(shí)間:2023/12/1 python 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python性能解决_我们如何发现并解决Python代码中性能下降的问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Python部落(python.freelycode.com)組織翻譯,禁止轉(zhuǎn)載,歡迎轉(zhuǎn)發(fā)。

作者:Omer Lachish

最近,我們已經(jīng)開始使用RQ庫代替Celery庫作為我們的任務(wù)運(yùn)行引擎。第一階段,我們只遷移了那些不直接進(jìn)行查詢工作的任務(wù)。這些任務(wù)包括發(fā)送電子郵件,確定哪些查詢需要刷新、記錄用戶事件和其他維護(hù)工作。

在部署完成之后我們注意到,任務(wù)數(shù)量相同的情況下,與Celery庫相比,RQ庫需要更多的CPU去執(zhí)行這些任務(wù)。我想我應(yīng)該分享一下我是如何分析和解決這個(gè)問題的。

關(guān)于Celery庫和RQ庫的區(qū)別

Celery庫和RQ庫都有工作進(jìn)程的概念,而且都使用分支來允許多種任務(wù)并行運(yùn)行。當(dāng)你啟動(dòng)一個(gè)Celery工作進(jìn)程時(shí),它會(huì)分到幾個(gè)不同的進(jìn)程,每個(gè)進(jìn)程會(huì)自主地處理任務(wù)。使用RQ庫,一個(gè)主進(jìn)程將只會(huì)實(shí)例化一個(gè)子進(jìn)程(稱為“Worker Horse”),該子進(jìn)程在執(zhí)行完一個(gè)單獨(dú)的任務(wù)后將會(huì)結(jié)束。當(dāng)主進(jìn)程從隊(duì)列中提取另一項(xiàng)任務(wù)時(shí),它將會(huì)派出一個(gè)新的Work Horse。

在RQ庫中,通過使用更多的工作進(jìn)程,即可實(shí)現(xiàn)與Celery相同的并行性。 但是,Celery庫和RQ庫之間存在著細(xì)微的區(qū)別:Celery進(jìn)程在啟動(dòng)時(shí)會(huì)實(shí)例化多個(gè)子進(jìn)程,并將其重用于多個(gè)任務(wù)。 而使用RQ庫時(shí),你必須給每一個(gè)任務(wù)分配進(jìn)程。 兩種方法都有優(yōu)點(diǎn)和缺點(diǎn),但這些內(nèi)容不在本文討論范圍之內(nèi)。

標(biāo)桿分析法

在介紹任何內(nèi)容之前,我想要確定一個(gè)基準(zhǔn),即一個(gè)工作容器處理1000項(xiàng)任務(wù)需要多長時(shí)間。我決定把重心放在record_event工作上,因?yàn)樗且环N頻繁的,輕量級(jí)的操作。我使用time命令來衡量性能,這里需要修改一下源代碼:為了得出完成1000項(xiàng)任務(wù)所需的時(shí)間,我傾向于采用RQ庫的burst模式,該模式在處理完作業(yè)后會(huì)退出流程。

我想避免測(cè)量那些被安排在基準(zhǔn)測(cè)試時(shí)間段的任務(wù)。因此,在task/general.py中的record_event聲明上方,通過將@job('default')替換為@job('benchmark'),可以將record_event移至一個(gè)名為benchmark的專用隊(duì)列。

現(xiàn)在我們可以開始計(jì)時(shí)了。首先,我想查看一個(gè)進(jìn)程啟動(dòng)和停止需要多長時(shí)間(沒有任何工作)以便之后可以從任何結(jié)果中減去該時(shí)間:

在我的計(jì)算機(jī)上,進(jìn)程初始化需要14.7秒。我會(huì)記住這個(gè)時(shí)間。

然后,我將1000個(gè)虛擬的record_event任務(wù)添加進(jìn)benchmark隊(duì)列中:

現(xiàn)在,運(yùn)行相同的命令,看看處理1000項(xiàng)任務(wù)需要多長時(shí)間:

減去14.7秒的啟動(dòng)時(shí)間,我們看到4個(gè)進(jìn)程處理1000項(xiàng)任務(wù)需要102秒。現(xiàn)在,讓我們嘗試找出原因!為此,在進(jìn)程工作的同時(shí),我們將使用py_spy模塊。

分析

讓我們?cè)僭黾?000項(xiàng)任務(wù)(因?yàn)樯洗蔚臏y(cè)試已經(jīng)刪除了所有任務(wù)),運(yùn)行進(jìn)程并同時(shí)監(jiān)控它們所耗費(fèi)的時(shí)間:

我知道,最后一條命令非常短。 理想情況下,出于可讀性考慮,我會(huì)在每個(gè)“ &&”上都打斷該命令,但是這些命令應(yīng)該在同一個(gè)docker-compose exec worker bash session中按順序運(yùn)行。所以,以下是其功能的快速分析:在后臺(tái)中,burst模式下,開啟了4個(gè)進(jìn)程。

等待15秒(大致讓它們完成啟動(dòng)。

安裝py-spy模塊。

運(yùn)行rq-info命令,并且為其中一個(gè)進(jìn)程進(jìn)行分層控制。

在該控制過程中記錄10秒中的活動(dòng)情況并將其保存到profile.svg文件中。

結(jié)果如下火焰圖所示:

從火焰圖中,我注意到record_event在sqlalchemy.orm.configure_mappers中花費(fèi)了很大一部分的執(zhí)行時(shí)間,并且每次處理一項(xiàng)工作時(shí)這種情況都會(huì)出現(xiàn)。從它們的文檔當(dāng)中,我知道了:初始化到目前為止已構(gòu)建的所有映射器的映射器間關(guān)系。

的確不需要在每一個(gè)分支上都發(fā)生這種事情。所以,我們可以在主進(jìn)程當(dāng)中一次性地初始化這些關(guān)系,避免在多個(gè)子進(jìn)程當(dāng)中重復(fù)性這些工作。

因此,在啟動(dòng)進(jìn)程之前,我已經(jīng)對(duì)sqlalchemy.org.configure_mappers()進(jìn)行了調(diào)用,并再次進(jìn)行了測(cè)試:

如果我們減去14.7秒的啟動(dòng)時(shí)間,4個(gè)線程處理1000項(xiàng)任務(wù)的時(shí)間將從102秒減少到24.6秒。 比以前提高了4倍! 通過修復(fù)此程序,我們成功地將RQ生產(chǎn)資源減少了4倍,并保持了相同的吞吐量。

我認(rèn)為,你應(yīng)該記住,在單線程和多線程的情況下,應(yīng)用的行為是有所不同的。如果每一項(xiàng)任務(wù)沒有繁重的重復(fù)的工作要做,通常最好在分到多個(gè)線程之前進(jìn)行一次。這些事情在測(cè)試和開發(fā)過程中不會(huì)出現(xiàn),因此請(qǐng)確保您進(jìn)行充分的測(cè)試并挖掘出任何會(huì)出現(xiàn)的性能問題。英文原文:https://blog.redash.io/how-we-spotted-and-fixed-a-performance-degradation-in-our-python-code/

譯者:Lyx

總結(jié)

以上是生活随笔為你收集整理的python性能解决_我们如何发现并解决Python代码中性能下降的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。