我是怎么從30個(gè)并發(fā)平均每個(gè)2000毫秒 到 300個(gè)并發(fā)平均每個(gè)178毫秒的

最近一個(gè)多月一直在做服務(wù)器的性能優(yōu)化浮声,老大的要求是要做到300個(gè)并發(fā)睡互,控制在200毫秒以內(nèi)丛楚,就說說我最近做的內(nèi)容吧截碴。
從30個(gè)并發(fā)平均每個(gè)2000毫秒 到 300個(gè)并發(fā)平均每個(gè)178毫秒
簡單介紹一下做了那些優(yōu)化:
01、減少log日志的打印
02尺上、減少redis的交互
03材蛛、耗時(shí)操作的處理
04、大文件信息的存儲(chǔ)
05怎抛、python的緩存機(jī)制
06卑吭、異步處理非返回操作

一、定位耗時(shí)操作 -- 唯一變量法

由于之前一直定位錯(cuò)誤马绝,導(dǎo)致了很多彎路豆赏,現(xiàn)發(fā)現(xiàn)一個(gè)比較好的定位方法 --- 逐個(gè)函數(shù)定位
需要借用壓測(cè)工具:wrk 或 jmeter

測(cè)試性能順序:純服務(wù)器性能 -- 加上參數(shù)處理時(shí)的性能 -- 加上第一個(gè)函數(shù)時(shí)的性能 -- 加上第二個(gè)函數(shù)時(shí)的性能 等等
如果在添加某一個(gè)步驟時(shí)性能變差很多,說明里有問題,需要仔細(xì)排查
簡單放兩個(gè)對(duì)比圖

純服務(wù)器性能 + 參數(shù)處理時(shí)的性能


+參數(shù)處理時(shí).png

純服務(wù)器性能 + 參數(shù)處理時(shí)的性能 + 讀取音頻


+讀取音頻

我們發(fā)現(xiàn)兩個(gè)性能測(cè)試只差一個(gè)讀取音頻函數(shù) 但形成卻相差很多河绽,說明在讀取音頻這里是一個(gè)巨大的耗時(shí)己单,那么就要想辦法處理掉

二、性能處理

01耙饰、我們可能會(huì)感覺打印一個(gè)log不會(huì)是耗時(shí)操作纹笼,但通過唯一變量法發(fā)現(xiàn) 打印log也是耗時(shí)的,因?yàn)橐刂圃?00ms以內(nèi)苟跪,那就是任何耗時(shí)的都要深思熟慮廷痘,于是減少log的打印

02、當(dāng)對(duì)redis做讀取操作時(shí)件已,每次讀取都要花費(fèi)幾毫秒笋额,那就想辦法優(yōu)化甚至怎么減少redis的讀取:

優(yōu)化:
a篷扩、當(dāng)能確認(rèn)并必確認(rèn)這是第一個(gè)存儲(chǔ)并不需要獲取時(shí)兄猩,就可以減少一次獲取,直接存儲(chǔ)鉴未。
b枢冤、要使用redis的緩存池
c、使用redis的通道法
減少判斷:
先假想代碼處理流程铜秆,中間用到了幾次redis的讀取淹真,然后通過redis的INFO commandstats 命令,定位redis的耗時(shí)连茧,以及有沒有多余的操作

redis的耗時(shí)

數(shù)據(jù)信息為:操作次數(shù) – 總耗時(shí) – 平均耗時(shí)
這樣我們就能清清楚楚的看到用到了幾次讀寫操作核蘸,分別耗時(shí)多少
具體詳見:
redis的使用,以及耗時(shí)定位

03+04+05啸驯、耗時(shí)操作的處理
一般指:mysql的讀取 -- I/O操作
當(dāng)頻繁性的使用一個(gè)數(shù)據(jù)時(shí)就要想著做緩存處理客扎,緩存也會(huì)考慮處理時(shí)間,個(gè)人感覺處理時(shí)間(如有不對(duì)坯汤,請(qǐng)斧正):
本地磁盤 > redis > 內(nèi)存 > 機(jī)制化內(nèi)存
通過”定位耗時(shí)操作 -- 唯一變量法“ 得知虐唠,音頻文件的讀取是一個(gè)很耗時(shí)的操作,那么就做緩存處理惰聂。

方法一:redis緩存

說到緩存數(shù)據(jù),首先想到了內(nèi)存性數(shù)據(jù)庫redis咱筛,于是想辦法將音頻存至redis中搓幌,操作很簡單,以音頻名稱為key值 -- 讀取的信息為value進(jìn)行存儲(chǔ)(注意類型為bytes類型) + 過期時(shí)間(redis的存儲(chǔ)大小為512M)
很快代碼寫完了迅箩,那就測(cè)測(cè)效果吧溉愁,一次效果還不錯(cuò),提升了不少饲趋,但還是很耗時(shí)拐揭,而且與想象的相差很多撤蟆,預(yù)想存儲(chǔ)redis,讀取都是幾毫秒 最多也就10+毫秒的時(shí)間堂污,為什么測(cè)試結(jié)果與預(yù)想結(jié)果查那么多家肯,在redis讀取那里加上時(shí)間,測(cè)一下讀取時(shí)間盟猖,一看打印時(shí)間都在80+以上有的甚至到達(dá)150+讨衣,后來發(fā)現(xiàn)原因:數(shù)據(jù)過大,讀取緩慢

方法二:cacheout緩存

