【中美技術專家分享實錄】性能優化的藝術

圖片描述

*大師兄說:
衆所周知,對於如今國內的互聯網環境,無論什麼樣的系統,一旦等用戶的訪問量上去以後,咱們每增長一個功能實際上都是要考慮它的吞吐量和延遲,在加工上都是要作一個縝密的思考的。因此我相信在這方面許多人都有本身一些獨到的看法,有許多人也會對這方面比較感興趣的。因此咱們此次就組織了一個關於性能優化的話題。*前端

全網首發·技術乾貨·大咖對話java

整理:魔窗丨 15618字丨20分鐘閱讀python

來源:本文整理自跨境茶話會線上分享,爲魔窗(magic-window)原創首發,轉載需得到受權。mysql

【主持丨大師兄】:你們好,我是本次跨境茶話會主持人張申竣,朋友們也能夠叫我大師兄,目前擔任魔窗CTO。我先介紹一下本期嘉賓。首先介紹一下咱們的耿茂。redis

圖片描述

【嘉賓丨耿茂】:你們好,我叫耿茂,我如今在Pinterest作SRE工程師,以前是作過多年的性能工程師。sql

圖片描述

【主持丨大師兄】:咱們介紹第二位嘉賓王羽嘉,來自Splunk,和你們打個招呼吧。數據庫

【嘉賓丨王羽嘉】:好的,你們好,我叫王羽嘉。以前在EMC和如今在Splunk都是作性能工程師,固然我目前主要是負責性能測試的自動化、性能測試的快速迭代的項目。後端

圖片描述

【主持丨大師兄】:第三位嘉賓是任志超,他目前在小紅書是整個測試團隊的負責人。緩存

【嘉賓丨任志超】:你們好,我是任志超,如今在小紅書,目前負責整個測試團隊,前面也在作一些咱們小紅書性能保障和全鏈路壓測的一些事情,因此很高興有機會跟你們作一些分享和交流。性能優化

圖片描述

【主持丨大師兄】:咱們接下來第一個環節是想請三位嘉賓分別談一下他們在本身公司所作的一些關於性能優化和性能測試方面的一些最佳的實踐,志超你先來談一下吧。

【嘉賓丨任志超】:能夠,從我我的的一些歷史經驗來看,我以爲在互聯網企業裏面,由於我前面在蘑菇街大概工做兩年,而後又來到小紅書,如今大概有半年多的工做經驗,大部分的時間可能會跟不一樣的業務場景和業務產品下面的性能壓力打交道。

我我的認爲在不一樣的業務模式和互聯網的場景下來,性能保障和優化是一個須要考慮不一樣場景下的一個綜合考慮的命題。事實上同一套方法論或者同一套優化理論在不一樣的業務模式下多是徹底不適應的。在小紅書這塊,由於實際上它是分爲兩塊,一塊是電商,另一塊是社區。在這兩塊不一樣的產品下面它的性能的優化和穩定、調優都是不一樣的方向。從我這邊的感觸來講,對電商來講更多的是,第一它會有一個峯值,從電商的峯值來講,對於大促一般是十倍以上的平時的壓力。在這個地方咱們更多的考慮是說在峯值狀況下的配比,以及基於它的不一樣的架構模式下咱們怎麼找到壓力的平衡點,基於壓力的平衡點,咱們預先對這一段壓力在大促前進行擴容,來保證它的平穩經過。也就是說對於像小紅書這樣的企業來講,咱們更可能是簡單粗暴,若是可以解決當前的問題就先解決當前的問題,而後再從架構層面咱們怎麼去拆微服務,怎麼去作隔離,怎麼去把數據遷移出來,把核心的鏈路保持穩定,以及作好總體的監控。

但事實上在整個優化過程當中說實話離不開各個技術崗位的配合,其中就包括咱們的產品,甚至包括咱們的運營,包括咱們的研發團隊,包括咱們本身的測試團隊,包括咱們運維的體系和實時響應的效率。我分享幾個場景,第一是在整個電商業務的66大促保障過程當中咱們是提倡一直到66前的一天咱們還在作業務的開發。在這種狀況下整個66大促的性能的保障,咱們更可能是結合業務的開發同步進行一些業務場景的梳理和配比的調優。在這種狀況下咱們同時作線上的性能壓測,以及基於線上性能壓測快速地作擴容和迭代。若是找到一些敏感瓶頸點,那咱們會及時對這個瓶頸進行處理。同時在每個所謂的咱們可能發生問題的瓶頸點,咱們會加大監控和線上數據採集的力度。在這種時候,咱們實施上第一,責任到人,每一個節點咱們會有對應的責任人。第二,作好應急預案,對於每一塊的業務,擔憂它出現問題的時候,咱們用什麼樣的應急預案。第三,咱們作好前期的數據的隔離,事實上咱們在大促前作了幾個業務系統的數據遷移。基於這些數據遷移咱們能夠保障咱們的核心內幕儘可能不要有其餘的業務數據會打到咱們的核心數據上面來,保證咱們核心數據的統一。

在整個的過程當中咱們事實上還會碰到各類各樣的一些問題的,因此在小紅書這一類的企業更可能是整個性能壓測和性能條有是持續改進和持續變化的工做。相對來講假設咱們是在一個大公司,好比阿里、京東這一類的企業,他們第一是更有計劃性。第二,可能會相對來講有更多的時間來投入在整個的性能保障和壓力上面。好比說他們在雙十一的全鏈路保障上面,他們可能從7月份開始就已經開始作今年的雙十一的整個的性能的準備和壓測了。事實上,好比說小紅書,咱們若是在作今年下半年紅五的大促保障的時候,咱們可能要到9月份,甚至10月份纔開始。而這個過程當中整個大促的開發,還有整個大促的業務的演進可能都還在進行中。

