.NET技術+25台服務器怎樣支撐世界第54大(dà)網站
英文原文:StackOverflow Update: 560M Pageviews A Month, 25 Servers, And It's All About Performance
StackOverflow 是(shì)一(yī / yì /yí)個(gè) IT 技術問答網站,用戶可以(yǐ)在(zài)網站上(shàng)提交和(hé / huò)回答問題。當下的(de) StackOverflow 已擁有 400 萬個(gè)用戶,4000 萬個(gè)回答,月 PV5.6 億,世界排行第 54。然而(ér)值得關注的(de)是(shì),支撐他(tā)們網站的(de)全部服務器隻有 25 台,并且都保持着非常低的(de)資源使用率,這(zhè)是(shì)一(yī / yì /yí)場高有效性、負載均衡、緩存、數據庫、搜索及高效代碼上(shàng)的(de)較量。近日,High Scalability 創始人(rén) Todd Hoff 根據 Marco Cecconi 的(de)演講視頻“ The architecture of StackOverflow”以(yǐ)及 Nick Craver 的(de)博文“ What it takes to run Stack Overflow”總結了(le/liǎo) StackOverflow 的(de)成功原因。
意料之(zhī)中,也(yě)是(shì)意料之(zhī)外,Stack Overflow 仍然重度使用着微軟的(de)産品。他(tā)們認爲(wéi / wèi)既然微軟的(de)基礎設施可以(yǐ)滿足需求,又足夠便宜,那麽沒有什麽理由去做根本上(shàng)的(de)改變。而(ér)在(zài)需要(yào / yāo)的(de)地(dì / de)方,他(tā)們同樣使用了(le/liǎo) Linux。究其根本,一(yī / yì /yí)切都是(shì)爲(wéi / wèi)了(le/liǎo)性能。
另一(yī / yì /yí)個(gè)值得關注的(de)地(dì / de)方是(shì),Stack Overflow 仍然使用着縱向擴展策略,沒有使用雲。他(tā)們使用了(le/liǎo) 384GB 的(de)内存和(hé / huò) 2TB 的(de) SSD 來(lái)支撐 SQL Servers,如果使用 AWS 的(de)話,花費可想而(ér)知。沒有使用雲的(de)另一(yī / yì /yí)個(gè)原因是(shì) Stack Overflow 認爲(wéi / wèi)雲會一(yī / yì /yí)定程度上(shàng)的(de)降低性能,同時(shí)也(yě)會給優化和(hé / huò)排查系統問題增加難度。此外,他(tā)們的(de)架構也(yě)并不(bù)需要(yào / yāo)橫向擴展。峰值期間是(shì)橫向擴展的(de)殺手級應用場景,然而(ér)他(tā)們有着豐富的(de)系統調整經驗去應對。該公司仍然堅持着 Jeff Atwood 的(de)名言——硬件永遠比程序員便宜。
Marco Ceccon 曾提到(dào),在(zài)談及系統時(shí),有一(yī / yì /yí)件事情必須首先弄明白——需要(yào / yāo)解決問題的(de)類型。首先,從簡單方面着手,StackExchange 究竟是(shì)用來(lái)做什麽的(de)——首先是(shì)一(yī / yì /yí)些主題,然後圍繞這(zhè)些主題建立社區,最後就(jiù)形成了(le/liǎo)這(zhè)個(gè)令人(rén)敬佩的(de)問答網站。
其次則是(shì)規模相關。StackExchange 在(zài)飛速增長,需要(yào / yāo)處理大(dà)量的(de)數據傳輸,那麽這(zhè)些都是(shì)如何完成的(de),特别是(shì)隻使用了(le/liǎo) 25 台服務器,下面一(yī / yì /yí)起追根揭底:
狀态
StackExchange 擁有 110 個(gè)站點,以(yǐ)每個(gè)月 3 到(dào) 4 個(gè)的(de)速度增長。
400 萬用戶
800 萬問題
4000 萬答案
世界排名 54 位
每年增長 100%
月 PV 5.6 億萬
大(dà)多數工作日期間峰值爲(wéi / wèi) 2600 到(dào) 3000 請求每秒,作爲(wéi / wèi)一(yī / yì /yí)個(gè)編程相關網站,一(yī / yì /yí)般情況下工作日的(de)請求都會高于(yú)周末
25 台服務器
SSD 中儲存了(le/liǎo) 2TB 的(de) SQL 數據
每個(gè) web server 都配置了(le/liǎo) 2 個(gè) 320G 的(de) SSD,使用 RAID 1
每個(gè) ElasticSearch 主機都配備了(le/liǎo) 300GB 的(de)機械硬盤,同時(shí)也(yě)使用了(le/liǎo) SSD
Stack Overflow 的(de)讀寫比是(shì) 40:60
DB Server 的(de)平均 CPU 利用率是(shì) 10%
11 個(gè) web server,使用 IIS
2 個(gè)負載均衡器,1 個(gè)活躍,使用 HAProxy
4 個(gè)活躍的(de)數據庫節點,使用 MS SQL
3 台實現了(le/liǎo) tag engine 的(de)應用程序服務器,所有搜索都通過 tag
3 台服務器通過 ElasticSearch 做搜索
2 台使用了(le/liǎo) Redis 的(de)服務器支撐分布式緩存和(hé / huò)消息
2 台 Networks(Nexus 5596 + Fabric Extenders)
2 Cisco 5525-X ASAs
2 Cisco 3945 Routers
主要(yào / yāo)服務 Stack Exchange API 的(de) 2 個(gè)隻讀 SQL Servers
VM 用于(yú)部署、域控制器、監控、運維數據庫等場合
平台
ElasticSearch
Redis
HAProxy
MS SQL
Opserver
TeamCity
Jil——Fast .NET JSON Serializer,建立在(zài) Sigil 之(zhī)上(shàng)
Dapper——微型的(de) ORM
UI
UI 擁有一(yī / yì /yí)個(gè)信息收件箱,用于(yú)新徽章獲得、用戶發送信息、重大(dà)事件發生時(shí)的(de)信息收取,使用 WebSockets 實現,并通過 Redis 支撐。
搜索箱通過 ElasticSearch 實現,使用了(le/liǎo)一(yī / yì /yí)個(gè) REST 接口。
因爲(wéi / wèi)用戶提出(chū)問題的(de)頻率很高,因此很難顯示最新問題,每秒都會有新的(de)問題産生,從而(ér)這(zhè)裏需要(yào / yāo)開發一(yī / yì /yí)個(gè)關注用戶行爲(wéi / wèi)模式的(de)算法,隻給用戶顯示感興趣的(de)問題。它使用了(le/liǎo)基于(yú) Tag 的(de)複雜查詢,這(zhè)也(yě)是(shì)開發獨立 Tag Engine 的(de)原因。
服務器端模闆用于(yú)生成頁面。
服務器
25 台服務器并沒有滿載,CPU 使用率并不(bù)高,單計算 SO(Stack Overflow)隻需要(yào / yāo) 5 台服務器。
數據庫服務器資源利用率在(zài) 10% 左右,除下執行備份時(shí)。
爲(wéi / wèi)什麽會這(zhè)麽低?因爲(wéi / wèi)數據庫服務器足足擁有 384GB 内存,同時(shí) web server 的(de) CPU 利用率也(yě)隻有 10%-15%。
縱向擴展還沒有遇到(dào)瓶頸。通常情況下,如此流量使用橫向擴展大(dà)約需要(yào / yāo) 100 到(dào) 300 台服務器。
簡單的(de)系統。基于(yú) .Net,隻用了(le/liǎo) 9 個(gè)項目,其他(tā)系統可能需要(yào / yāo) 100 個(gè)。之(zhī)所以(yǐ)使用這(zhè)麽少系統是(shì)爲(wéi / wèi)了(le/liǎo)追求極限的(de)編譯速度,這(zhè)點需要(yào / yāo)從系統開始時(shí)就(jiù)進行規劃,每台服務器的(de)編譯時(shí)間大(dà)約是(shì) 10 秒。
11 萬行代碼,對比流量來(lái)說(shuō)非常少。
使用這(zhè)種極簡的(de)方式主要(yào / yāo)基于(yú)幾個(gè)原因。首先,不(bù)需要(yào / yāo)太多測試,因爲(wéi / wèi) Meta.stackoverflow 本來(lái)就(jiù)是(shì)一(yī / yì /yí)個(gè)問題和(hé / huò) bug 讨論社區。其次,Meta.stackoverflow 還是(shì)一(yī / yì /yí)個(gè)軟件的(de)測試網站,如果用戶發現問題的(de)話,往往會提出(chū)并給予解決方案。
紐約數據中心使用的(de)是(shì) Windows 2012,已經向 2012 R2 升級(Oregon 已經完成了(le/liǎo)升級),Linux 系統使用的(de)是(shì) Centos 6.4。
SSD
默認使用的(de)是(shì) Intel 330(Web 層等)
Intel 520 用于(yú)中間層寫入,比如 Elastic Search
數據層使用 Intel 710 和(hé / huò) S3700
系統同時(shí)使用了(le/liǎo) RAID 1 和(hé / huò) RAID 10(任何4+ 以(yǐ)上(shàng)的(de)磁盤都使用 RAID 10)。不(bù)畏懼故障發生,即使生産環境中使用了(le/liǎo)上(shàng)千塊 2.5 英寸 SSD,還沒碰到(dào)過一(yī / yì /yí)塊失敗的(de)情景。每個(gè)模型都使用了(le/liǎo) 1 個(gè)以(yǐ)上(shàng)的(de)備件,多個(gè)磁盤發生故障的(de)情景不(bù)在(zài)考慮之(zhī)中。
ElasticSearch 在(zài) SSD 上(shàng)表現的(de)異常出(chū)色,因爲(wéi / wèi) SO writes/re-indexes 的(de)操作非常頻繁。
SSD 改變了(le/liǎo)搜索的(de)使用方式。因爲(wéi / wèi)鎖的(de)問題,Luncene.net 并不(bù)能支撐 SO 的(de)并發負載,因此他(tā)們轉向了(le/liǎo) ElasticSearch。在(zài)全 SSD 環境下,并不(bù)需要(yào / yāo)圍繞 Binary Reader 建立鎖。
高可用性
異地(dì / de)備份——主數據中心位于(yú)紐約,備份數據中心在(zài) Oregon。
Redis 有兩個(gè)從節點,SQL 有 2 個(gè)備份,Tag Engine 有 3 個(gè)節點,elastic 有 3 個(gè)節點,冗餘一(yī / yì /yí)切,并在(zài)兩個(gè)數據中心同時(shí)存在(zài)。
Nginx 是(shì)用于(yú) SSL,終止 SSL 時(shí)轉換使用 HAProxy。
并不(bù)是(shì)主從所有,一(yī / yì /yí)些臨時(shí)的(de)數據隻會放到(dào)緩存中
所有 HTTP 流量發送隻占總流量的(de) 77%,還存在(zài) Oregon 數據中心的(de)備份及一(yī / yì /yí)些其他(tā)的(de) VPN 流量。這(zhè)些流量主要(yào / yāo)由 SQL 和(hé / huò) Redis 備份産生。
數據庫
MS SQL Server
Stack Exchange 爲(wéi / wèi)每個(gè)網站都設置了(le/liǎo)數據庫,因此 Stack Overflow 有一(yī / yì /yí)個(gè)、Server Fault 有一(yī / yì /yí)個(gè),以(yǐ)此類推。
在(zài)紐約的(de)主數據中心,每個(gè)集群通常都使用 1 主和(hé / huò) 1 隻讀備份的(de)配置,同時(shí)還會在(zài) Oregon 數據中心也(yě)設置一(yī / yì /yí)個(gè)備份。如果是(shì)運行的(de)是(shì) Oregon 集群,那麽兩個(gè)在(zài)紐約數據中心的(de)備份都會是(shì)隻讀和(hé / huò)同步的(de)。
爲(wéi / wèi)其他(tā)内容準備的(de)數據庫。這(zhè)裏還存在(zài)一(yī / yì /yí)個(gè)“網絡範圍”的(de)數據庫,用于(yú)儲存登陸憑證和(hé / huò)聚合數據(大(dà)部分是(shì) stackexchange.com 用戶文件或者 API)。
Careers Stack Overflow、stackexchange.com 和(hé / huò) Area 51 等都擁有自己獨立的(de)數據庫模式。
模式的(de)變化需要(yào / yāo)同時(shí)提供給所有站點的(de)數據庫,它們需要(yào / yāo)向下兼容,舉個(gè)例子(zǐ),如果需要(yào / yāo)重命名一(yī / yì /yí)個(gè)列,那麽将非常麻煩,這(zhè)裏需要(yào / yāo)進行多個(gè)操作:增加一(yī / yì /yí)個(gè)新列,添加作用在(zài)兩個(gè)列上(shàng)的(de)代碼,給新列寫數據,改變代碼讓新列有效,移除舊列。
并不(bù)需要(yào / yāo)分片,所有事情通過索引來(lái)解決,而(ér)且數據體積也(yě)沒那麽大(dà)。如果有 filtered indexes 需求,那麽爲(wéi / wèi)什麽不(bù)更高效的(de)進行?常見模式隻在(zài) DeletionDate = Null 上(shàng)做索引,其他(tā)則通過爲(wéi / wèi)枚舉指定類型。每項 votes 都設置了(le/liǎo) 1 個(gè)表,比如一(yī / yì /yí)張表給 post votes,1 張表給 comment votes。大(dà)部分的(de)頁面都可以(yǐ)實時(shí)渲染,隻爲(wéi / wèi)匿名用戶緩存,因此,不(bù)存在(zài)緩存更新,隻有重查詢。
Scores 是(shì)非規範化的(de),因此需要(yào / yāo)經常查詢。它隻包含 IDs 和(hé / huò) dates,post votes 表格當下大(dà)約有 56454478 行,使用索引,大(dà)部分的(de)查詢都可以(yǐ)在(zài)數毫秒内完成。
Tag Engine 是(shì)完全獨立的(de),這(zhè)就(jiù)意味着核心功能并不(bù)依賴任何外部應用程序。它是(shì)一(yī / yì /yí)個(gè)巨大(dà)的(de)内存結構數組結構,專爲(wéi / wèi) SO 用例優化,并爲(wéi / wèi)重負載組合進行預計算。Tag Engine 是(shì)個(gè)簡單的(de) windows 服務,冗餘的(de)運行在(zài)多個(gè)主機上(shàng)。CPU 使用率基本上(shàng)保持在(zài)2-5%,3 個(gè)主機專門用于(yú)冗餘,不(bù)負責任何負載。如果所有主機同時(shí)發生故障,網絡服務器将把 Tag Engine 加載到(dào)内存中持續運行。
關于(yú) Dapper 無編譯器校驗查詢與傳統 ORM 的(de)對比。使用編譯器有很多好處,但在(zài)運行時(shí)仍然會存在(zài) fundamental disconnect 問題。同時(shí)更重要(yào / yāo)的(de)是(shì),由于(yú)生成 nasty SQL,通常情況還需要(yào / yāo)去尋找原始代碼,而(ér) Query Hint 和(hé / huò) parameterization 控制等能力的(de)缺乏更讓查詢優化變得複雜。
編碼
流程
大(dà)部分程序員都是(shì)遠程工作,自己選擇編碼地(dì / de)點
編譯非常快
然後運行少量的(de)測試
一(yī / yì /yí)旦編譯成功,代碼即轉移至開發交付準備服務器
通過功能開關隐藏新功能
在(zài)相同硬件上(shàng)作爲(wéi / wèi)其他(tā)站點測試運行
然後轉移至 Meta.stackoverflow 測試,每天有上(shàng)千個(gè)程序員在(zài)使用,一(yī / yì /yí)個(gè)很好的(de)測試環境
如果通過則上(shàng)線,在(zài)更廣大(dà)的(de)社區進行測試
大(dà)量使用靜态類和(hé / huò)方法,爲(wéi / wèi)了(le/liǎo)更簡單及更好的(de)性能
編碼過程非常簡單,因爲(wéi / wèi)複雜的(de)部分被打包到(dào)庫裏,這(zhè)些庫被開源和(hé / huò)維護。.Net 項目數量很低,因爲(wéi / wèi)使用了(le/liǎo)社區共享的(de)部分代碼。
開發者同時(shí)使用 2 到(dào) 3 個(gè)顯示器,多個(gè)屏幕可以(yǐ)顯著提高生産效率。
緩存
緩存一(yī / yì /yí)切
5 個(gè)等級的(de)緩存
1 級是(shì)網絡級緩存,緩存在(zài)浏覽器、CDN 以(yǐ)及代理服務器中。
2 級由 .Net 框架 HttpRuntime.Cache 完成,在(zài)每台服務器的(de)内存中。
3 級 Redis,分布式内存鍵值存儲,在(zài)多個(gè)支撐同一(yī / yì /yí)個(gè)站點的(de)服務器上(shàng)共享緩存項。
4 級 SQL Server Cache,整個(gè)數據庫,所有數據都被放到(dào)内存中。
5 級 SSD。通常隻在(zài) SQL Server 預熱後才生效。
舉個(gè)例子(zǐ),每個(gè)幫助頁面都進行了(le/liǎo)緩存,訪問一(yī / yì /yí)個(gè)頁面的(de)代碼非常簡單:
使用了(le/liǎo)靜态的(de)方法和(hé / huò)類。從 OOP 角度來(lái)看确實很糟,但是(shì)非常快并有利于(yú)簡潔編碼。
緩存由 Redis 和(hé / huò) Dapper 支撐,一(yī / yì /yí)個(gè)微型 ORM
爲(wéi / wèi)了(le/liǎo)解決垃圾收集問題,模闆中 1 個(gè)類隻使用 1 個(gè)副本,被建立和(hé / huò)保存在(zài)緩存中。監測一(yī / yì /yí)切,包括 GC 操。據統計顯示,間接層增加 GC 壓力達到(dào)了(le/liǎo)某個(gè)程度時(shí)會顯著的(de)降低性能。
CDN Hit 。鑒于(yú)查詢字符串基于(yú)文件内容進行哈希,隻在(zài)有新建立時(shí)才會被再次取出(chū)。每天 3000 萬到(dào) 5000 萬 Hit,帶寬大(dà)約爲(wéi / wèi) 300GB 到(dào) 600GB。
CDN 不(bù)是(shì)用來(lái)應對 CPU 或I/O負載,而(ér)是(shì)幫助用戶更快的(de)獲得答案
部署
每天 5 次部署,不(bù)去建立過大(dà)的(de)應用。主要(yào / yāo)因爲(wéi / wèi)
可以(yǐ)直接的(de)監視性能
盡可能最小化建立,可以(yǐ)工作才是(shì)重點
産品建立後再通過強大(dà)的(de)腳本拷貝到(dào)各個(gè)網頁層,每個(gè)服務器的(de)步驟是(shì):
通過 POST 通知 HAProxy 下架某台服務器
延遲 IIS 結束現有請求(大(dà)約 5 秒)
停止網站(通過同一(yī / yì /yí)個(gè) PSSession 結束所有下遊)
Robocopy 文件
開啓網站
通過另一(yī / yì /yí)個(gè) POST 做 HAProxy Re-enable
幾乎所有部署都是(shì)通過 puppet 或 DSC,升級通常隻是(shì)大(dà)幅度調整 RAID 陣列并通過 PXE boot 安裝,這(zhè)樣做非常快速。
協作
團隊
SRE (System Reliability Engineering):5 人(rén)
Core Dev(Q&A site)6-7 人(rén)
Core Dev Mobile:6 人(rén)
Careers 團隊專門負責 SO Careers 産品開發:7 人(rén)
Devops 和(hé / huò)開發者結合的(de)非常緊密
團隊間變化很大(dà)
大(dà)部分員工遠程工作
辦公室主要(yào / yāo)用于(yú)銷售,Denver 和(hé / huò) London 除外
一(yī / yì /yí)切平等,些許偏向紐約工作者,因爲(wéi / wèi)面對面有助于(yú)工作交流,但是(shì)在(zài)線工作影響也(yě)并不(bù)大(dà)
對比可以(yǐ)在(zài)同一(yī / yì /yí)個(gè)辦公室辦公,他(tā)們更偏向熱愛産品及有才華的(de)工程師,他(tā)們可以(yǐ)很好的(de)衡量利弊
許多人(rén)因爲(wéi / wèi)家庭而(ér)選擇遠程工作,紐約是(shì)不(bù)錯,但是(shì)生活并不(bù)寬松
辦公室設立在(zài)曼哈頓,那是(shì)個(gè)人(rén)才的(de)誕生地(dì / de)。數據中心不(bù)能太偏,因爲(wéi / wèi)經常會涉及升級
打造一(yī / yì /yí)個(gè)強大(dà)團隊,偏愛極客。早期的(de)微軟就(jiù)聚集了(le/liǎo)大(dà)量極客,因此他(tā)們征服了(le/liǎo)整個(gè)世界
Stack Overflow 社區也(yě)是(shì)個(gè)招聘的(de)地(dì / de)點,他(tā)們在(zài)那尋找熱愛編碼、樂于(yú)助人(rén)及熱愛交流的(de)人(rén)才。
編制預算
預算是(shì)項目的(de)基礎。錢隻花在(zài)爲(wéi / wèi)新項目建立基礎設施上(shàng),如此低利用率的(de) web server 還是(shì) 3 年前數據中心建立時(shí)購入。
測試
快速叠代和(hé / huò)遺棄
許多測試都是(shì)發布隊伍完成的(de)。開發擁有一(yī / yì /yí)個(gè)同樣的(de) SQL 服務器,并且運行在(zài)相同的(de) Web 層,因此性能測試并不(bù)會糟糕。
非常少的(de)測試。Stack Overflow 并沒有進行太多的(de)單元測試,因爲(wéi / wèi)他(tā)們使用了(le/liǎo)大(dà)量的(de)靜态代碼,還有一(yī / yì /yí)個(gè)非常活躍的(de)社區。
基礎設施改變。鑒于(yú)所有東西都有雙份,所以(yǐ)每個(gè)舊配置都有備份,并使用了(le/liǎo)一(yī / yì /yí)個(gè)快速故障恢複機制。比如,keepalived 可以(yǐ)在(zài)負載均衡器中快速回退。
對比定期維護,他(tā)們更願意依賴冗餘系統。SQL 備份用一(yī / yì /yí)個(gè)專門的(de)服務器進行測試,隻爲(wéi / wèi)了(le/liǎo)可以(yǐ)重存儲。計劃做每兩個(gè)月一(yī / yì /yí)次的(de)全數據中心故障恢複,或者使用完全隻讀的(de)第二數據中心。
每次新功能發布都做單元測試、集成測試盒 UI 測試,這(zhè)就(jiù)意味着可以(yǐ)預知輸入的(de)産品功能測試後就(jiù)會推送到(dào)孵化網站,即 meta.stackexchange(原 meta.stackoverflow)。
監視/日志
當下正在(zài)考慮使用 http://logstash.net/做日志管理,目前使用了(le/liǎo)一(yī / yì /yí)個(gè)專門的(de)服務将 syslog UDP 傳輸到(dào) SQL 數據庫中。網頁中爲(wéi / wèi)計時(shí)添加 header,這(zhè)樣就(jiù)可以(yǐ)通過 HAProxy 來(lái)捕獲并且融合到(dào) syslog 傳輸中。
Opserver 和(hé / huò) Realog 用于(yú)顯示測量結果。Realog 是(shì)一(yī / yì /yí)個(gè)日志展示系統,由 Kyle Brandt 和(hé / huò) Matt Jibson 使用 Go 建立。
日志通過 HAProxy 負載均衡器借助 syslog 完成,而(ér)不(bù)是(shì) IIS,因爲(wéi / wèi)其功能比 IIS 更豐富。
關于(yú)雲
還是(shì)老生常談,硬件永遠比開發者和(hé / huò)有效率的(de)代碼便宜。基于(yú)木桶效應,速度肯定受限于(yú)某個(gè)短闆,現有的(de)雲服務基本上(shàng)都存在(zài)容量和(hé / huò)性能限制。
如果從開始就(jiù)使用雲來(lái)建設 SO 說(shuō)不(bù)定也(yě)會達到(dào)現在(zài)的(de)水準。但毫無疑問的(de)是(shì),如果達到(dào)同樣的(de)性能,使用雲的(de)成本将遠遠高于(yú)自建數據中心。
性能至上(shàng)
StackOverflow 是(shì)個(gè)重度的(de)性能控,主頁加載的(de)時(shí)間永遠控制在(zài) 50 毫秒内,當下的(de)響應時(shí)間是(shì) 28 毫秒。
程序員熱衷于(yú)降低頁面加載時(shí)間以(yǐ)及提高用戶體驗。
每個(gè)獨立的(de)網絡提交都予以(yǐ)計時(shí)和(hé / huò)記錄,這(zhè)種計量可以(yǐ)弄清楚提升性能需要(yào / yāo)修改的(de)地(dì / de)方。
如此低資源利用率的(de)主要(yào / yāo)原因就(jiù)是(shì)高效的(de)代碼。web server 的(de) CPU 平均利用率在(zài)5% 到(dào) 15% 之(zhī)間,内存使用爲(wéi / wèi) 15.5 GB,網絡傳輸在(zài) 20 Mb/s到(dào) 40 Mb/s。SQL 服務器的(de) CPU 使用率在(zài)5% 到(dào) 10% 之(zhī)間,内存使用是(shì) 365GB,網絡傳輸爲(wéi / wèi) 100 Mb/s到(dào) 200 Mb/s。這(zhè)可以(yǐ)帶來(lái) 3 個(gè)好處:給升級留下很大(dà)的(de)空間;在(zài)嚴重錯誤發生時(shí)可以(yǐ)保持服務可用;在(zài)需要(yào / yāo)時(shí)可以(yǐ)快速回檔。
學到(dào)的(de)知識
1. 爲(wéi / wèi)什麽使用 MS 産品的(de)同時(shí)還使用 Redis?什麽好用用什麽,不(bù)要(yào / yāo)做無必要(yào / yāo)的(de)系統之(zhī)争,比如 C# 在(zài) Windows 機器上(shàng)運行最好,我們使用 IIS;Redis 在(zài)*nix 機器上(shàng)可以(yǐ)得到(dào)充分發揮,我們使用*nix。
2. Overkill 即策略。平常的(de)利用率并不(bù)能代表什麽,當某些特定的(de)事情發生時(shí),比如備份、重建等完全可以(yǐ)将資源使用拉滿。
3. 堅固的(de) SSD。所有數據庫都建立在(zài) SSD 之(zhī)上(shàng),這(zhè)樣可以(yǐ)獲得 0 延時(shí)。
4. 了(le/liǎo)解你的(de)讀寫負載。
5. 高效的(de)代碼意味着更少的(de)主機。隻有新項目上(shàng)線時(shí)才會因爲(wéi / wèi)特殊需求增加硬件,通常情況下是(shì)添加内存,但在(zài)此之(zhī)外,高效的(de)代碼就(jiù)意味着 0 硬件添加。所以(yǐ)經常隻讨論兩個(gè)問題:爲(wéi / wèi)存儲增加新的(de) SSD;爲(wéi / wèi)新項目增加硬件。
6. 不(bù)要(yào / yāo)害怕定制化。SO 在(zài) Tag 上(shàng)使用複雜查詢,因此專門開發了(le/liǎo)所需的(de) Tag Engine。
7. 隻做必須做的(de)事情。之(zhī)所以(yǐ)不(bù)需要(yào / yāo)測試是(shì)因爲(wéi / wèi)有一(yī / yì /yí)個(gè)活躍的(de)社區支撐,比如,開發者不(bù)用擔心出(chū)現“Square Wheel”效應,如果開發者可以(yǐ)制作一(yī / yì /yí)個(gè)更更輕量級的(de)組件,那就(jiù)替代吧。
8. 注重硬件知識,比如 IL。一(yī / yì /yí)些代碼使用 IL 而(ér)不(bù)是(shì)C#。聚焦 SQL 查詢計劃。使用 web server 的(de)内存轉儲究竟做了(le/liǎo)些什麽。探索,比如爲(wéi / wèi)什麽一(yī / yì /yí)個(gè) split 會産生 2GB 的(de)垃圾。
9. 切勿官僚作風。總有一(yī / yì /yí)些新的(de)工具是(shì)你需要(yào / yāo)的(de),比如,一(yī / yì /yí)個(gè)編輯器,新版本的(de) Visual Studio,降低提升過程中的(de)一(yī / yì /yí)切阻力。
10. 垃圾回收驅動編程。SO 在(zài)減少垃圾回收成本上(shàng)做了(le/liǎo)很多努力,跳過類似 TDD 的(de)實踐,避免抽象層,使用靜态方法。雖然極端,但是(shì)确實打造出(chū)非常高效的(de)代碼。
11. 高效代碼的(de)價值遠遠超出(chū)你想象,它可以(yǐ)讓硬件跑的(de)更快,降低資源使用,切記讓代碼更容易被程序員理解。