于是將音頻的數(shù)據(jù)存至內(nèi)存中式镐,發(fā)小效果不錯(cuò)反镇,幾乎不耗時(shí),達(dá)到了理想狀態(tài)娘汞。
轉(zhuǎn)念一想歹茶,數(shù)據(jù)會(huì)一直累加與服務(wù)器內(nèi)存,導(dǎo)致整個(gè)服務(wù)器增加你弦,于是查找有效的緩存機(jī)制辆亏,就找到了cacheout緩存
它可以設(shè)置同時(shí)設(shè)置多個(gè)緩存,并且可以設(shè)置緩存機(jī)制(優(yōu)先策略)鳖目,設(shè)置有效條目數(shù) 以及 設(shè)置有效時(shí)間扮叨, 大多數(shù)操作基本和redis一樣,簡單易懂

    # 判斷是否存在
    cache["voice_store"].has(voice_id)
    # 根據(jù)key獲取
    cache["voice_store"].get(voice_id)
    # 存儲(chǔ)
    cache["voice_store"].set(voice_store_key, voice_body)
方法三:redis + cacheout

(主要考慮到負(fù)載均衡领迈,可能會(huì)有多個(gè)服務(wù)彻磁,但會(huì)公用一個(gè)redis)
按理說現(xiàn)在已經(jīng)完全達(dá)到了要求,對(duì)音頻(根據(jù)url下載的)的處理已經(jīng)最優(yōu)化了狸捅,但有一個(gè)問題是音頻文件還一直存在于服務(wù)器內(nèi)衷蜓,增加內(nèi)存,那就想辦法移除尘喝。
于是就有了這個(gè)redis + cacheout的想法磁浇。
存儲(chǔ):
URL下載音頻 -- 讀取音頻 -- 將音頻信息存至redis 和 緩存中 -- 刪除音頻文件
讀取:
獲取音頻名稱 -- 緩存查找 -- redis查找 -- URL下載存儲(chǔ)

06朽褪、異步處理非返回操作
一次請(qǐng)求處理中置吓,打印log和發(fā)送日志,以及一些I/O是避免不了的缔赠,所以我們會(huì)用到子線程異步存儲(chǔ)衍锚,讓這些耗時(shí)的去一邊處理,不影響主線的處理嗤堰。
另加一個(gè)小點(diǎn)-如果你的用戶請(qǐng)求是有順序的戴质,那么在存儲(chǔ)redis時(shí)也可以用一下時(shí)間差,但一定要把握好!
我這里用的是twisted的threads

threads.deferToThread(save_user_info, "voice_body", voice, 1)

附送:使同步阻塞函數(shù)秒表非阻塞異步并發(fā)函數(shù)--twisted框架
一告匠、使同步函數(shù)秒變異步并發(fā)函數(shù)
如果需要返回值戈抄, 如run2()函數(shù)
給請(qǐng)求函數(shù)添加裝飾器@inlineCallbacks
并使用yield進(jìn)行接收返回值

@inlineCallbacks
def run2():
    """
    主函數(shù)
    """
    # 將耗時(shí)函數(shù)放入另一個(gè)線程執(zhí)行,返回一個(gè)deferred對(duì)象
     d = yield (threads.deferToThread(largeFibonnaciNumber))

     # 等待返回的結(jié)果 再做處理
     print(d)

二后专、如果不需要返回值可以使用addCallback回調(diào)函數(shù) 如run()函數(shù)

def run():
    """
    主函數(shù)
    """
    # 將耗時(shí)函數(shù)放入另一個(gè)線程執(zhí)行划鸽,返回一個(gè)deferred對(duì)象
    d = threads.deferToThread(largeFibonnaciNumber)
    # 添加回調(diào)函數(shù)
    d.addCallback(fibonacciCallback)

具體代碼見項(xiàng)目中的other目錄


Python小學(xué)僧.gif

Git代碼: 公眾號(hào)后臺(tái)回復(fù) python_sanic

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市行贪,隨后出現(xiàn)的幾起案子漾稀,更是在濱河造成了極大的恐慌,老刑警劉巖建瘫,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崭捍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡啰脚,警方通過查閱死者的電腦和手機(jī)殷蛇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來橄浓,“玉大人粒梦,你說我怎么就攤上這事≥┦担” “怎么了匀们?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長准给。 經(jīng)常有香客問我泄朴,道長,這世上最難降的妖魔是什么露氮? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任祖灰,我火速辦了婚禮,結(jié)果婚禮上畔规,老公的妹妹穿的比我還像新娘局扶。我一直安慰自己,他們只是感情好叁扫,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布三妈。 她就那樣靜靜地躺著,像睡著了一般陌兑。 火紅的嫁衣襯著肌膚如雪沈跨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天兔综,我揣著相機(jī)與錄音,去河邊找鬼。 笑死软驰,一個(gè)胖子當(dāng)著我的面吹牛涧窒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锭亏,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼纠吴,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了慧瘤?” 一聲冷哼從身側(cè)響起戴已,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锅减,沒想到半個(gè)月后糖儡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怔匣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年握联,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片每瞒。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡金闽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剿骨,到底是詐尸還是另有隱情代芜,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布浓利,位于F島的核電站挤庇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏荞膘。R本人自食惡果不足惜罚随,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望羽资。 院中可真熱鬧淘菩,春花似錦、人聲如沸屠升。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腹暖。三九已至汇在,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脏答,已是汗流浹背糕殉。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國打工亩鬼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阿蝶。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓雳锋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親羡洁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子玷过,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容