因此從這一點來講,不一樣的互聯網的工做模式和業態,以及公司的當前所處的階段會決定你對於整個性能和線上業務穩定性保障的不一樣的策略。這是我從小紅書和之前蘑菇街的經驗來看到的個人一些感悟。

【主持丨大師兄】: 好的,很是感謝。接下來羽嘉你講一下在Splunk的目前關於性能方面的作法。

【嘉賓丨王羽嘉】:ok。剛纔志超這邊講了不少在互聯網行業這邊確實是比較傳統的作法。可是在Splunk這多是一個很是特別的案子,由於Splunk自己它的業務場景就很特別,首先它的定位就是一個企業級的軟件,可能跟互聯網的行業差距比較大。簡單先說一下Splunk的場景是什麼,他自己主要像咱們你們都知道的ElasticSearch同樣,他們都是對非結構化的數據作索引和搜索的。因此這種行爲更可能是面向好比說IT的管理人員或者說是devops,他們可能會更多地使用Splunk這樣的產品。

它的場景其實主要能夠分爲兩類,一個就是作索引,一個就是作搜索。因此我能夠簡單說一下針對索引和搜索這兩塊咱們是怎麼考慮它的性能的。首先說作索引吧,其實它的索引行爲其實也是很簡單,好比說咱們會指定某一類的數據源,對這個數據源咱們會把它的數據首先要抓出來,而後扔到Splunk裏面去作index。這個行爲咱們能夠理解爲它是由多個管道串聯起來的,第一個管道就是我首先要在數據源的性能以及Scalability能夠保證的前提下,這樣我可使用多線程並排的方式去從一個單一的數據源裏面把數據都抓出來。

我舉個例子,好比說咱們可能會對AWS S3這些全部的key作抓取,那我能夠用多線程的方式把它都抓出來。一般是多個管道(pipeline),其實咱們這邊的作法也比較傳統,多個管道鏈接的話咱們都會用到Queue,我把數據抓出來以後我會把它扔到一個Queue裏面,而後由下一個管道的具體的線程去處理個人Queue裏數據,從而傳輸到個人下一層管道里面。這樣的話,若是考慮是否是在個人多個管道鏈接的過程中,會不會有一些瓶頸的存在,咱們會monitor每一個Queue的size和length,就是看每一個Queue當前的一個累積的數據數量是多少,那麼我從而能夠定位到具體是哪一個管道的行爲比較慢,這個咱們能夠再繼續作優化。

另一個點,由於咱們涉及到多線程從一個pipeline裏面去扔到另一個pipeline裏面,因此必然會考慮到寫checkpoints,由於只有寫checkpoints的話才能避免我在一個多線程去抓數據的時候可以保證數據沒有重複,而且沒有丟失數據。通常來講checkpoints的讀寫其實有不少種方式能夠作。固然好比說讀寫內存或者是文件,或者是數據庫,那這樣的話咱們要去考慮咱們想達到的throughput是多少,固然可能性能最優的就是對數據庫的讀寫,同時也要考慮我單獨去衡量我這個數據庫讀寫的性能可以達到多少,從而能夠保證我一個點對點的整體的吞吐量是多少。這個就是咱們抓數據,而且對數據作索引,整個的flow是這個樣子的。

若是是另一種場景,就是作搜索,作搜索的話實際上是徹底又不同的。Splunk咱們這邊用的搜索語言叫SPL,是咱們本身的作搜索的一種比較特別的Language,你們能夠理解爲就像咱們在查詢數據庫用SQL同樣。這個語言其實自己同樣能夠像SQL同樣寫得很是複雜,包括有嵌套,包括也是相似於用一個管道去鏈接的。因此可能超過百分之六七十以上的狀況你去優化搜索行爲的話,更多你要優化你的SPL,在這個語言上的優化多是佔的比重比較大的。並且咱們的搜索雖然是給用戶直接使用,可是它的主要的面向對象可能不少的狀況下是IT或Devops,因此它對於搜索的高併發要求並非很是高。因此咱們一般來講可能十幾個用戶是一個很是高的併發量了。

對於搜索咱們其實也有一些優化的考慮,這個可能跟Splunk本身的一些技術相關係。好比我舉一個例子,Splunk作索引和搜索跟ElasticSearch最大的差異是,像ElasticSearch更可能是說我在數據進來的時候我會把對應的那些字段抽取出來,而且作index。可是Splunk偏偏相反,它對不少的字段其實並非直接被寫到index裏的,它仍是都存在於你的raw data的,也就是說我其實在進index的時候這個行爲是很是快的,可是作搜索的時候其實在搜索的runtime裏面會把你的字段再從新抽取出來做爲你能夠看到的字段。因此這個行爲就會致使你的搜索實際上是比較慢的。在這塊咱們有不少的優化方式。主要目的就是讓用戶能夠更加動態,更加靈活地使用我進來的這些數據。這多是一個比較大的話題,好比Splunk支持把一部分的字段的數據或者必定時間範圍內的數據寫進index,這個是能夠在數據進來的後期去作的。其實在這塊是一種邏輯層面上的優化,可是這種優化對用戶直接的使用的體驗效果會很是好。這只是一個例子,若是更多人有興趣的話咱們其實能夠再去討論更多的細節。

這邊主要是我這邊的一些經驗,關於Splunk的索引和搜索的場景。

【主持丨大師兄】:好,謝謝羽嘉。看來針對搜索由於是一個比較大的話題,咱們從此在下幾期也能夠考慮單獨開一個關於搜索的話題。接下來咱們請耿茂幫咱們講一下Pinterest的常規的一些作法。

