天天看點

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

2016年的雙11在淘寶上買買買的時候,天貓和優酷洋芋一起做了聯合促銷,在天貓雙11當天購物滿xxx元就贈送優酷會員,這個過程需要使用者在優酷側綁定淘寶賬号(登入優酷、提供淘寶賬号,優酷調用淘寶api實作兩個賬号綁定)和贈送會員并讓會員權益生效(看收費影片、免廣告等等) 這裡涉及到優酷的兩個部門:passport(在上海,負責登入、綁定賬号,下文中的優化過程主要是passport部分);會員(在北京,負責贈送會員,保證權益生效) 在雙11活動之前,passport的綁定賬号功能一直在運作,隻是沒有碰到過大促銷帶來的挑戰

接入中間件drds,讓優酷的資料庫支援拆分,分解mysql壓力

接入中間件vipserver來支援負載均衡

接入集團drc來保障資料的高可用

對業務進行改造支援amazon的全鍊路壓測

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

上圖是壓測過程中主要的階段中問題和改進,主要的問題和優化過程如下:

優化過程中碰到的比如淘寶api調用次數限流等一些業務問題就不列出來了

由于使用者進來後先要登入并且綁定賬号,實際壓力先到passport部分,在這個過程中最開始單機tps隻能到500,經過n輪優化後基本能達到5400 tps,下面主要是闡述這個優化過程

login 主要處理登入請求

userservice 處理登入後的業務邏輯,比如将優酷賬号和淘寶賬号綁定

為了更好地利用資源每台實體加上部署三個docker 容器,跑在不同的端口上(8081、8082、8083),通過bridge網絡來互相通訊

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

說明:這裡的500 tps到5400 tps是指登入和将優酷賬号和淘寶賬号綁定的tps,也是促銷活動主要的瓶頸

在userservice機器上通過netstat也能看到大量的syn_sent狀态,如下圖:

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

這時socketconnect異常不再出現

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

docker(bridge)----短連接配接--->通路淘寶api(淘寶open api隻能短連接配接通路),性能差,cpu都花在si上;

如果 docker(bridge)----長連接配接到主控端的某個代理上(比如haproxy)-----短連接配接--->通路淘寶api, 性能就能好一點。問題可能是短連接配接放大了docker bridge網絡的性能損耗

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

去掉docker後,性能有所提升,繼續通過perf top看到核心态尋找可用的local port消耗了比較多的cpu,gif動态截圖如下(可以點選看高清大圖):

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

注意圖中ipv6_rcv_saddr_equal和inet_csk_get_port 總共占了30%的cpu

一般來說一台機器可用local port 3萬多個,如果是短連接配接的話,一個連接配接釋放後預設需要60秒回收,30000/60 =500 這是大概的理論tps值

同時觀察這個時候cpu的主要花在sy上,最理想肯定是希望cpu主要用在us上,截圖如下:

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

sy占用了30-50%的cpu,這太不科學了,同時通過 netstat 分析連接配接狀态,确實看到很多time_wait:

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

于是讓pe修改了tcp相關參數:降低 tcp_max_tw_buckets和開啟tcp_tw_reuse,這個時候tps能從1000提升到3000

居然性能又回到了500,太沮喪了,其實最開始賬号綁定慢,passport這邊就懷疑taobao api是不是在大壓力下不穩定,程式員一般都是認為自己沒問題,有問題的一定是對方 :) ,taobao api那邊給出調用資料都是1ms以内就傳回了(alimonitor監控圖表)。

于是懷疑從優酷的機器到淘寶的機器中間鍊路上有瓶頸,但是需要設計方案來證明這個問題在鍊路上,要不各個環節都會認為自己沒有問題的,當時passport的開發也隻能拿到login和userservice這兩組機器的權限,中間的負載均衡、交換機都沒有權限接觸到。

在嘗試過tcpdump抓包、ping等各種手段分析後,設計了場景證明問題在中間鍊路上。

壓測的時候在userservice ping 淘寶的機器;

将一台userservice機器從負載均衡上拿下來(沒有壓力),ping 淘寶的機器;

從公網上非優酷的機器 ping 淘寶的機器;

這個時候奇怪的事情發現了,壓力一上來場景1、2的兩台機器ping淘寶的rt都從30ms上升到100-150ms,場景1 的rt上升可以了解,但是場景2的rt上升不應該,同時場景3中ping淘寶在壓力測試的情況下rt一直很穩定(說明壓力下淘寶的機器沒有問題),到此确認問題在優酷到淘寶機房的鍊路上有瓶頸,而且問題在優酷機房出口扛不住這麼大的壓力。于是從上海passport的團隊找到北京passport的pe團隊,确認在優酷調用taobao api的出口上使用了snat,pe到snat機器上看到snat隻能使用單核,而且對應的核早就100%的cpu了,因為之前一直沒有這麼大的壓力是以這個問題一直存在隻是沒有被發現。

于是pe去掉snat,再壓的話 tps穩定在3000左右

優化到3000tps的整個過程沒有修改業務代碼,隻是通過修改系統配置、結構非常有效地把tps提升了6倍,對于優化來說這個過程是最輕松,成本效益也是非常高的。實際到這個時候也臨近雙11封網了,最終通過計算(機器數量*單機tps)完全可以抗住雙11的壓力,是以最終雙11運作的版本就是這樣的。 但是有工匠精神的工程師是不會輕易放過這麼好的優化場景和環境的(基線、機器、代碼、工具都具備配套好了)

優化完環境問題後,3000tps能把cpu us跑上去,于是再對業務代碼進行優化也是可行的了。

代碼中的第二個問題是我們程式中很多異常(fillinstacktrace),實際業務上沒有這麼多錯誤,應該是一些不重要的異常,不會影響結果,但是異常頻率很高,對這種我們可以找到觸發的地方,catch住,然後不要抛出去(也就是别觸發fillinstacktrace),列印一行error日志就行,這塊也能省出10%的cpu,對應到tps也有幾百的提升。

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

部分觸發fillinstacktrace的場景和具體代碼行(點選看高清大圖):

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

對應的火焰圖(點選看高清大圖):

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程
10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

整個useragent調用堆棧和cpu占用情況,做了個彙總(useragent不啟用tps能從4700提升到5400)

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

實際火焰圖中比較分散:

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程

最終通過對代碼的優化勉勉強強将tps從3000提升到了5400(太不容易了,改代碼過程太辛苦,不如改配置來錢快)

優化代碼後壓測tps可以跑到5400,截圖:

10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程10+倍性能提升全過程--優酷賬号綁定淘寶賬号的TPS從500到5400的優化曆程