
千萬級并發實現的秘密:內核不是解決方案,而是問題所在!
既然我們已經解決了 C10K并發連接問題,應該如何提高水平支持千萬級并發連接?你可能會說不可能。不,現在系統已經在用你可能不熟悉甚至激進的方式支持千萬級別的并發連接。
要知道它是如何做到的,我們首先要了解Errata Security的CEO Errata Security,以及他在Shmoocon 2013大會上的無稽之談 C10M Defending The Internet At Scale。
Robert用一種我以前從未聽說的方式來很巧妙地解釋了這個問題。他首先介紹了一點有關Unix的歷史,Unix的設計初衷并不是一般的服務器操作系統,而是電話網絡的控制系統。由于是實際傳送數據的電話網絡,所以在控制層和數據層之間有明確的界限。問題是我們現在根本不應該使用Unix服務器作為數據層的一部分。正如設計只運行一個應用程序的服務器內核,肯定和設計多用戶的服務器內核是不同的。
也就是他所說的關鍵要理解內核不是解決辦法,內核是問題所在。
這意味著:
不要讓內核執行所有繁重的任務。將數據包處理,內存管理,處理器調度等任務從內核轉移到應用程序高效地完成。讓Linux只處理控制層,數據層完全交給應用程序來處理。
最終就是要設計這樣一個系統,該系統可以處理千萬級別的并發連接,它在200個時鐘周期內處理數據包,在14萬個時鐘周期內處理應用程序邏輯。由于一次主存儲器訪問就要花費300個時鐘周期,所以這是最大限度的減少代碼和緩存丟失的關鍵。
面向數據層的系統可以每秒處理1千萬個數據包,面向控制層的系統,每秒只能處理1百萬個數據包。
這似乎很極端,請記住一句老話:可擴展性是專業化的。為了做好一些事情,你不能把性能問題外包給操作系統來解決,你必須自己做。
現在,讓我們學習Robert如何創建一個能夠處理千萬級別并發連接的系統。
C10K問題最近十年
十年前,工程師處理C10K可擴展性問題時,盡量避免服務器處理超過1萬個的并發連接。通過改進操作系統內核以及用事件驅動服務器(如Nginx和Node)代替線程服務器(Apache),這個問題已經被解決。人們用十年的時間從Apache轉移到可擴展服務器,在近幾年,可擴展服務器的采用率增長得更快了。
Apache的問題
Apache的問題在于服務器的性能會隨著連接數的增多而變差
關鍵點:性能和可擴展性并不是一回事。當人們談論規模時,他們往往是在談論性能,但是規模和性能是不同的,比如Apache。
持續幾秒的短期連接,比如快速事務,如果每秒處理1000個事務,只有約1000個并發連接到服務器。
事務延長到10秒,要維持每秒1000個事務,必須打開1萬個并發連接。這種情況下:盡管你不顧DoS攻擊,Apache也會性能陡降;同時大量的下載操作也會使Apache崩潰。
如果每秒處理的連接從5千增加到1萬,你會怎么做?比方說,你升級硬件并且提高處理器速度到原來的2倍。發生了什么?你得到兩倍的性能,但你沒有得到兩倍的處理規模。每秒處理的連接可能只達到了6000。你繼續提高速度,情況也沒有改善。甚至16倍的性能時,仍然不能處理1萬個并發連接。所以說性能和可擴展性是不一樣的。
問題在于Apache會創建一個CGI進程,然后關閉,這個步驟并沒有擴展。
為什么呢?內核使用的O(N^2)算法使服務器無法處理1萬個并發連接。
內核中的兩個基本問題:
連接數=線程數/進程數。當一個數據包進來,內核會遍歷其所有進程以決定由哪個進程來處理這個數據包。
連接數=選擇數/輪詢次數(單線程)。同樣的可擴展性問題,每個包都要走一遭列表上所有的socket。
解決方法:改進內核使其在常數時間內查找。
使線程切換時間與線程數量無關。
使用一個新的可擴展epoll()/IOCompletionPort常數時間去做socket查詢。
因為線程調度并沒有得到擴展,所以服務器大規模對socket使用epoll方法,這樣就導致需要使用異步編程模式,而這些編程模式正是Nginx和Node類型服務器具有的;所以當從Apache遷移到Nginx和Node類型服務器時,即使在一個配置較低的服務器上增加連接數,性能也不會突降;所以在10K連接時,一臺筆記本電腦的速度甚至超過了16核的服務器。
C10M問題未來十年
不遠的將來,服務器將要處理數百萬的并發連接。IPv6協議下,每個服務器的潛在連接數都是數以百萬級的,所以處理規模需要升級。
如IDS / IPS這類應用程序需要支持這種規模,因為它們連接到一個服務器骨干網。其他例子:DNS根服務器,TOR節點,互聯網Nmap,視頻流,銀行,Carrier NAT,VoIP PBX,負載均衡器,網頁緩存,防火墻,電子郵件接收,垃圾郵件過濾。
通常人們將互聯網規模問題歸根于應用程序而不是服務器,因為他們賣的是硬件+軟件。你買設備,并將其應用到你的數據中心。這些設備可能包含一塊Intel主板或網絡處理器以及用來加密和檢測數據包的專用芯片等。
截至2013年2月,40Gpbs,32芯,256G RAM 的X86處理器在Newegg網站上的報價是5000美元。該服務器可以處理1萬個以上的并發連接,如果它們不能,那是因為你選擇了錯誤的軟件,而不是底層硬件的問題。這個硬件可以很容易地擴展到1千萬個并發連接。
10M的并發連接挑戰意味著什么:
我們所學的是Unix而不是網絡編程
很多程序員通過W. Richard Stevens所著的《Unix網絡編程》學習網絡編程技術。問題是,這本書是關于Unix的,而不只是網絡編程。它告訴你,讓Unix做所有繁重的工作,你只需要在Unix的上層寫一個小服務器。但內核規模不夠,解決的辦法是盡可能將業務移動到內核之外,并且自己處理所有繁重的業務。
這方面有影響的一個例子是Apache每個連接線程的模型。這意味著線程調度程序根據將要到來的數據確定接下來調用哪一個read()函數,也就是把線程調度系統當作數據包調度系統來用。(我真的很喜歡這一點,從來沒有想過這樣的說法)。
Nginx宣稱,它不把線程調度當作數據包調度程序,而是自己進行數據包調度。使用select找到socket,我們知道數據來了,就可以立即讀取并處理數據,數據也不會堵塞。
經驗:讓Unix處理網絡堆棧,但之后的業務由你來處理。
怎樣編寫規模較大的軟件?
如何改變你的軟件,使其規?;??許多只提升硬件性能去支撐項目擴展的經驗都是錯誤的,我們需要知道性能的實際情況。
要達到到更高的水平,需要解決的問題如下:
實現數據包可擴展編寫自己的個性化驅動來繞過堆棧
數據包的問題是它們需經Unix內核的處理。網絡堆棧復雜緩慢,數據包最好直接到達應用程序,而非經過操作系統處理之后。
做到這一點的方法是編寫自己的驅動程序。所有驅動程序將數據包直接發送到應用程序,而不是通過堆棧。你可以找到這種驅動程序:PF_RING,NETMAP,Intel DPDK(數據層開發套件)。Intel不是開源的,但有很多相關的技術支持。
速度有多快?Intel的基準是在一個相當輕量級的服務器上,每秒處理8000萬個數據包(每個數據包200個時鐘周期)。這也是通過用戶模式。將數據包向上傳遞,使用用戶模式,處理完畢后再返回。Linux每秒處理的數據包個數不超過百萬個,將UDP數據包提高到用戶模式,再次出去??蛻趄寗映绦蚝?a href='/map/linux/' style='color:#000;font-size:inherit;'>Linux的性能比是80:1。
對于每秒1000萬個數據包的目標,如果200個時鐘周期被用來獲取數據包,將留下1400個時鐘周期實現類似DNS / IDS的功能。
通過PF_RING得到的是原始數據包,所以你必須做你的TCP堆棧。人們所做的是用戶模式棧。Intel有現成的可擴展TCP堆棧
多核的可擴展性
多核可擴展性不同于多線程可擴展性。我們都熟知這個理念:處理器的速度并沒有變快,我們只是靠增加數量來達到目的。
大多數的代碼都未實現4核以上的并行。當我們添加更多內核時,下降的不僅僅是性能等級,處理速度可能也會變得越來越慢,這是軟件的問題。我們希望軟件的提高速度同內核的增加接近線性正相關。
多線程編程不同于多核編程
多線程
每個CPU內核中不止一個線程
用鎖來協調線程(通過系統調用)
每個線程有不同的任務
多核
每個CPU內核中只有一個線程
當兩個線程/內核訪問同一個數據時,不能停下來互相等待
同一個任務的不同線程
要解決的問題是怎樣將一個應用程序分布到多個內核中去
Unix中的鎖在內核實現。4內核使用鎖的情況是大多數軟件開始等待其他線程解鎖。因此,增加內核所獲得的收益遠遠低于等待中的性能損耗。
我們需要這樣一個架構,它更像高速公路而不是紅綠燈控制的十字路口,無需等待,每個人都以自己的節奏行進,盡可能節省開銷。
解決方案:
在每個核心中保存數據結構,然后聚合的對數據進行讀取。
原子性。CPU支持可以通過C語言調用的指令,保證原子性,避免沖突發生。開銷很大,所以不要處處使用。
無鎖的數據結構。線程無需等待即可訪問,在不同的架構下都是復雜的工作,請不要自己做。
線程模型,即流水線與工作線程模型。這不只是同步的問題,而是你的線程如何架構。
處理器關聯。告訴操作系統優先使用前兩個內核,然后設置線程運行在哪一個內核上,你也可以通過中斷到達這個目的。所以,CPU由你來控制而不是Linux。
內存的可擴展性
如果你有20G的RAM,假設每次連接占用2K的內存,如果你還有20M的三級緩存,緩存中會沒有數據。數據轉移到主存中處理花費300個時鐘周期,此時CPU沒有做任何事情。
每個數據包要有1400個時鐘周期(DNS / IDS的功能)和200個時鐘周期(獲取數據包)的開銷,每個數據包我們只有4個高速緩存缺失,這是一個問題。
聯合定位數據
不要通過指針在滿內存亂放數據。每次你跟蹤一個指針,都會是一個高速緩存缺失:[hash pointer] -> [Task Control Block] -> [Socket] -> [App],這是四個高速緩存缺失。
保持所有的數據在一個內存塊:[TCB |socket| APP]。給所有塊預分配內存,將高速緩存缺失從4減少到1。
分頁
32GB的數據需占用64MB的分頁表,不適合都存儲在高速緩存。所以存在兩個高速緩存缺失分頁表和它所指向的數據。這是開發可擴展的軟件不能忽略的細節。
解決方案:壓縮數據,使用有很多內存訪問的高速緩存架構,而不是二叉搜索樹
NUMA架構加倍了主存訪問時間。內存可能不在本地socket,而是另一個socket上。
內存池
啟動時立即預先分配所有的內存
在對象,線程和socket的基礎上進行分配。
超線程
每個網絡處理器最多可以運行4個線程,英特爾只能運行2個。
在適當的情況下,我們還需要掩蓋延時,比如內存訪問中一個線程在等待另一個全速的線程。
大內存頁
減小頁表規模。從一開始就預留內存,讓你的應用程序管理內存。
總結
網卡
問題:通過內核工作效率不高
解決方案:使用自己的驅動程序并管理它們,使適配器遠離操作系統。
CPU
問題:使用傳統的內核方法來協調你的應用程序是行不通的。
解決方案:Linux管理前兩個CPU,你的應用程序管理其余的CPU。中斷只發生在你允許的CPU上。
內存
問題:內存需要特別關注,以求高效。
解決方案:在系統啟動時就分配大部分內存給你管理的大內存頁
控制層交給Linux,應用程序管理數據。應用程序與內核之間沒有交互,沒有線程調度,沒有系統調用,沒有中斷,什么都沒有。
然而,你有的是在Linux上運行的代碼,你可以正常調試,這不是某種怪異的硬件系統,需要特定的工程師。你需要定制的硬件在數據層提升性能,但是必須是在你熟悉的編程和開發環境上進行。
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-25