【嘉賓丨耿茂】:那我簡單介紹一下Pinterest的一些經驗。我在加入Pinterest以前其實我是在Oracle、EMC、SuccessFactors這些公司,更多的是企業級軟件和服務的公司裏面作性能工程師。因此這些企業軟件基本上就是三層架構,從Web服務器到應用服務器到數據庫,固然也會有一些可擴展性的設計。好比說應用服務器無狀態,而後能夠動態擴容,數據庫能夠分庫,能夠Sharding。基本上的性能工做模式是比較容易找到每個層次不一樣的壓力測試點,會針對不一樣的特性咱們能夠去作不一樣的測試。外部服務器可能常常會出現的是網絡鏈接的壓力,或者是網絡響應時間的壓力。

應用服務器可能不少時候是java的,會有jvm的性能優化還有垃圾收集的調優。還有應用自己對於請求的處理狀態,是線程模型呢,仍是一個異步的網絡I/O模型,這都會有不一樣。

像數據庫的話可能更多的關注於數據的存儲路徑,好比說數據它的存儲路徑要合理地優化,設計的表結構足夠合理,老是可以和快速地存取。這些經驗多是針對傳統的企業軟件基本上能夠套用這一套規律。

可是我進入Pinterest以後就至關因而跨了一個行業,進入到面向用戶的服務上。Pinterest如今主要是手機用戶佔了八成以上,另外還有兩成是來自於網頁。但背後都是使用咱們的服務,幾乎全在AWS之上。從架構上是有很大的不一樣,是說內部會有不少的微服務,和傳統的企業軟件不同了。這些微服務咱們在Pinterest裏面可能有上百個。固然核心的幾個服務,面向用戶的幾個服務你們會比較熟悉,咱們SRE會接觸的多一些,可是有好些服務咱們也只知道個名字,並不清楚它內部是如何實現的。

因此做爲一個運維工程師對於關心性能來講的時候,咱們主要是要知道每個服務的性能指標,好比說這個服務它可以接受多少個併發請求,它的50%的響應時間應該是多少,90%的響應時間應該是多少。因此,這裏面有一個很重要的實踐,針對全部的這些微服務,就是說每個服務必需要定義一個SLA,叫作服務水平協議。好比說這個服務要達到好比說99.9%的可用性,它的90%的響應時間應該要在50毫秒之內,它可以響應的請求數每秒好比說是10萬或者百萬,這些就是這個服務要達到的目標。在一個新的服務被設計的時候首先要考慮這個目標,它的設計架構要可以支持到這個目標。因此在每一個服務咱們也有一個相應的Service Owner來負責這樣一個服務的SLA。這是針對微服務上我感受的一個重要的不一樣。

另外還有一個,由於有不少的服務,這些服務之間的依賴是很複雜的關係。有時候基本上就算是參與其中的工程師或者是架構師都不可以徹底掌握清楚。因此這裏面有很重要的是一個工具,怎麼樣把這個服務之間的依賴暴露出來。在Pinterest內部是有一個工具基於開源的軟件叫Zipkin,來創建的。它的工做機制主要就是說在每一個服務的客戶端和服務端一塊兒都會埋入一些代碼,而後產生一個日誌。這個日誌會帶有一個惟一的請求ID,或者叫作Span ID,這一個Span ID就是從用戶的一個請求開始,一直記錄他這個請求所流過的每個服務,這每個服務都會有這樣的相同的ID。因此在不少不一樣的服務都產生日誌以後,咱們的日誌抓取平臺把這些蒐集起來以後而後會有一些聚合處理,最後把處理的結果放到一個ElasticSearch的集羣裏面。最後咱們能夠經過一個叫作Pintrace,基於zipkin的一個網頁UI而後來檢查這樣一個請求所通過的全部服務。而後經過匯聚不少的請求,咱們能夠獲得一個服務之間的依賴圖。而後這個依賴圖裏面咱們能夠知道這個服務與服務之間的請求流量大小。因此這對於咱們知道這個系統的整個情況是頗有用的一個工具。每個服務在實現的時候都要遵循必定的規範,都要接入這樣一個支持zipkin的日誌的埋點。這是微服務的另一方面。

除了Zipkin用做服務的請求響應時間的收集以外,還有一個很重要的東西,就是收集每個服務它的性能指標。這裏面性能指標多是有基本的服務裏面的每個虛擬機的CPU使用率、內存使用率,它的網絡的IO,塊讀寫的IO,全部這些東西都會產生一些metrics,而後被集中到一箇中心的監視系統。這樣一個性能監視系統會蒐集上百萬個,甚至上千萬個不一樣的metrics。而後在咱們的每個服務基本上都會定義一個dashboard, 而後能夠實時地呈現這樣一個服務的性能情況。

因此若是有問題的時候立刻就會有page,報警到相應的服務的負責人。固然整個網站來說的話,若是整個Site有問題,或者一些重要的路徑有問題,就會先報警到SRE的平臺,而後咱們通過分析以後定位哪個服務有問題,而後相應的確定會有這個服務的負責人會被page到,而後這個服務的負責人會來解決這個問題。基本上這是咱們運維的一個實踐。

在日常還有關於性能的另一個很重要的實踐就是從公司上下對性能的指標都很在乎。這是公司CEO制定的很重要的一個目標。他定義一個叫作性能目標的協議,而後發給全部的工程師。因此性能工做不是隻是性能工程師或者SRE工程師的工做,而是全部人的目標。你們首先上線新的功能或者新的服務首先都要保證這樣一個性能目標不會降低,好比用戶的響應時間不會降低,用戶體驗不會降低。

相應的性能的調優工做有不少資深的工程師都一直在投入其中,他們會去仔細地檢查,好比說咱們使用的網絡庫,好比說咱們用到一個庫叫Finagle,它又用到Netty,在用到這些服務的響應時間在十個毫秒之內或者是更小,這樣子他們對網絡的鏈接的打開、關閉都很是敏感。因此有工程師會專門的去研究,而後去找到能夠調優的地方,而後經過調整這樣一些庫,由於這些庫是全部服務都用到的,因此在這樣一個庫的性能優化能夠達到很是顯著的性能調優效果。

因此基本上這是個人一些體會。

