本篇文章是個經驗談,作者想要聊聊是如何將一個 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/
「dns封包」的推薦目錄:
- 關於dns封包 在 矽谷牛的耕田筆記 Facebook 的精選貼文
- 關於dns封包 在 矽谷牛的耕田筆記 Facebook 的最佳解答
- 關於dns封包 在 矽谷牛的耕田筆記 Facebook 的最佳貼文
- 關於dns封包 在 [討論] DNS Query封包連海外嚴重受阻了.. - 看板WorkinChina 的評價
- 關於dns封包 在 [討論] DNS Query封包連海外嚴重受阻了.. - 看板WorkinChina 的評價
- 關於dns封包 在 合勤榮耀資戰CTF 初賽Write-up – LJP-TW 的評價
- 關於dns封包 在 請教中華固6 ping Google DNS掉封包 - Mobile01 的評價
dns封包 在 矽谷牛的耕田筆記 Facebook 的最佳解答
關鍵字: conntrack, DNS, CoreDNS-autoscaler
影響: 部分正式生產環境崩壞
整個問題是簡單來說就是正式叢集再不預期的情況下,發生了 DNS 的問題,導致內部服務大概有 15000 筆 query 失敗。造成錯誤的原因是因為 kube-proxy 沒有順利地去移除過期的 conntrack,導致有些 DNS封包被導向到一個已經不存在的Pod。
這個問題的發生前提是,因為某些情境的發生,譬如系統負載過低, CoreDNS-autoscaler 就被觸發起來,將運行的 Pod 數量從三個降為兩個。所以系統上能夠處理 DNS 的Pod剩下兩個,但是如果有節點上的 conntrack 沒有順利清理乾淨,導致所有的封包都被導向那個被刪除的 CoreDNS,問題就這樣發生了。
詳細的過程跟一些學習重點可以參考原文
註:想要掌握 kubernetes 網路,對於 conntrack 的認識絕對不可以少,有太多太多的問題都跟 conntrack 有關,從 race condition, max 等眾多選項都牽扯所有運行的封包。有時間的話一定要好好的複習一下 conntrack 的概念
https://medium.com/preply-engineering/dns-postmortem-e169efd45afd
dns封包 在 矽谷牛的耕田筆記 Facebook 的最佳貼文
Kuberentes 支援的運算資源種類繁多,諸如 Pod, Job, ReplicaSet, DaemonSet, Deployment 以及 StatefulSet.
其中 StatefulSet 則是特別針對 stateful 應用程式所設計的,實際使用上會有些許小地方與 Deployment 用法不同,譬如
1. Storage 使用的是 Template 的概念,希望每個 StatefulSet Pod 可以綁定固定的 PV
2. 名稱採取流水號設計,相對於 Deployment -> ReplicaSet -> Pod 兩層亂數來說, StatefulSet 的名稱更加顯眼
3. StatefulSet 的 Pod 有網路存取唯一性,搭配 Headless Service,就可以使用固定一組的 DNS 名稱來存取固定 Pod(預設情況下,Pod 重啟 IP 就會不同,要做到固定一致需要不少修改)
今天這篇文章算是一個入門教學文,主要是跟大家探討什麼是 StatefulSet,以及於 Kubernetes 內該如何使用,使用上有什麼要注意的,以下幫大家節錄部分資訊
1. StatefulSet 的設計是安全優先,所以預設情況下刪除 StatefulSet 不會連帶刪除使用的 Volume
2. 使用 StatefulSet 的時候,要記得處理當 Pod 被停止,被刪除時,相關資料的寫入與同步
3. 預設情況下, StatefulSet 的創建與移除都是一個一個來,創建時由 0-N-1, 移除則反過來。
4. 對於多節點的 StatefulSet 來說,這些應用程式可能都會需要一些初始化的操作,甚至 leader-election 等相關算法。這意味者 Container(s) Running 不等於 Pod 以及準備好了。
5. 針對上述概念,使用者一定要仔細的去設定 liveness 以及 readiness,來確保
6. PostStart/PreStop 的用法與時機也要考慮進去,特別是 PreStop 用得好還可以減少使用端封包無故重送
7. 研究 disruption budgets 的用法,來確保你的 StatefulSet 運行得更安心
8. 針對特定的儲存空間使用權限問題,可以考慮使用 fsGroup 來修改,而不用自己寫一堆 shellScript 來做。當然要注意儲存空間檔案過多內容過大的情況,預設的 fsGroup 行為可以會導致你的 Pod 花太多時間來啟動
原文: https://itnext.io/stateful-applications-in-kubernetes-808a60bc109
想學習更多關於 Kubernetes 的實戰經驗與基礎設計,可參閱我的線上課程: https://technologynoteniu.github.io/awesome-notes/linux/network/
dns封包 在 [討論] DNS Query封包連海外嚴重受阻了.. - 看板WorkinChina 的推薦與評價
但若用nslookup 發出DNS Query封包,則會受到80%~90%的timeout訊息,只有1/5左右的機會能收到DNS回復的IP解析訊息,所以我猜測是金盾開始不僅針對IP或FQDN封鎖,現在還 ... ... <看更多>
dns封包 在 合勤榮耀資戰CTF 初賽Write-up – LJP-TW 的推薦與評價
請分析題目所給網路封包檔案,判斷攻擊者使用了什麼攻擊手法範例:CVE-2020-0606 答案格式:flag{CVE-XXXX-XXXX}. 裡面看起來比較可疑的是某幾個DNS ... ... <看更多>
dns封包 在 [討論] DNS Query封包連海外嚴重受阻了.. - 看板WorkinChina 的推薦與評價
目前使用家用寬頻ISP:杭州電信
相信大家都很清楚,國內的DNS汙染很嚴重,所以才會有前陣子的PTT上不了。
所以前兩週筆者都把家用的Wifi AP內部設定的DNS改成168.95.1.1和168.95.192.1
但本週發現網路常常上不去,於是用nslookup -168.95.1.1和-168.95.192.1測試
發現ping是通的沒問題,延遲也在30~50ms而已,且不會掉封包。但若用nslookup
發出DNS Query封包,則會受到80%~90%的timeout訊息,只有1/5左右的機會能收到
DNS回復的IP解析訊息,所以我猜測是金盾開始不僅針對IP或FQDN封鎖,現在還會針
對連出到海外DNS Server的DNS Query封包進行干擾和攔截。
目前敝人測出的解決方案是(不使用VPN):自己用Win 2008或其他Server side OS架設
DNS Server,且Forwarder設置成台灣的DNS,若Forwarder連不到,DNS Server自己去
問Root再一層層問到的IP解析是不會受汙染的,敝人所在公司的DNS Server就是這樣
設定,目前為止還不會受到國內DNS汙染,僅供大家參考。
--
When you're able to give your love, love will come to you very soon.
When you only wait for love, love will stay away from you.
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 153.126.173.60
※ 文章網址: https://www.ptt.cc/bbs/WorkinChina/M.1462677466.A.F25.html
... <看更多>