高性能服務端的幾個驚人真相

Ett97Z 8年前發布 | 30K 次閱讀 高性能 性能測試 性能測試和優化

這是我在 2016 OpenResty 全球技術大會上面的分享,起了一個 驚悚 的標題,內容是我自己工作多年的總結。這篇文章是現場分享的文字版本,歡迎大家評論。

說到高性能服務端,沒有真正接觸的工程師都覺得有些神秘,高不可攀的樣子。而事實是什么呢?這里我結合自己接觸到的一些講講。

大部分性能測試都是錯的

這是第一個驚人真相。性能測試對于服務端是肯定需要做的,但真相是 90% 以上的性能測試都是錯的,我自己接觸到的性能測試基本沒有做對的。為什么會這樣?

第一點是性能測試方案沒有業務處理鏈和大局觀,很多都是拍腦袋得出來的。在做測試之前,參與測試的工程師是否對整個業務系統了然于胸?是否熟悉系統架構以及設計的原因?測試數據應該隨機生成,還是需要從線上系統拷貝流量回來放大重放?可能出現性能的子系統和 API 是什么?

很多時候,都是開發列出幾個 API,QA 找兩臺機器就開始隨機發包了。美其名曰快速迭代。沒有一個精心設計的測試方案,后面的都是無用功。

第二點是系統環境沒有調優。我不止一次在郵件列表里面看到工程師的提問,為什么 OpenResty 的 hello world 性能測試數據這么低?其實只需要調整幾個系統參數就可以解決。在一個 ulimit 還是 1024 的系統,不管什么語言開發的 web server,QPS 都很低。

第三點是沒有檢查系統和應用的錯誤日志。在做性能測試之前,你應該保證冒煙測試是通過的,而不是被 SELinux 攔截、連不上數據庫等磕絆,讓性能測試變成錯誤日志刷新測試。

第四點是沒有用工具打滿負載。如果 A 系統和 B 系統的 QPS 一樣,但是前者 CPU 占用 30%,后者占用 90%,那么這個結果是沒有意義的。

所以我們應該用能夠產生足夠大壓力的測試工具,比如 wrk,來保證 A 系統和 B 系統測試時都被狠狠的打滿 CPU。當然有些代碼很差勁的系統,會使用阻塞 IO,無論如何 CPU 都很空閑,那時候需要拿起 off-cpu 火焰圖分析工具照一照。

第五點是沒有 APM 或者火焰圖這樣的分析工具。測試到性能問題,然后就沒有然后了。只能丟給開發查問題,然后再測試新版本。這樣的壓力測試是沒有意義的。我們應該使用科學的分析工具, 讓數據替代猜測,很多性能點是完全猜測不出來的。

人類和動物最大的區別是,人類會創造和使用工具。

第六點是沒有業務增長的預判。現在的系統性能可以支撐多少用戶量,我們是否需要進行性能優化,甚至系統重構來應對未來的業務增長?其實做性能測試的工程師很多時候是不關心這個問題的。

上面提到的工具類和系統優化類的,這里有一個例子給大家參考: https://github.com/iresty/Mio/blob/master/benchmark.md

高大上系統的 QPS 并不高

現在參加技術會議,有一個感覺,大家產品的日訪問量都是百億起步,日志量都到了萬億,服務器集群幾千幾萬的。聽得時候心情澎湃,看看自家的產品實在是自慚形穢。

但是他們好像從來也不提這些高大上系統的單機 QPS 是多少?

讓我們算一筆帳。某個產品,?活 2000 萬,每個?戶每天 500 個請求,那么每天就是 100 億的訪問量。你也可以當做日活 5000 萬, 200 個請求,也是 100 億。其實日活幾千萬的產品并不多,那些后臺沒事亂搞的 app 不算。

每天按照十小時計算,這樣系統的 QPS 是:每天100億訪問量 / 每天10?時 / 3600秒 = 27.78 萬,就按照 30 萬算吧。那么單機 QPS 就是 30 萬除以服務器數。那么問題來了,對于日活好幾千萬的高大上系統,如果單機 QPS 達到 3 萬,只需要 10 臺機器,如果 QPS 是 3千,就需要 100 臺機器。

日志量的話,每天 100 億,堅持一年就是 3.65 萬億,只要你的儲存空間足夠。真正的問題是儲存萬億級別的日志,和存儲百億級別的日志,對于業務是否有質的改變?

很多人可能會說,我們的業務邏輯很復雜,所以 QPS 并沒有預期的那么高。其實,機器比人便宜,多買 100 臺機器,就幾百萬,用好幾年,比招幾個大牛要劃算。這算是一個很痛的領悟。

系統性能和語言性能無關

有些架構師做系統技術選型時,主要精力放在開發語言的對比和糾結上,這是一個誤區。對于高性能服務端來說,整個系統的性能瓶頸并不在語言,而在網絡和數據庫。

更重要的是,主流開發語言已經同質化。比如 JIT、協程 逐漸成為標配,雖然有些開發語言官方版本沒有接受,但第三方版本已經很成熟。連 await/async 這些關鍵字在 C#、python、ES7 里面都是一樣的,雖然有些語言的實現只是語法糖。在這個背景下,幾千的 QPS 已經不成問題,如果你有 100 臺機器,一樣可以支撐日訪問量 100 億次的系統。

更重要的是,選擇的這個開發語言,要開發、維護和替換成本低。這個如人飲水,冷暖自知,不要為了追時髦而使用某個新技術。

存在銀彈

銀彈,是三十年前提出的一個理論:在十年后不會出現讓軟件過程提高十倍的技術。現在軟件過程上面都沒有銀彈。那么在高性能服務端開發上面有沒有銀彈呢?

我覺得是有的。在揭曉這個銀彈之前,讓我們先完成 極致性能 這個小目標。對于服務端的工程師來說,幾千的 QPS 完全不能昭顯技術的優勢,對于性能的追求是沒有極限的。

我們先看下經典的服務端架構,http request 到服務端的 web server,再轉給業務邏輯,然后是緩存和數據庫。這個過程會經過多個進程,也可能跨過多個服務器和機房。那么又沒有一個技術方案, 可以把這個過程簡化到一步呢 ?就是在一臺服務器,一個進程內,處理完所有之前(web server + 業務邏輯 + cache + db)的事情呢?沒有進程的通信,沒有網絡和磁盤的IO。

這看上去是一個不可能的事情。而實際上,早在 2010 年就已經實現了。 https://github.com/ecug/con-2012/tree/master/charlespeng 這是 2012 年的一個幻燈片,我當年部門的老大做的分享。

我們 當時的系統每天有接近 100 億次用戶請求,而服務器只有 10 臺 ,分布在 2 個機房。所以我剛才提到的 QPS 計算,其實是一個真實的高性能服務端案例,是在資源有限的情況下,被倒逼實現的一個技術方案。由于高度優化,所以和業務綁定很死,沒有開源出來。但是思路是可以借鑒的。

再回到銀彈的話題,這枚銀彈除了自帶極致性能,還應該可以用 DSL 解耦開發和業務。春哥經常提到一個他在淘寶的親身經歷,在開發看來就是桃花源。就是產品同學有需求變更的時候,只用更新一個語法嚴謹的文檔,編譯器自動生成邏輯代碼。

在這個桃花源里,不用不停的更新流程圖,也不用為產品需求和技術實現不同而撕逼。工程師的重心是理解業務,設計好符合業務的 DSL,并進行針對性優化。

 

 

來自:http://mp.weixin.qq.com/s/nqxrVVV9BM-iqDyuuzfxkA

 

 本文由用戶 Ett97Z 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!