【主持丨大師兄】:謝謝耿茂,耿茂剛剛已經講得很是詳細了。由於在接下去的環節咱們是準備了一些特定的關於性能的主題想和嘉賓一塊兒採用互動的方式一塊兒交流一下。其中有一塊就是關於在分佈式環境下的一個線上的性能檢測,我想耿茂已經很好地回答了這個問題。

剛剛許多嘉賓也談到了一個全鏈路的性能檢測和性能測試的問題,由於咱們知道性能指標更多的應該是反映一種業務指標,從一個用戶的請求到拿到響應結果,它在什麼狀況下它可以支持多少個併發,在這些併發下要求的一個延時有多少,它實際上是整個的一個端到端全鏈路的過程。

首先第一個問題,我想跟你們探討一下,在條件容許的狀況下,若是說咱們要作性能測試,那我如何去模擬生產環境的測試。由於你們都知道,性能測試最關鍵的一點就是儘可能要去模擬真實的一個線上的環境,包括數據和併發量,那你獲得的整個的測試結果對你來講纔是有參考價值的。個人第一個問題是你們以爲在模擬真正的一個線上環境上面,你們以爲有什麼好的作法?還有一種觀點就是可能根本我就沒有辦法真實地去模擬線上的狀況,那我就是在線上直接去測了,有問題再直接調整。

關於這個問題我想聽一下你們的見解,三位嘉賓有先想關於這個問題發表一下本身的意見嗎?

【嘉賓丨王羽嘉】:好的。咱們先說一下線上吧,由於Splunk這個產品其實它的特色就是我今天說的它很特別,它能夠把非結構化的數據作索引和搜索。其實,用戶在使用的時候,用戶使用的任何的日誌的信息其實默認都是能夠走進到Splunk index裏面去的,因此說對於線上的用戶,好比說咱們能夠到他們的生產環境裏面去,而後經過咱們的Search,基本上是能夠看到用戶的行爲的,好比他最近遇到了一個很是慢的search,那麼咱們能夠看到他的search發生時間的時候,系統中具體的一些狀況。好比說CPU的使用狀況,以及系統中是否是有一些在後臺job在工做,這些東西咱們均可以看得很清楚。從這個角度來看,咱們比較容易地幫他去定位一個問題。

【主持丨大師兄】:因此Splunk的作法是事先也沒有辦法真實地模擬在線上的環境,我就直接作一個基本的調優,而後讓用戶去線上跑,若是有問題的話我再真實地去查看線上的這樣一個上下文環境,去定位問題,再告訴用戶怎麼去作一些優化。

【嘉賓丨王羽嘉】:對,這是一個很是challenge的行爲。可是咱們更多的總歸仍是要作性能的測試,性能測試的時候咱們可能會想無論用戶有沒有問題,咱們須要去了解到用戶他們的使用的數據是什麼樣子的,這個狀況其實咱們的作法是固然咱們確定是經過咱們的PM去跟用戶那邊看他們的數據量大概是多少,咱們基本上是會了解一些指標,這些指標不包括他們好比說天天有多少的數據進來,而後天天他們進來的數據的數據的格式是什麼樣子的。由於進來的數據的格式多是千奇百怪,可能咱們要清楚。並且好比說有一些用戶,像這個用戶自己就是一個CDN的廠商,他確定會進來不少的網絡的數據,網絡數據裏面一旦被index的話會有一些好比說IP,source IP或者destination IP,這些都會進來。都會進來的話,它的數據值的變化量,好比它的IP的range大概有多少,其實對咱們最終作search都會有很大的影響。因此像這些指標咱們都要搞清楚,就是它數據的總量,以及數據在這個總量下面每個字段的變化是有多少,是一千種、一萬種仍是十萬種。而後咱們根本他們給咱們提供的指標,好比說咱們會有一個內部的工具專門來生成這些數據的。咱們把這些數據生成出來,生成在咱們的測試環境裏面去,而後咱們來跑咱們的測試,而後來評估咱們的測試有沒有達到咱們最終的標準(criteria)。

【主持丨大師兄】:也就是說實際上整個的數據的分佈狀況是大家先會和客戶作一個充分的溝通,而後利用一些溝通的結果,根據客戶提的意見而後去模擬這部分數據,而後去作一個測試?

【嘉賓丨王羽嘉】:對的。

【主持丨大師兄】:那志超和耿茂關於這個有什麼意見嗎?由於可能Splunk是一個企業的產品,你們針對於互聯網的產品的狀況下以爲有沒有可能也能夠這樣去作呢?

【嘉賓丨任志超】:實際上在我所經歷的兩家互聯網的電商企業,蘑菇街和小紅書來看,基本上你要在線下環境,就是在咱們的測試環境裏面去作線上的性能測試和調優是一個僞命題。我爲何這樣說呢?事實上我在兩家公司都經歷了這種從沒有作微服務,到微服務改造的過程。整個系統架構是處於一個在原來蘑菇街是一個統一,就是一個PHP的大的一個單服務的狀況下,最後改爲基於java的阿里的這一套整個的微服務體系。小紅書是目前來講正在從python轉向基於java的這種微服務。整個這樣的一個分佈式系統它的鏈路的調用規則和水位分佈實際上是在動態變化和調整過程當中的。若是說咱們強調全鏈路的性能測試或者說線上性能壓力的能力,從某種意義上來講,你在線下很難搭建一個完整的分佈式的這樣一個模型來實時地模擬如今當前的系統架構的演進。

第二,就算有這樣一個線下的測試環境。第一,它的一些相關依賴,好比我舉一個例子,好比說redis,好比說存儲,好比說MQ,這些第三方的依賴它的第一處理能力,它的SOI的水平和線上都是會有區別的。包括咱們的數據的第二個大小,好比說咱們到存儲這一級別,小紅書大部分仍是用mongo,蘑菇街之前是mysql,那不一樣的存儲集羣對數據的響應和性能都是不同的。而在一個本身數據中心的一個環境和你好比說用AWS或者騰訊雲下面的這種雲服務這樣的一個封閉式的環境下面,它的性能場景也都是不同的。因此在個人實踐裏面,咱們一般來使用作性能的測試或者是作全鏈路的測試一般是基於如下三個方式。

