国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

記一次tornado QPS 優(yōu)化

Doyle / 3644人閱讀

摘要:初步分析提升可從兩方面入手,一個是增加并發(fā)數(shù),其二是減少平均響應(yīng)時間。大部分的時間花在系統(tǒng)與數(shù)據(jù)庫的交互上,到這,便有了一個優(yōu)化的主題思路最大限度的降低平均響應(yīng)時間。不要輕易否定一項公認(rèn)的技術(shù)真理,要拿數(shù)據(jù)說話。

本文最早發(fā)表于個人博客:Pylixm"Wiki

應(yīng)項目的需求,我們使用tornado開發(fā)了一個api系統(tǒng),系統(tǒng)開發(fā)完后,在8核16G的虛機(jī)上經(jīng)過壓測qps只有200+。與我們當(dāng)初定的QPS 大于2k差了一個數(shù)量級,于是便開始了漫長的優(yōu)化之路。在優(yōu)化過程中,學(xué)了許多東西,有必要整理記錄下備查。

我們的技術(shù)選型:

python2.7

tornado4.4.3

sqlalchemy1.1.5

mysql5.6

rabbitmq

當(dāng)初技術(shù)選型的時候選擇tornado,便是因為其優(yōu)秀的性能,這么低的QPS自然是不甘心。究竟tornado可以達(dá)到多少Q(mào)PS呢?于是編寫了簡單的hello world,在上邊的虛擬機(jī)中起16個進(jìn)程下,使用ab壓測QPS竟然達(dá)到了驚人的6K,平均響應(yīng)時間在毫秒級。這下有信心將api的QPS繼續(xù)優(yōu)化了。

初步分析

提升QPS, 可從兩方面入手,一個是增加并發(fā)數(shù),其二是減少平均響應(yīng)時間。從目前情況看,增加進(jìn)程并發(fā)數(shù)是最直接的手段,但當(dāng)達(dá)到機(jī)器資源的瓶頸時,可靠堆疊機(jī)器來解決。那么
相比較下,減小平均響應(yīng)更為重要。初步分析了我們開發(fā)的api,平均響應(yīng)時間在幾百毫秒級別。大部分的時間花在系統(tǒng)與數(shù)據(jù)庫的交互上,到這,便有了一個優(yōu)化的主題思路:最大限度的降低平均響應(yīng)時間。

我們API完成的功能為,接受請求參數(shù)做一些列的認(rèn)證判斷(與數(shù)據(jù)庫交互),將消息以廣播的形式發(fā)送到rabbitmq供消費(fèi)者消費(fèi),最后返回給客戶端發(fā)送結(jié)果。根據(jù)此邏輯,影響響應(yīng)時間的地方,分析如下:

與mysql 數(shù)據(jù)庫的交互

使用rabbitmq廣播消息時的時間耗費(fèi)

耗時的業(yè)務(wù)邏輯代碼片段

優(yōu)化思路

根據(jù)上邊的問題,從以下幾個方面入手:

增加tornado的異步特性

分析與數(shù)據(jù)庫的交互,減少與數(shù)據(jù)庫的交互時間

分析rabbitmq的時間耗費(fèi),減少發(fā)送信息時間

優(yōu)化業(yè)務(wù)代碼邏輯

具體實施 tornado 的異步特性

開發(fā)api時,因為對tornado 的異步特性不是很熟悉,便沒有使用。后來隨著測試的深入,發(fā)現(xiàn)需要使用后,開始了解。
隨著了解的深入,發(fā)現(xiàn)tornado是并沒有很好的支持?jǐn)?shù)據(jù)庫的異步特性,更多是對網(wǎng)絡(luò)的異步,官網(wǎng)上也是寫的”網(wǎng)絡(luò)非阻塞框架“。
查閱官方文檔,tornado的異步實現(xiàn),見官方文檔
總的來說,使程序異步的方式有3種,參考這里。如下:

第一種,使用tornado 的 gen.coruntine。

使用此種方式,需要異步數(shù)據(jù)庫的驅(qū)動庫,經(jīng)查找現(xiàn)階段并沒有很好的成熟的支持異步查詢mysql的python驅(qū)動,放棄此種方案。

第二種,使用tornado 的線程模塊。

此種方式比較方便,只需要在耗時的函數(shù)上添加裝飾器即可,簡單方便,可以說是一種萬能方案,但此方案耗費(fèi)系統(tǒng)資源。
系統(tǒng)資源并不是我們的瓶頸,我們最后采納了此種方式。

第三種,使用外部隊列,多帶帶其worker 進(jìn)程或線程去處理。例如,celery 等。

此種方式增加了外部的依賴,增加了系統(tǒng)的復(fù)雜性和后期的維護(hù)難度,放棄此種方案。

增加了異步特性外有顯著的提升。

mysql 數(shù)據(jù)庫的優(yōu)化

數(shù)據(jù)庫方便,我們適用的是SQLAlchemy。使用ORM時,在減少裸sql帶來的查詢復(fù)雜度的同時,必然會增加查詢數(shù)據(jù)庫的耗時。我們也做過測試,
使用pymsql鏈接mysql,直接使用裸sql查詢與使用sqlalcemy 的對象查詢的耗時差別有7、8個毫秒的時差,與sqlalchemy的裸sql方式執(zhí)行時間幾乎一致。
可見,sqlalchemy的orm方式是有一定時間耗損的。stackoverflow的一個問題,也驗證了我的想法,見Why is loading SQLAlchemy objects via the ORM 5-8x slower than rows via a raw MySQLdb cursor?

針對數(shù)據(jù)庫方面,我們做了如下優(yōu)化:

