跨境茶話會8月期丨性能優化的藝術

跨境茶話會8月期丨性能優化的藝術

大師兄說:

衆所周知,對於現在國內的互聯網環境,不管什麼樣的系統,一旦等用戶的訪問量上去之後,我們每增加一個功能實際上都是要考慮它的吞吐量和延遲,在加工上都是要做一個縝密的思考的。所以我相信在這方面許多人都有自己一些獨到的見解,有許多人也會對這方面比較感興趣的。所以我們這次就組織了一個關於性能優化的話題。

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

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

來源:本文整理自跨境茶話會線上分享,爲魔窗原創首發,轉載需獲得授權。

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

跨境茶話會8月期丨性能優化的藝術

【嘉賓丨耿茂】:大家好,我叫耿茂,我現在在Pinterest做SRE工程師,之前是做過多年的性能工程師。

跨境茶話會8月期丨性能優化的藝術

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

【嘉賓丨王羽嘉】:好的,大家好,我叫王羽嘉。之前在EMC和現在在Splunk都是做性能工程師,當然我目前主要是負責性能測試的自動化、性能測試的快速迭代的項目。

跨境茶話會8月期丨性能優化的藝術

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

【嘉賓丨任志超】:大家好,我是任志超,現在在小紅書,目前負責整個測試團隊,前面也在做一些我們小紅書性能保障和全鏈路壓測的一些事情,所以很高興有機會跟大家做一些分享和交流。

跨境茶話會8月期丨性能優化的藝術

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

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

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

但事實上在整個優化過程中說實話離不開各個技術崗位的配合,其中就包括我們的產品,甚至包括我們的運營,包括我們的研發團隊,包括我們自己的測試團隊,包括我們運維的體系和實時響應的效率。我分享幾個場景,第一是在整個電商業務的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企業在職高級工程師,面向所有互聯網從業技術人員分享交流先進理念和實戰案例,同時爲中美技術朋友提供跨境交友和深度學習的平臺。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章