第一,日誌回放。咱們一般作的是咱們會在業務層面都會收集各類訪問日誌和你的使用日誌。在必定的時間,咱們一般說是半夜12點或者12點半之後等整個線上的業務下來之後,咱們會隔離一些機器而後作線上白天的日誌回放。

第二,咱們寫一部分的針對某一個單點寫一些單點鏈路腳本,在夜裏咱們針對這個單點的壓測腳本,一樣把線上的服務作隔離之後對它進行壓測。

第三,咱們作影子庫,作壓測打標,咱們會對全部的咱們的壓測鏈路加上咱們的測試標這一層能夠在線上進行,或者在咱們的底層的業務中間層作處理。作了壓測打標之後事實上也是在夜裏12點之後一般來講咱們會統一的對整個線上進行釋壓來去模擬真實的用戶場景。

爲何咱們說相對來講咱們仍是能夠模擬出來比較真實的用戶產品。第一,咱們會先作幾個事情。一是對歷史的峯值的壓力審閱的一個梳理。也就是說咱們會對歷史上好比上一次大促咱們的模型是什麼樣子的。我舉一個簡單的場景,好比說有一萬個用戶同時進到咱們的首頁,其中六千個用戶可能去訪問了某個會場頁,由會場頁進到商詳頁裏面可能大概併發量是在一千五,那這個時候下單的用戶可能就是在五百,下單之後到支付多是三百到一百五之間。因此基於這樣的使用模型你能夠基於咱們的線上的這種當前架構下面的接口的調用鏈路,也就是剛纔耿茂跟你們分享的,咱們有一些工具能夠把當前線上的這種鏈路調用關係以圖形和鏈路的形式反映出來。基於這樣一個鏈路調用關係咱們能夠援引出來壓測的行爲,因此基於這樣的壓測行爲咱們能夠去開發全鏈路的壓測腳本,而這個壓測腳本是基於咱們如今已有的單鏈路腳本之上開發和更新的。在這樣的狀況下咱們能夠約定在某一個時間,好比說開發、運維和測試的同窗你們都在半夜12點之後咱們同時開始對線上的鏈路進行集中的壓測,那這個壓測不是針對單點的,是針對全鏈路的。

在這樣的狀況下,加上咱們的測試打標,能夠把這些壓力真實地打到咱們的線上的系統,可是同時又不會產生好比說咱們擔憂的,產生一些垃圾數據,是否是影響咱們的業務數據,是否是影響咱們線上的一些真實的體驗。基於這樣的壓測打標之後咱們能夠從業務系統裏面,能夠從咱們的線上服務裏面把這些數據從最終的用戶當中去掉。可是事實上我能夠對線上的系統進行實時的真實的模擬。

這樣的三種模式下咱們能夠針對某一個點,某一臺機器,甚至某一個服務,和全鏈路進行有效的線上的壓測。固然這一切都離不開整個團隊的配合,也就是第一,咱們要有足夠好的監控手段,就是剛纔耿茂說的,咱們的APM,內部鏈路的關係,咱們的Sentry,咱們的業務的日誌的收集,整個的運維的平臺必定要具有。

第二,咱們要具有全鏈路的施壓的能力,施壓能力提供一般來講若是用了其餘的好的的狀況下能夠採用一些開源的現存工具,好比說用阿里的PTS,或者用本身寫的基於Gatling這樣一個用戶式的調用施壓鏈路。還有一些好比說像阿里內部有一些本身內部的一些壓測工具,實在都沒有了,能夠直接用好比說AB、JMeter這樣子的一些工具對單點進行。可是經過一些鏈路的調用等一些引擎,能夠把這些施壓點串起來對整個系統構成壓力行爲的施壓,這樣纔可以對整個線上的系統是有價值的壓力測試的場景。

這是咱們這邊實踐的一些經驗。

【主持丨大師兄】:很是感謝。那耿茂,你關於這點有什麼向說的嗎?

【嘉賓丨任志超】:志超剛纔說的很好,他們的壓測作得很不錯。相比較而言,Pinterest說實話咱們就是在線上測,就沒有本身生成數據來作壓力測試這種東西。這裏面有幾個緣由,一個是咱們用AWS,是一個彈性的雲計算的環境,咱們的這些微服務基本上都是動態伸縮的。因此它在請求量大的時候基本上是能夠水平擴展,能夠去支持它的請求。因此若是咱們測試的時候,那相應的服務也會自動擴容去支撐這樣一個流量。只要AWS沒有出現問題,沒有自動擴容的能力受影響的話,通常不會有大的問題。固然,有一些存儲的服務他們基於MySQL,或者基於HBase,是須要作預先的切分的,不可以動態擴容的。這種多是先基於咱們實際的流量測試以後他們會有一個相應的準備。好比說會先劃分紅多少個數據庫,產生數據庫也可能在應對流量增加的時候預先作容量升級,從一個低CPU或者內存的服務器動態升級到高級的上面,在不影響服務的狀況下。這是AWS這個環境給咱們的一個能力,因此基本上每一個服務都會考慮在線升級、在線擴容的辦法。

咱們還有一個,若是有功能的變化或者是一些性能改進的話咱們一般是作AB測試。一樣一個服務可能有不一樣的環境,有A環境和B環境,一部分機器是A環境,一部分是B環境,你收集相應的性能指標以後作一個比較,而後發現確實是有進步,那咱們把它所有切換到你的優化上面。若是說性能不是你預想的那樣,那再回滾回來。因此一切都是經過動態的調整服務的集羣來實現的。