將SQLAlchemy 查詢改為核心裸sql方式,可參考這里。

優(yōu)化數(shù)據(jù)庫,增加必要的索引。

將邏輯中的過濾條件,盡量的移到sql中,減少sql結(jié)果集的大小,加快查詢速度。

將可以單詞查詢出的數(shù)據(jù)集放到一次查詢中,減少鏈接數(shù)據(jù)庫的次數(shù)。

分析rabbitmq的時間耗費(fèi),減少發(fā)送信息時間

rabbitmq 方面,使用的是pika 作為驅(qū)動庫連接的,使用方式是每次發(fā)送數(shù)據(jù)的時候創(chuàng)建鏈接和通道,發(fā)送完畢后立即關(guān)閉鏈接。考慮到是否可以使用長鏈接,創(chuàng)建鏈接后不關(guān)閉,只關(guān)閉channel。修改后發(fā)現(xiàn)報錯,具體代碼如下:

# -*- coding:utf-8 -*-
import pika
from settings import settings


class Client(object):
    def __init__(self, host, port, username, pwd):
        self.host = host
        self.port = port
        self.username = username
        self.pwd = pwd
        self.init_connection()

    def init_connection(self):
        user_pwd = pika.PlainCredentials(self.username, self.pwd)
        self.connection = pika.BlockingConnection(pika.ConnectionParameters(
            host=self.host, port=self.port, credentials=user_pwd))

    # ... 

補(bǔ)充錯誤材料分析 - todo

翻閱了pika的文檔,發(fā)現(xiàn)其有異步的使用方式,且有與tornando 框架的結(jié)合的實例,見文檔。
pika的異步方式,使用了和tornado 相同的基于epull的事件循環(huán)模型,如何將其與tornado 的IOloop結(jié)合是個問題,
其有個tornado的鏈接適配器,翻看其代碼還是有些不太明確如何使用,有時間的時候再繼續(xù)研究下。

針對rabbitmq的優(yōu)化我們放棄了,但優(yōu)化過程中有些值得分析的文章,整理如下:

rabbitmq-amqp-channel-best-practices

rabbitmq-best-practices-for-designing-exchanges-queues-and-bindings

tornado與pika結(jié)合實例

優(yōu)化業(yè)務(wù)代碼邏輯

代碼邏輯方便的優(yōu)化,如下:

減少循環(huán)

review 邏輯,去除冗余邏輯

提取公共變量,賦值一次,減少查詢數(shù)據(jù)庫。

總結(jié)

經(jīng)過以上的優(yōu)化,我們的api 的 QPS 提升到了1200+, 由于時間問題,我們暫停了繼續(xù)的優(yōu)化。通過本次QPS的優(yōu)化過程,有幾點感悟:

使用一項新技術(shù)時,一定要認(rèn)真閱讀官方文檔,了解清楚后,再使用。

不要輕易否定一項公認(rèn)的“技術(shù)真理”,要拿數(shù)據(jù)說話。

個人工作總結(jié),歡迎留言交流!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/40750.html

相關(guān)文章

  • 一次PHP并發(fā)性能調(diào)優(yōu)實戰(zhàn) -- 性能提升104%

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同的機(jī)制,通常也被稱為處理器間中斷,。文章編寫計劃 待完成: 詳細(xì)介紹用到的各個工具 作者: 萬千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無論是php, java, 還是其他任何語言都是用. 如果你有php使用經(jīng)驗, 那肯定就更好了 業(yè)務(wù)背景 框架及相應(yīng)環(huán)境 laravel5.7, mysql5.7, redis5, nginx1.15 cento...

    番茄西紅柿 評論0 收藏0
  • 一次PHP并發(fā)性能調(diào)優(yōu)實戰(zhàn) -- 性能提升104%

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同的機(jī)制,通常也被稱為處理器間中斷,。文章編寫計劃 待完成: 詳細(xì)介紹用到的各個工具 作者: 萬千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無論是php, java, 還是其他任何語言都是用. 如果你有php使用經(jīng)驗, 那肯定就更好了 業(yè)務(wù)背景 框架及相應(yīng)環(huán)境 laravel5.7, mysql5.7, redis5, nginx1.15 cento...

    xeblog 評論0 收藏0
  • 一次 JAVA 的內(nèi)存泄露分析

    摘要:展示如下場景再現(xiàn)經(jīng)過分析,最后我們定位到是使用產(chǎn)生的內(nèi)存泄露問題。下面通過一個,來簡單講下具體內(nèi)存泄露的原因。這一次的內(nèi)存泄露問題算是解決了。總結(jié)關(guān)于內(nèi)存泄露問題在第一次排查時,往往是有點不知所措的。 記一次 JAVA 的內(nèi)存泄露分析 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留出處:https://github.com/jasonGeng88/blog 當(dāng)前環(huán)境 jdk == 1.8 ...

    Tecode 評論0 收藏0
  • python:一次簡單的模擬flask和cgi服務(wù)器

    摘要:目前來說文章亮點就是解耦做的還行,有一定的可擴(kuò)展性簡單的仿實現(xiàn)路由分發(fā)規(guī)定應(yīng)用程序需要是一個可調(diào)用的對象可調(diào)用對象接收兩個參數(shù)可調(diào)用對象要返回一個值,這個值是可迭代的。 最近web服務(wù)器知識,中間懶癌犯了,斷了一兩天后思路有點接不上來,手頭上也有其他事情要做,先簡單的總結(jié)下學(xué)習(xí)進(jìn)度,很多重要的功能都沒跑通,目前flask只是簡單實現(xiàn)路由分顯示不同的結(jié)果,cgi可以根據(jù)不同的靜態(tài)資源或者...

    Aldous 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<