第1課 大規模服務和小規模服務
Scale up: 提高硬件性能
Scale out: 增加服務器數量
用廉價硬件確保可擴展性
用load balancer
第2課 持續增長的服務和大規模化的障礙
用LVS + keepalived 這種負載均衡器+運行狀態盡視的開源軟件
逐漸推行虛擬操作系統
第3課 服務開發現場
實現過程中盡量書寫測試用例 - TDD
編程語言的選擇策略是同一層僅使用一種語言
第5課 大規模數據處理的難點
大規模 = 無法 in-memory computation
查找bottleneck:
top
或sar
for processesps
for CPU timestrace
或oprofile
進行剖測
第6課 可擴展性的要點
硬件價格和性能不成比例
CPU擴展可借助於load balancer
I/O擴展十分困難,可借助於大規模數據庫
第8課 操作系統的緩存機制
LRU cache: Linux用inode編號識別文件,以文件inode編號和offset作鍵進行caching
OS內部使用Radix tree作caching搜索
- Radix tree similar to Patricia tree
第10課 利用局部性的分布式
Partitioning,將一個數據庫分割到多台服務器上
相應cache可以用在別的地方,整體來看,in-memory數據量就增加了
分割成島: Google/Yahoo spider分配到一個島,人類用戶分配到另一個
- Spider會訪問很久很久以前的網頁,人類不會
- 因應寬廣度,caching很難奏效
第13課 MySQL的橫向擴展和Partitioning
Redundancy = 4台server
- 如果只用3台,即1 master+2 slave,其中一台slave發生故障,就只剩下 1 master+1 slave運作。然後用新server替換,就要從其中一台複製數據, 過程中就要將餘下的一台slave停機,即將僅餘的redundancy都失去
- 如果master只作寫入,slave只作讀取,任何情況下都要有2台運作
Partitioning: 如果加RAM可以應付就不用Partitioning
第17課 可變字節碼和速度的感覺
Variable byte code: 正常integer = 4 bytes,但不是每一個integer都要4 byte。如果要儲存array of integer,e.g. [5, 130]
5 = 00000000 00000000 00000000 00000101
130 = 0000000 00000000 00000000 10000010
VBC: 7 LSB作數字,MSB作flag,只有最後一byte會assert MSB
5 = 1000101
130 = 00000001 10000010
[5, 130] = 1000101 00000001 10000010
其他方法壓縮儲存: 用數值差e.g., [5, +125]
- 差的分佈呈幾何分佈
其他方法: Gamma code, delta code, Golomb code, interpolate encoding
第20課 Hatena Diary的關鍵字鏈接
Aho-Corasick算法: One large string (document), a series of keywords to search from document
- Keywords form a trie
- Trie: Add failed links to other nodes of the trie, e.g.
[ABCE, BCB]
A -> B -> C -> E B -> C -> B Fail link:C
on first chain to secondB
on second chain, so when afterC
we failed to matchE
, we allow it to matchB
- The trie becomes a state machine. We walk the document on the state machine and enumerate all “accept” nodes ever traversed.
第22課 創建Hatena關鍵字鏈接
Goal:
- 給定keyword set
- 輸入文章
- 從文章找出關鍵字並返回 offset
- 將關鍵字部分用
<a href=”..”> .. </a>
替換
Solution:
- Aho-Corasick算法,用keyword set建trie (Aho-Corasick Automata)
- 從Trie的root作BFS,失敗則從failure link返回
第25課 搜索系統的架構
全文搜索: grep
- Document size m, keyword size n, complexity = O(mn)
- Knuth-Morris-Pratt algorithm: O(m+n)
- KMP algorithm is Aho-Corasick Algorithm with only one keyword
- Boyer-Moore algorithm: O(mn) in worst case, O(n/m) in best case
後綴類型
- Trie, suffix array, suffix tree
- 將可搜索的形式將文檔全部儲到記憶體中,不需要保存文檔副本
逆向索引 Inverted index
- Relate “term” and document
- 在文檔之外另建逆向索引
- 需要保存文檔副本
第25課 搜索引擎的內部結構
Dictionary + Postings
- Dictionary: keyword set
- Postings: term-document relationship
- 能即時發現包含在term中的文檔
創建dictionary
- 怎樣選擇term?
- 預定字典 或 語素分析 或 用n-gram切分
- 用wikipedia標題作字典
- 語素分析,以詞性分詞
搜索引擎質素評測:
- Recall: 搜索結果佔相關文檔比例, coverage, 量
- Precision: 相關文檔佔搜索結果比例, accuracy, 質
參考文獻:
- Maxime Crochemore, Christophe Hancart, Thierry Lecrog, “Algorithm on String”, Cambridge University Press, 2007.
- Manning D. Christopher, Raghavan Prabhakar, Schutze Hinrich, “Introduction to Information Retrieval”, Cambridge University Press, 2008.
- Ian H. Witten, Alistair Moffat, Timothy C. Bell, “Managing Gigabytes”, Morgan Kaufmann, 1999.
- Bruce Croft, Donald Metzler, Trevor Stroham, “Search Engines: Information Retrieval in Practice”, Addison Wesley, 2009.
第28課 答案範例和思路
2010年:
- Twitter每秒處理1.2M tweets
- 橫向擴展用partitioning對數據進行分割
- 用MySQL+memcached和partitioning
- Partitioning用tweet發表時間為準,而非user id
第29課 企業軟件vs web服務
Web服務:
- 低成本、高效率
- 不要追求100%可靠性
- 重視可擴展性、responsiveness的設計
- 只需保持99%時間good responsive,將技術重點放在可擴展性上
- 要重視開發速度
- 企對軟件要從半年到一年前就開始規劃,進行開發測試,web基礎設施必須能靈活應對
第30課 雲vs自行構建基礎設施
Hatena服務規模
- 用戶1.5M,每月unique user 19M
- 每月數billion request,不包括圖像
- Peak time traffic 850Mbps
- 實體硬件600台以上,22 racks,virtualized 1300台
系統架構:
- App:Database ratio = 1:2
- 服務器根據請求屬性分成了面向用戶和面向爬蟲
- 架構: Reverse proxy (3), Squid (2), memcached (5), App server (5 user, 6 spider), DB (2 content, 14 entry, 2 html, 6 keyword), load balancer (2) Other services: Search (2), categorize (1), related doc (2), hadoop (2), worker (2)
第31課 層和可擴展性
每月1M page view可用一台server處理
第33課 保証冗餘性
應對策略: 用load balancer作failover和failback
- Failover: 自動離線
- Failback: 恢複正常的server再次上線
- Load balancer自動health check判斷是否需要failover/failback
數據庫服務器
- Master冗餘化比較困難
- Multi-master = 雙向replication,會有延遲和短時間內(millisecond)數據不一致
- MySQL multimaster: 多個服務器之間用Virtual Router Redundancy Protocol互相監視
- active/standby架構
- 只有一active,所有寫入均向active寫入
- 一旦active停機,standby就提升為active,變成新的master
- 修復後failback,成為新standby或重新成為active
Hatena 2009年8月,一天消耗幾十GB存儲量,一個月2TB
增加單台服務器的儲存量 = 保存文件數激增 = I/O性能成瓶頸
第34課 系統穩定化
用保証冗餘性的方法讓系統更穩定。
避免用盡CPU,以免故障時處理能力不足。實際應只使用7成左右
Slashdot效應、digg效應: 加上squid之類的緩存服務器,結未登錄的用戶返問緩存內容
Example: Nintendo DSi
- 加星星會有Super Mario吃金幣的叮鈴聲,因此孩子會加上100個、1000個星星
- Ugo memo上線之前,全部星星有幾千萬個,上線後增大到上億。原本數GB的數據庫變成幾十GB
第35課 系統穩定對策
為了維持適當的餘量,在極限的70%運營
自動DoS判斷: mod_dosdetector
- 一分鐘之內同一IP地址發送的請求過多,就返回403
資源過度使用時自動重啟系統
- Memory leak protection
自動終止耗時查詢
- Kill SQL running too long
- 未能修改代碼時的臨時對策
第36課 虛擬化技術
Hatena用Xen (CentOS 5.2, Xen 3.0.3)
- Local disk LVM partition
- monit監視平均負載,一旦超過threshold,就執行Apache重啟或操作系統重啟
Virtualization overhead:
- CPU speed: 2-3%
- Memory throughput: 1%
- Network throughput: 50%
- I/O performance: 5%
第37課 硬件和提高效率
32GB RAM vs 8GB RAM + SSD
- 32GB RAM可將全部數據in-memory,不會發生I/O read,只有I/O write
- 8GB RAM I/O read非常多,但因SSD,I/O wait不明顯
- SSD效能近似於in-memory而不需用服務器專用硬件
- 兩者均達到每秒處理500次SQL SELECT的性能
SSD壽命
- 查看S.M.A.R.T. 值中的 E9 (media wearout indicator) 數值,會從100減少到0
- 用smartctl命令查看,ID 233 (Hex = E9)
特別篇第1課 作業隊例系統TheSchwartz、Gearman
用Task queue執行那些允許延遲的處理
特別篇第3課 緩存系統Squid、Varnish
兩台squid聯合運行: 使用Inter-Cache Protocol (ICP, internet draft)
兩層結構:
- 上層squid接收但不保持cache,而是將request轉發結下層squid
- 用CARP (Cache Array Routing Protocol)
- 以URL為key,轉發至適當的squid server
Bibliographic data
@book{
title = "大規模Web服務開發技術",
author = "伊藤直也 田中慎司",
editor = "李劍",
publisher = "電子工業出版社",
isbn = "978-7-121-1388-3",
year = "2011",
month = "July",
}