另外,咱們固然也有測試,這就是每一個服務本身的事情了。在一般作一些技術選型的時候會作足夠的測試,無論是MySQL也好,HBase也好,或者是其餘用到的一些ElasticSearch、Redis這樣的一些通用的開源技術,那就是會用相應的測試工具,若是有開源的拿開源的來用,若是沒有會本身寫一寫。而後來有針對性的針對這個服務的使用場景來測試這個基礎的技術的擴展性。還有在AWS上咱們會有一些測試,關於好比說EC2虛擬機類型的性能測試,咱們會測試它的新一代的虛擬機好比說I3, r4, c5這些不一樣的虛擬機的性能表現,以此來決定咱們是否是能夠升級換代一些。或者說從CPU優化的服務器換到存儲優化的服務器,會作一些這樣的測試,有針對性的。還有是由於這些跟操做系統的版本和Kernel也有關係,因此有不少測試也會針對不一樣的Kernel來看。由於那個影響其實還不小,可是全部這些測試必定是每一個服務單獨來看,而後逐漸的AB測試,而後逐漸的擴展到整個系統裏去。因此,有些升級變化會花很長的時間。

【主持丨大師兄】:謝謝,我接下去有個問題,實際上剛剛大家在講的是關於動態擴容的問題,那有沒有可能有一種狀況,由於有些問題多是架構上,或者是代碼上的一些問題,致使我可能前期沒有測出來,但真的等到線上環境之後,它不是靠擴容就能夠解決的,那我只根據java的話可能好比說會有Memory Leak,那等到你線上環境達到必定的量的時候出現了Memory Leak,那這種狀況通常是擴容解決不了,由於你擴一下機器它立刻就被消耗光了,通常出現這種狀況的話咱們應該怎麼樣去作一些線上的應對或者隔離?

【嘉賓丨耿茂】:在Pinterest的作法也是會有一個叫作rate limiter的東西,你能夠限容。這個rate limiter其實就是在客戶的一些庫而後java語言或者python語言這種,這個庫就是各類客戶端的語言都支持的,因此在客戶端調用的時候會受到rate limiter的限制,若是在後端的服務支撐不了動態擴容,不可以支持流量增加的事實那就會限容這樣子。

【主持丨大師兄】:那若是發生這種狀況的話,這個服務自己是有問題了,是打算把它隔離掉,仍是接下去會怎麼處理?

【嘉賓丨耿茂】:這個以後再處理,先扛住,不讓它完全當掉。就是限制上游來的流量,讓這個等於就是降級,因此只使用這部分服務的人受到一些影響。或者說,超過了必定量的用戶受到影響,可是基本上這個服務仍是暫時可用的,固然這個服務的負責人必定會想辦法怎麼樣把它儘快擴容,而後可以支撐,可以解除這樣一個流量限制。

【嘉賓丨任志超】:這邊咱們也能夠分享一下在電商這塊咱們的一些作法。一般來講做爲電商來講最大的心理壓力就是平時通常都沒有什麼流量,正常的用迭代、發佈,而後線上通常都不會有太大的問題。最大的問題其實就是來自於這種像大促期間流量基本上是十倍以上的增加,這種狀況下咱們通常來講正規的作法是第一,咱們會定預期水位,第二會定開關、降級預案,第三會對降級預案進行分解。對於降級預案進行分解會經過一些敏感服務,核心電路會產生什麼樣子的降級作一個定義,可能會降級會有一些降級開關,它也會有一些觸發條件,以及在這個觸發條件下面相關的操做。那這些操做一些是經過動態熔斷,好比我曾經作熔斷,另外一些就是經過業務熔斷來作的。好比說咱們把這個業務直接從前臺下掉了。第三個是咱們能夠在前臺統一作一些所謂的批量化,好比說把一些高併發的請求。

咱們曾經在蘑菇街作過這樣一個產品,就是在全部的客戶端的相應過程當中加上一層,當他在大促時間,大促時咱們把兩個開關開了之後,當客戶端提交這個請求,發現咱們咱們的返回值是某個制定的開關結果的時候,它會把全部的對後端的請求作緩存,因而我在接下來15秒鐘以內我不會對後臺發任何請求,對前臺會形成一個Loading的標識,對於客戶來講感受是慢了,可是事實上咱們仍是在有機會完成交易。另外一方面,對於一些可降級的,好比說前端的一些頁面。

好比舉個例子,咱們商詳頁,咱們會對它若干個區域,好比一些核心區域,價格確定是不能錯的,咱們的下單功能確定是不能少的,除此以外咱們都是能夠降級,在大促期間咱們有一個降級預案,當到這個水平的時候咱們會把商詳頁上的相關商品和相關筆記咱們再下掉。在這個時候當咱們降級被觸發之後在客戶端看到的頁面會只有標準的商詳和裏面的價格自己,以及一個下單的按鈕,其餘的額外的東西一切都沒有了。這是正常的狀況下的降級和熔斷。

可是就像你說的,總會有沒有測到的狀況。好比咱們出現過在大促前前一天剛上的一個業務,這個業務恰好是過了咱們全鏈路壓測的場景之後上去的。而這個業務就有一個while true的循環就鎖住咱們的數據庫,而當時確實就上去了,這個時候又沒有降級預案。那咱們的方法,第一,先定位到問題所在。發現當有這個問題,咱們整個數據庫鎖死,整個線上沒有反應的時候,咱們第一是回滾,由於基於咱們的線上的性能監控咱們能夠知道是哪一個服務出了問題。首先對這個服務進行暫時的線上的回滾,緊急回滾之後先定位到問題,定位到問題之後從新把開關設好,而且開開,在這種狀況下幾個手段咱們一般來講是並行開展的。就是降級、擴容,以及線上的緊急回滾和修復,整個是一個執行體系,和系統架構,和咱們的技術領域其實也沒有太大的關係,在任何其它領域均可以作相似的操做。

