前段時間趁空把《大規模web服務開發技術》這本書看完了,今天用一下午時間重新翻了一遍,把其中的要點記了下來,權當復習和備忘。由於自己對數據壓縮、全文檢索等還算比較熟,所以筆記內容主要涉及前5章內容,后面的零星記了一些。本文可能對如下人士比較有幫助:1、對這本書有興趣,但對內容存疑的;2、對大規模Web服務有一定經驗的,可對照着查漏補缺。
Hatena的規模(2010年4月)
- 注冊用戶150w,UU1900w/月
- 請求數:幾十億/月
- 繁忙時流量:850Mbps(不含圖像)
- 硬件(服務器)600台,通過虛擬化技術,主機超過1300台
- 日志每天幾GB級別,數據庫GB到TB級別
系統增長的戰略
- 最小化開端、預見變化的管理和設計
平衡效率和質量
- 開會、規范化、文檔、敏捷等
GB級別(千萬)的文本數據庫,不用索引,一句select查詢200s也未能執行完
內存和硬盤的速度差異
- 尋址:前者是后者的10w到100w倍
- 傳輸速度(總線):前者——7.5G/s,后者——58M/s
找尋單機瓶頸(用足單機的性能,不要推測,要測量)
- sar或vmstat查看是CPU問題還是IO問題
- 若是CPU問題
- top或sar查看是系統進程還是用戶程序
- ps查看進程狀態和cpu使用情況,確定問題進程
- 用strace或oprofile找出程序或進程的具體問題所在
- 若是IO問題
- 發生頻繁頁交換--->內存不足
- ps查看程序所用內存
- 能否改善程序,減少內存占用
- 不行增加硬件或分布式
- 若無,則可能是緩存的內存不夠
- 增加內存
- 不行就增加機器,分布式
CPU擴展比較方便,但IO負載的擴展比較困難
- 查看實際負載:top結果中的load average(1分鍾 5分鍾 15分鍾)
- 查看是IO負載過高還是CPU負載過高:sar -P(多核)
處理大規模技術的重點
- 盡量在內存中進行,可實現分布式,利用局部性
- 算法的復雜度,O(n) --> O(logn)有質的飛躍
- 數據壓縮和檢索技術
緩存機制
- 頁面緩存(page cache)
- 現代操作系統均采用虛擬內存
- 內核分配過的內存會盡量留下來,下次無需訪問磁盤,即頁面緩存
- 操作系統以頁為單位緩存,即虛擬內存的最小單位
- 增加內存可提高緩存的命中率,降低IO負載
- sar命令
- sar -r 即可查看當前的內存狀態(kbbuffered緩存使用的物理內存大小)
- sar 1 3 一秒1次,總共3次
- sar -u 查看CPU使用率
- sar -q 查看平均負載
- sar -r 查看內存使用情況
降低IO負載的策略
- 提高緩存,即加內存
- 擴展到多台服務器
- 2實際可能未提高緩存命中率(每台機器的數據不變),需要切分(Partition)數據
切分(Partition)——利用局部性的分布式
- 以RDBMS的表為單位
- 從數據中間切分
- a-c服務器1,d-f服務器2……
- 一致性哈希
- 按用途將系統分成不同的“島”
- 爬蟲
- 圖像API
- 一般訪問
以頁面緩存為基礎的基本運維規則
- 操作系統啟動時不要馬上投入生產環境,要先預熱,即讀一遍所有文件
- 性能測試要在緩存優化后進行
數據庫橫向擴展策略
靈活應用操作系統緩存
- 盡量讓數據庫大小小於物理內存
- 考慮表的結構設計對數據庫大小的影響
建立索引
- B+樹
- 提高搜索效率(logn),改善磁盤尋道次數
- MySQL的explain命令幫助查看索引是否有效
MySQL的分布式
- master/slave設計(master更新,slave讀)
- 查詢可以擴展(slave)
- 但master無法擴展(數據一致性)
- 但Web應用大多數情況下90%都是讀取查詢
- master的負載可通過分庫分表或更換實現方法來解決
MySQL的Partition
- 將聯系不緊密的表放在不同機器上
- 避免對不同機器上表進行JOIN操作
- 使用INNER JOIN或where...in…
- 使用自定義的ORM
- Partition的代價
- 運維變得復雜,故障率上升,成本上升
- 實現冗余化最少需要多少台機器
- 4台——1台master,3台slave
- 3台slave中,一台用於提供持續服務,一台可能會故障,最后一台用於故障后復制
Web服務的基礎設施重視的三點
- 低成本、高效率
- 不應追求100%可靠性
- 設計很重要
- 可擴展性和響應時間
- 開發速度很重要
- Web服務經常添加或更改功能,需為服務提供靈活的資源
一台服務器能處理的流量極限
- Hatena標准服務器:4核CPU,8G內存;
- 性能:繁忙時每分鍾幾千請求
- 若4核CPU*2,32G內存
- 100w~200wPV/月
調優
- 掌握負載
- 服務器監控工具
冗余性與系統穩定性
master的冗余化
- multi-master
- 通常有兩台服務器,組成Active/Standby結構
- 一台是Active的,另一台Standby
- 兩台服務器互為slave,一方的寫入數據傳入另外一方,雙向replication
- 當Standby通過VRRP協議發現Active停機,則Standby自動提升為Active,變成新的master
- Active服務器有個虛擬ip,將此ip分配給哪台機器,哪台機器就是Active的master
- 缺點
- 還是有不一致的風險
系統的穩定性
- 資源應都保留一定余量,只用到70%左右
- 去除不穩定因素(盡量自動化處理)
- 規定SQL負載上限
- 減少內存泄露,遇到可自動重啟
- 異常行為的自律控制
- 自動DOS判斷
- 自動重啟
- 自動終止耗時查詢
虛擬化技術
- 好處
- 可擴展性
- 將額外開銷降至最低
- 動態遷移
- 性價比
- 提高資源利用率
- 提高運維的靈活程度
- 軟件層面的主機控制
- 高可用性
- 環境隔離
- Hatena的虛擬化應用
- Xen(CentOS 5.2、Xen 3.0.3)+ 本地磁盤構建LVM
- 用HyperVisor替代IPMI
- 使用准虛擬化(ParaVirtualization)
- 控制資源消耗
- 負載過高時警告
- 調整負載
- 檢測工具:monit
- 提高資源利用率
- CPU空閑 --> Web服務器
- IO空閑 --> 數據庫服務器
- 內存空閑 --> 緩存服務器
- 避免消耗傾向相同的組合在一起
- 虛擬化的額外開銷
- CPU:2%~3%
- 內存性能:10%
- 網絡性能:50%
- IO性能:5%
SSD的壽命
- 損耗程度指標:S.M.A.R.T值中的E9(Media Wearout Indicator)---> smartctl命令
- Hatena寫入最頻繁的SSD用了9個月左右
網絡的分界點
- 1Gbps,即30wpps,是PC路由器的極限(1Gbps是千兆以太網的界限,30wpps是Linux內核的極限)
- 對策:多個PC路由,購買昂貴成品路由
- 500台主機,是子網、ARP表的極限
- 對策:對網絡進行層次化
RDBMS還是k-v存儲
- 判斷依據
- 平均數據大小
- 最大數據大小
- 新數據增加頻率
- 更新頻率
- 刪除頻率
- 訪問頻率
- MyISAM vs. InnoDB
- MyISAM
- 優點
- 未經update、delete的表也能快速insert
- 啟動、停止十分迅速
- 表移動、改名稱可直接從文件系統中操作
- 缺點
- 異常停止可能會損壞表
- 不支持事務
- update、delete、insert(追加數據之外)會鎖表,在更新較多的應用中性能不好
- 適合場景
- 只有數據追加
- 使用SELECT COUNT(*)
- InnoDB
- 優點
- 支持事務
- 異常停止恢復
- 數據更新時執行行鎖定
- 缺點
- 啟動、停止慢
- 表操作完全通過數據庫
- 適合場景
- 更新頻率高
- 需要事務
- 分布式k-v
- memcached
- TokyoTyrant
緩存系統
- Squid
- 用作HTTP、HTTPS、FTP等多種(反向)代理
- 訪問控制、認證功能
- Varnish
- 高性能HTTP加速器
- 靈活的設置語言
- 基本完全在內存中執行
- 速度比Squid快
- nginx、pound……
- 緩存服務器上線時注意
- 兩台負載均衡時,一台故障會導致另一台無法承受負載
- 備足服務器
- 即使備足服務器也要注意
- 新服務器(或剛啟動)要預熱,流量從小到大慢慢增大