本篇文章是個經驗談,作者想要聊聊是如何將一個 4vCPU 的VM給調整到可以達到每秒處理 1.2M(120萬)個 JSON Reuqest,本篇文章非常的長,所以會分多天來介紹。
整篇文章探討的是各種 turning 的步驟,來聊聊如何從最初每秒 224k(22萬四千) 給調整到每秒 1.2M 的處理能力。
整個過程分成九大步驟,後面同時標示每個過程後的每秒請求能力
1. Application Optimizations (347k)
2. Speculative Execution Migtigations (446k)
3. Syscall Auditing/Blocking (495k)
4. Disabling iptables/netfilter (603k)
5. Perfect Locality (834k)
6. Interrypt Optimizations (1.06M)
7. The Case of the Nosy Neighbor (1.12M)
8. The Battle Against the Spin Lock (1.15M)
9. This Gost to Twelv (1.20M)
作者強調,上述的過程不一定適合你的應用程式,但是透過這些步驟能夠讓你更佳瞭解應用程式的運作行為,同時也有機會發現一些潛在的瓶頸問題。
環境介紹
1. 團隊使用 Techempower 來進行 JSON Serialization 的測試
2. 使用 libreactor(event-driven框架) 來搭建一個簡單的 API Server
3. HTTP 的解析使用 picohttpparser,同時使用 libclo 來處理 JSON 的編碼
4. 硬體環境
- Server: 4 vCPU, c5n.xlarge AWS VM
- Client: 16 vCPU, c5n.4xlarge AWS VM (clinet太弱會變成瓶頸)
- Network: Server/Client 屬於同一個可用區域(AZ)
5. 軟體環境
- 作業系統: Amazon Linux2 (Kernel 4.14)
- Server: 使用 libreactor (使用不同版本,分別是 Round18 以及 Round20)
- Client: 修改 wrk 這個知名的工具並重新命名為 twrk,詳細差異自己看文章內部,主要都跟顯示有關
6. 實驗方式
- 每個測試跑三次,取中間值
- 256 連線,16 threads,同時每個 thread 都會 pin 到一個固定的 CPU
- 每個實驗都有兩秒的暖機時間來建立連線
Ground Zero
第一個要探討的就是什麼最佳化都還沒有使用前,到底當前應用程式可能的瓶頸在哪裏
首先團隊將該應用程式與其他常見的應用程式或是開發框架比較,譬如 Netty, Nginx, Actix, aspcore 等, libreactor 的效能不錯,有中上水準。
接者作者使用火焰圖(Flame Graphs)來 Profile 該伺服器,作者很好心地將文章中所有的火焰圖都調整了一下,讓所有的 user-space 相關的 function call 都轉成藍色,而剩下跟 kernel 相關都維持紅色。
1. 大部分的時間都在 Kernel 處理
2. 主要是花費在收封包與送封包
3. 應用程式本身主要是分兩大部分,解析 HTTP 的封包以及處理請求與回應。
從上述兩點來看,作者認為目前的應用程式寫得算不錯,因為瓶頸很明顯是卡在 Kernel 端
接下來就正式進入到各種 Turning 的章節探討
Application Optimizations
長話短說:
- 作者基於 libreactor Round18 的框架進行修改,並且所有的修改都已經被合併到 Round20 的版本中,而這些修改主要是實作方面的強化以及整個框架的最佳化。
1. 作者首先透過 htop 觀察運行過程,發現 Server 只有使用 2vCPU 而已(系統有 4vCPU),因此這是作者進行的第一個修改,讓 Server 使用了 4vCPU,這個簡單調整就讓效能提升 25%
註: 作者特別強調,不要覺得從 2vCPU 變成 4vCPU 效能就可以變成兩倍,主要是1) 沒有使用的 vCPU 還有很多其他的工作要處理,因此不是完全都送給你應用程式處理。2)基於 hypter-thread vCPU 的架構,環境只有兩個真正的 CPU 而是透過邏輯的方式產生四個抽象的 CPU,所以全用一定會變快,但是基於很多資源還是要競爭與共用,數字不是單純翻倍
2. 作者自己的應用程式本身使用 gcc 建置時有使用 "-o3" 的方式來最佳化處理,然而框架本身卻沒有使用 "-o3" 的方式來弄,因此作者也針對這個部分來處理,讓建制框架時能夠使用 -o3
3. 從實作方面來看,作者觀察到 libreactor 1.0 版本使用的是 read/write 這兩個常見的方式來處理封包的送收,作者將其修改成 recv/send 整個效能就提升了將近 10%。
註: write(針對 FD,更全面廣泛的用法) 與 send(針對 Socket,更針對的用法) 使用上差異不大,但是 write 於底層 Kernel 最終還是會呼叫到 send 來處理,所以基本上可以理解就是在沒有特別參數需求時,可以直接跳過幾個 kernel function 來達到加速的效果。
write kernel 內的走向: sys_write -> vfs_write -> __vfs_write -> sock_write_iter -> sock_sendmsg
send kernel 內的走向: sendto -> sock_sendmsg
4. 作者觀察到火焰圖中有一些 pthread 相關的資料,進而發現 libreactor 會創造一個 thread pool 來處理非同步的 DNS 名稱解析問題。對於一個 HTTP Client 來說,如果今天要發送請求到多個不同的 domain,而每個 domain 都會需要進行一個 blocking 的解析過程,透過這種方式可以減少 DNS 解析造成的 blocking 問題。然而對於 HTTP Server 來說,這個使用情境帶來的效益似乎就稍微低了些,畢竟 Server 只有 Bind Socket 之前可能會需要去解析一次 DNS 而已。
大部分的情境下, thread pool 都是應用程式初期會去創造而接者就不太會管她,但是對於錙銖必較的效能除錯人來說,任何能夠調整的部分都可能是個值得探討的地方。
作者透過修改 Server 端(準確來說是 libreactor 框架內的程式碼)關於 Thread Pool 的一些用法,成長的讓整個效能提升了 2~3%
結論來說,透過上述四個概念來提升的程式碼效能。
1. vCPU 盡量使用: 25%-27%
2. 使用 gcc -O3 來建置框架的程式碼: 5%-10%
3. 使用 march=native 等參數來建置最後的 server 應用程式: 5%-10%
4. 使用 send/recv 而非 write/read: 5%-10%
5. 修改 pthread 的用法: 2%-3%
註: 作者強調每個最佳化的結果並非是單純累積的概念,反而還會有互補的效果。
可能前述的操作實際上也會讓後續的操作達到更好的效果,
譬如如果先跑 vCPU 的調整,效能大概提升 25%,但是如果先執行別的最佳化過程,最後再來調整 vCPU,就可以達到 40% 的效果,主要是 CPU 可以共有效率的去執行程式。
最後,這個部分讓整個處理封包能力從 224k 提升了 55% 到 347k (req/s)。
從火焰圖來看,整個 user-space 的範圍縮小許多,同時 send/recv 的處理也有使得整體的高度下降一點點(大概四格..)
為了避免文章過長,本篇文章就探討第一個最佳化的過程,剩下的就敬請期待後續!
https://talawah.io/blog/extreme-http-performance-tuning-one-point-two-million/
同時也有1部Youtube影片,追蹤數超過11萬的網紅Bmon's Live,也在其Youtube影片中提到,DS1821+:http://sy.to/j5yhf Discord 伺服器連結:https://discord.gg/S7gURc7P4W 是ㄉ 今天偷偷用NAS架設了一台Minecraft Server(´・ω・`) 有興趣一起玩的可以進Discord和我們交流交流啦!! 得獎名單(請點連結...
nginx是什麼 在 矽谷牛的耕田筆記 Facebook 的最佳解答
今天這篇文章也是一個入門介紹文,雖說是一個入門介紹文,但是我覺得期主題滿好的,主要是針對 Ingress 這個架構來探討。我個人認為 Kubernetes 的架構加上 Yaml 安裝一切的結果很容易導致大家其實不知道 Kubernetes 做了什麼,也不知道架構到底是什麼,總之 Yaml 寫寫功能就通了。因此如果本來對於 Ingress 背後含義與架構的讀者是可以參考這篇文章重新複習一下對於 Ingress/Ingress Controller 的差異與概念。
Ingress: 其實從抽象層面來看, Ingress 就如同過往使用的 reverse proxy 一樣,根據不同的方式來轉發不同的請求封包到不同的後端服務。然而這個抽象概念於 Kubernetes 被拆分為二,分別為資訊定義端以及真正實作端。
舉例來說,假如我們採用 Nginx 作為 Ingress 的解決方案
資訊定義端(Ingress Yaml Definition): Ingress 的物件描述,也就是大家最常看到的 Ingress Yaml 資源格式,這個格式是由 kubernetes 所定義,本身沒有任何實作功能,完全是一群規則的描述。
真正實作端(Ingress Controller): 負責將 Ingress 物件轉換成 Nginx.conf,並且動態的告知 Nginx 伺服器去載入最新的設定檔案
這也是我們為什麼都要先安裝一個 deployment之類的服務到 k8s 之中,該 deployment 會扮演 Ingress Controller 的角色
接者我們根據需求部署各種 Ingress 規則到系統中,然後先前部署的 Ingress Controller 就會去抓取這些資源,並且轉換成真正可行的 nginx.conf 這種資源
本文使用的是 Kong 這套解決方案,但是整體運作邏輯跟上述提到用 Nginx 的邏輯一樣,因為這邊遵循的都是 k8s Ingress 的運作模式,因此只要搞懂其背後邏輯,未來學習任何一套解決方案的時候,都會有相同的脈絡跟模式可以參考,比較不會瞎子摸象的感覺
原文: https://medium.com/swlh/kubernetes-ingress-simplified-e0b9dc32f9fd
nginx是什麼 在 Kewang 的資訊進化論 Facebook 的最讚貼文
這一系列文總共有三篇,這是第二篇。
上一篇解決了 social network 抓取 head tag 裡面的 title, og data 等問題,但其實還有 search engine 要解決,因為 social network 只看 head,但 search engine 除了 head 以外也會看 body,所以這篇要來解決 body 一模一樣的問題。
傳統的 web 開發方式通常是一條龍開發 (你就是那條龍!),後端取得資料庫的內容,然後組成 HTML 之後丟到瀏覽器上顯示。現代的 web 開發方式通常就是一個前端配一個後端,後端專注於把資料送給前端,前端專注於取得資料後在瀏覽器上面顯示漂漂亮亮的。而傳統方式稱為 server side rendering (SSR),現代方式就稱為 client side rendering (CSR)。兩者開發方式各有優缺,蠻多文章有提過,這裡也就不另外說明了。
比較簡單判斷 CSR/SSR 的方式可以直接在你想知道的網頁,按下 Ctrl+u (Windows, Linux) 打開原始碼,看看實際上顯示的內容跟原始碼是不是差異過大。如果網頁內容很豐富,但原始碼才十幾二十行而已,那可以很粗略的說這是 CSR,如果基本上一致那就可以說是 SSR。
而 search engine 就是靠著原始碼把網頁內容做索引,所以如果谷歌大神到 CSR 的網站爬網頁內容,最後爬到的 body 當然都是同一份內容,這樣子對於 SEO 上是不合格的,所以這裡就要分享一下 Funliday-旅遊規劃 是如何處理這塊的。
第一種方式,可以用 VAR 這三套前端框架各自支援的 SSR 方案來處理,像是 Nuxt.js, Next.js, Angular Universal,這些內容已經有許多前輩分享,這裡就不另外說明了。但要注意一點,就是導入這類的解決方案通常會影響到原本的開發模式,像是 webpack 跟 bootstrapping 的方式就一定會動到,小編是建議對框架真的很熟悉之後,再來用這方式會比較好。
第二種方式,就是這次的重頭戲 prerender 了。prerender 也不是什麼魔法,就是一句話「讓爬蟲看到它應該要看的內容」。如圖所示,當 Nginx 收到 request 之後,發現 user agent 是 googlebot 就轉送到 prerender service,如果是一般 request 就直接丟到後面原本的 web server。
而 prerender service 接到 request 之後,就執行 headless chrome (用程式控制沒介面的 Google Chrome),把原本的網頁用 CSR 處理完之後,再把 HTML 的完整資料傳回給 googlebot,這樣子就達到「讓爬蟲看到它應該要看的內容」的功能了。原本的程式完全不用改,只要在 Nginx 做處理就可以了,也是負擔相對較小的方式。
另外,用了 prerender 之後,原本第一篇為了 title, og data 所做的調整也可以拿掉了。因為 CSR 本來就可以改 title, og data,所以避免重複做一樣的事,app.get("*") 這個 route 裡面關於 metadata 的功能也可以直接刪掉了。
那為什麼還會有第三篇?因為 Funliday 實際在應用 prerender.io 似乎有些問題,所以我們就改成自己寫 prerender 了,原因下回說明。
* Prerender.io:https://prerender.io
#prerender #funliday
nginx是什麼 在 Bmon's Live Youtube 的最佳解答
DS1821+:http://sy.to/j5yhf
Discord 伺服器連結:https://discord.gg/S7gURc7P4W
是ㄉ 今天偷偷用NAS架設了一台Minecraft Server(´・ω・`)
有興趣一起玩的可以進Discord和我們交流交流啦!!
得獎名單(請點連結進入觀看):https://media.discordapp.net/attachments/679581500475179044/825756924216606751/unknown.png
———抽獎方式———
公主今天特別幫大家和廠商爭取了一台DS120j
他是一台低功耗的1Bay NAS,並且同樣支援影片中所提到的各種各種套件功能,對於有存儲需求的朋友來說,可說是再適合不過了呢。
很謝謝大家願意等我們這麼久(´◓Д◔`)
上次的活動抽獎結果已經在影片中公布囉(ゝ∀・)
▫截止時間:2021/03/27 上午11:00
▫抽獎名單公布:2021/03/28 下午8:00
▫本次活動獎品:Synology DS120j
▫參加方式:
(1)喜歡這部影片
(2)將這部影片發表到你的Discord伺服器或Facebook後設定成公開,並且截圖保存以利後續確認(´◓Д◔`)
(3)在底下留言這部影片中,你最喜歡的NAS特殊玩法或是你自己想到的用法(ゝ∀・),並加上「我要抽DS120j」即可完成抽獎。
▫「B夢實況」 保有變更、修改、解釋活動規則的權利,參加此活動時即視為同意我們變更、修改及解釋活動規則之權利。
———一些酷酷的連結———
▫公主IG:https://www.instagram.com/dorabmontw
▫FB觀眾場社團:https://www.facebook.com/groups/BmonTeamFight
▫FB粉絲團網址:https://www.facebook.com/DorabmonVideo
▫合作信箱:sam3u7858@gmail.com
▫小宗宗的教學:https://www.soujirou.info/blog/39893
▫nginx rtmp server on Github:https://github.com/illuspas/nginx-rtmp-win32
0:00 開頭
1:05 NAS是什麼?
2:20 用NAS架Minecraft Server
4:52 架設虛擬機開Minecraft Server
6:36 其他酷酷的功能
7:17 Steam Server
9:03 Discord機器人
10:42 http-server
11:28 來用NAS來架設一台RTMP直播系統
12:58 總結
13:30 抽獎公布
#Synology #NAS #steamserver #rtmpserver
———Music used———
Jelly Stone
Brain Trust
Electrician - Jeremy Black
Electric Heritage
Ella Vater - The Mini Vandals
nginx是什麼 在 NGINX 安裝與設定- Web server 反向代理與負載平衡- YouTube 的必吃
2020 Getting started with pfsense 2.4 Tutorial: Network Setup, VLANs, Features & Packages · 1 2 什么是 Nginx ?常用的Web服务器有哪些?(第6周). ... <看更多>
nginx是什麼 在 紀老師程式教學網- NginX! 最猛的HTTP 伺服器換人做做看 ... 的必吃
在NETCRAFT 2012年8月WEB Server 調查中,使用Nginx 當服務器或是代理服務器就佔全世界的11.48%。隨著Nginx 在很多大型網站的廣泛使用,其穩定、高效的特性逐漸被越來越多 ... ... <看更多>