【主持丨大師兄】:謝謝。我這邊接下去的問題剛剛都有說了,就是整個系統的話不只僅是Performance團隊或者是測試團隊的事,而是和開發,和運維,和架構都相關。

個人一個問題是說可能在你不考慮性能的狀況下,那我上的功能確定決定是很快的,開發的話我就按功能開發完就沒事了。可是若是涉及到我這邊性能方面是有些要求,有些架構,就像各位剛剛介紹的同樣。首先要有一些微服務的監測,我每上一個功能是要有可監測的,我可能還會去準備一些降級的預案作一些隔離,那我要考慮到這些架構的方方面面的時候,那我怎麼同時可以保證個人開發上的敏捷度,或者怎麼樣去和真正的業務上的開發比較好的作一個協同呢?

【嘉賓丨任志超】:從咱們這邊的實踐來看說實話這是一個不斷教育的過程,可能由於我待的公司都比較特殊,都處在一個快速擴張的時間,進雲的速度是至關快。好比咱們一個業務可能在半年的時間裏面可能翻一翻,兩三翻 ,裏面的性能對於一些老同窗來講它對限容架構和當前的服務有些什麼問題他是很清楚的,在這樣一種狀態下仍是比較容易去作協同和擴展的。

可是,固然不斷的有新同窗來,團隊在不斷的擴充,新業務在不斷的增長的過程當中其實很難有一個合適的途徑對他進行一個教育。更多的是,第一,樹立一個Ramp up Plan的時候,咱們可能須要對他性能方面的專項的一個Enablement,就是讓他可以知道我所負責的這塊業務當前的一個性能模型是什麼意義,架構是什麼意義,之前有什麼坑,那這些坑咱們當時又怎麼解決的。

另一點,對於整個公司來講一般咱們都會有一個相對於底層的虛擬團隊也好,仍是一個基礎團隊也好,會負責對一些就像剛剛耿茂說的,對一些中間層,對一些公共庫咱們要作一些規範和標準化。好比說咱們會要求全部的目前來講全部的微服務中間層都採用Thrift協議,都採用長鏈讓咱們的服務尋址和路由都用咱們本身封裝好的REDRPC這一套。經過這樣一些分層和公共組件的隔離,咱們能夠把一些和性能相關的一些東西從這個裏面抽象出來,抽離出來,這樣對於業務開發的時候能夠更關注在業務自己。

第三點,目前來講大部分互聯網公司都在作先後端分離,那作了先後端分離之後對於業務的同窗一般來講會換成兩種不一樣的東西,第一種我聚焦在後端的接口開發,同時前端的同窗會對UI展示和交互進行一些設計,而後在這個設計過程當中經過和產品的緊密配合大概知道從業務的層面怎麼去優化交互的性能,有不少東西其實能夠在前端的層面去作的,好比咱們的一些CDN,咱們一些回源,咱們的一些接口的優化,其實是和整個業務開發的同窗是能夠作隔離的。

有了這些關鍵的作法之後,另一點就是一個按期了,由於對於電商來講按期的月促,每一年至少有兩次或者三次或者更多的大促,藉助這樣的機會咱們會對它進行幾輪的這種全鏈路的壓測和按期的單鏈路的壓測,其實就至關於在持續的更新和迭代的過程。經過這樣的過程教育新來的同窗讓他慢慢地成長起來。其實沒有什麼所謂的Silver bullet這種銀彈,更多的仍是執行力的過程。

【主持丨大師兄】:很是感謝。我相信可能大部分公司也都是這麼作的,接下來咱們時間差很少了,我這邊就留一些時間給一些聽衆,看看他們有什麼問題,或者你們有問題的話能夠在羣裏面提出來,讓嘉賓幫忙解答一下。

【嘉賓丨耿茂】:我看到餘侃有一個問題是關於Docker對吧?我正好能夠想講一下,這也是在Pinterest我一進去就開始作的事情。以前Pinterest的部署主要是基於Puppet,有不少的問題。由於Puppet在動態更新環境的時候可能會遇到一些意想不到的問題,好像依賴的包會有問題,或者其餘的東西,引發部署失敗。後面引入Docker以後一切經過Docker Image去部署的話,那就一切好了不少。用Puppet這是歷史緣由,之前是這麼搞的。如今替換成爲Docker以後這個部署就相應地穩定不少,可是不是全部的服務都被Dockerized的,只是還在一個遷移的過程中。至於Kubernetes和Mesos這塊如今Pinterest尚未大規模使用,Mesos咱們用在數據處理平臺上。像如今AWS autoscaling 再加上Docker Image這種方式,其實能夠作到動態的發佈回滾,挺方便的。

【主持丨大師兄】:我看到有一我的在問怎麼作性能相關的OKR或者KPI設計。我相信三位嘉賓當中可能Pinterest和Splunk的作法應該是會比較類似,可能小紅書又是不一樣的作法,我想請各位嘉賓分別講一下吧。

【嘉賓丨任志超】:對於我來講我最大的OKR就是保證大促的穩定,這個裏面咱們作設定的時候其實很簡單,由於大促一般來講就那一波過來咱們可以穩定地保證它平穩地經過,所謂的平穩經過就是說咱們全站,那核心的業務好比說咱們的下單支付,咱們的商詳,咱們的會場是能夠打開的。其實就和你在淘寶同樣,好比說你在雙十一去下單的時候,你下下去之後會不會全站都下不了單,碰到這種狀況確定你的KPI要掛了。我如今目前來講我對這塊更多的是保障在大促高峯的時候可以下單和支付和商詳頁這三個主鏈路不要出問題。

【主持丨大師兄】:因此志超你這邊更多的仍是比較偏業務的保證功能正常的指標吧。

【嘉賓丨任志超】:對,線上的。

【主持丨大師兄】:我想另外兩位嘉賓大家是否是會有更加關於請求的吞吐量和延時的指標呢?會有這些KPI嗎?

【嘉賓丨耿茂】:是,咱們在Pinterest SRE其實就是負責這個整個網頁和麪向手機客戶端的API的吞吐量和Success Rate。三個九的Success Rate是必須的。而後響應時間要在幾百毫秒之內,若是有低了以後立刻就會有報警告訴咱們。

【主持丨大師兄】:這個指標是誰定的呢?是基於一個什麼樣的場景會定一個具體的量化指標?

【嘉賓丨耿茂】:這仍是根據業務來的。像咱們的外部主頁其實有不少不一樣的路徑,像有的路徑是Create一個Pin,有的路徑是作一個搜索,有的路徑是直接看咱們的Home Feed,有的路徑是看Related Pin。因此每個路徑其實會有相應的團隊在背後,他們要背相應的指標的,好比Success Rate和響應時間。這是面向用戶使用場景的一個事情。

【嘉賓丨王羽嘉】:我稍微補充一點,對於Splunk來講可能第一指標是數據天天被index的數據量是多少,由於這個對於客戶來講,好比說它在客戶的生產環境裏,或者他本身的IT環境裏面可能天天的產生的數據量就是很是龐大的,他確實是能夠會比較合理地說,我爲了這些數據至少要在幾個小時以內都要被index進來,他對這個一天或者一個小時index的capability是很是在乎的。通常來講咱們會保證一天兩個TB的數據或者更多,這個是一個必備的指標。

【主持丨大師兄】:關於端到端的Tracking ID耿茂已經回答了, Zipkin是目前比較流行的分佈式的監測方案。

接下來最後一個問題,有一位同窗問了一下開發過程當中單用戶的性能和併發測試的實踐,這個問題應該是更多在於普通的Developer在開發過程當中如何對於Performance有敏銳的Insight,並付諸於實踐,寫出對於Performance友好的代碼。這個我不知道各位有對各自的一些Developer有這方面的一些要求嗎?

【嘉賓丨耿茂】:這個我說一下,像如今單用戶的測試在微服務的環境下是比較難作的,主要仍是經過trace,就是若是有一個請求進來,而後你能夠trace到全部通過的服務,每一個服務的響應時間都在這樣一個span裏面能夠體現出來,那你就很容易定位到問題在哪裏,能夠去優化。

【主持丨大師兄】:因此你的建議仍是在初期教育的時候儘可能去讓他們用一些比較通用的,特別是佔用外部資源的時候,可能就是佔用一些公用的一些內庫,就是保證基本的性能不會差到哪裏去,可能真正的測試仍是要到一個線上的環境評估一下這方面的性能?

【嘉賓丨耿茂】:對,我想其實最重要的就是你先埋入一些可測量的點,若是可以收集到這些實際的數據相應地來作性能調優,那就頗有針對性,並且就能夠省掉不少時間。固然你要埋入這些監視的東西須要花工夫,可是你作了之後會有很大的好處。

【嘉賓丨任志超】:我也贊成耿茂的,不過咱們這邊一般來講會在整個上線流程都會分爲幾個不一樣的階段,在開發的T環境下,一般來講他們會作自己開發追求的自己的功能測試。可是到了咱們SIT集成環境之後其實相關的一些依賴,目前來講是有的。咱們的測試過程當中會保證在有線上數據同步過來的狀況下會有些業務點在正常的處理模型下單用戶是OK的,也就是說咱們會在SIT的環境下對單用戶的性能作一些監測,這個監測包括響應時間等等。

等到C環境,就是咱們用線上的數據而後更新咱們服務代碼式的單獨的開發代碼的狀況下,咱們就能夠對線上的依賴進行一些基本的校驗。耿茂說的,咱們還有AB,AB上去的時候流量不是說一會兒全打過來的,多是經過灰度不斷地拉過來的,那在拉過來的過程當中一旦發現問題,能夠再回滾,整個的過程當中咱們的節奏裏面會相對來講有效的保障,若是真的有代碼問題,在針對上線之前咱們仍是有幾道關口能夠卡的,再加上耿茂剛剛說的鏈路的應用監控,也能夠從這個角度來有效的保障。

【主持丨大師兄】:大家以爲內部監控,由於自己它也有性能方面的Overhead,大家以爲這方面是好比如今一些開發的框架已經優化得不錯,仍是說再作埋點和Tracking的時候須要充分分析Overhead對於Production的影響。

【嘉賓丨耿茂】:個人見解是開源的已經作得很不錯了,可是本身仍是要注意,由於埋點是有Overhead的,若是你在一個循環裏面,好比說是一個很critical的code path裏面去作這些東西可能會影響到這個服務反而沒有起到監控的效果了,這個是經過灰度上線、AB上線的方式來及早發現,及早回滾,避免出現真正的問題。

【主持丨大師兄】:好,謝謝耿茂。咱們今天這期節目若是你們沒什麼問題的話就到這裏,咱們下期再見。謝謝三位嘉賓。

「跨境茶話會」是由移動增加技術服務商「魔窗」聯合國內外衆多技術專家發起的在線技術交流活動,目前已邀請嘉賓來自Google、ebay、Snap、Uber、VISA、Pinterest、BranchMeteics、Splunk、小紅書、華爲等國際知名IT企業在職高級工程師,面向全部互聯網從業技術人員分享交流先進理念和實戰案例,同時爲中美技術朋友提供跨境交友和深度學習的平臺。

「跨境茶話會」結合前沿熱點技術話題,精心策劃每個月一個線上技術主題交流,每期邀請來自國內外互聯網界的三位實戰嘉賓分享一線技術最佳實踐,並針對核心技術問題對話答疑,爲技術從業者拓寬思路、提高技術實力、驅動業務增加。

下期免費報名:https://www.wenjuan.net/s/3iu...

相關文章
相關標籤/搜索