第5課 大規模數據處理的難點 -- 內存和磁盤
單台Linux服務器瓶頸分析
1、查看平均負載
用top、uptime命令查看平均負載;
1、平均負載很低,系統吞吐量無法提升 --------->檢查軟件設置是否異常,網絡、主機是否存在故障
2、平均負載很高,用sar或vmstat命令查看cpu使用率和I/O等待率
2、確認CPU、I/O是否存在瓶頸;
>如果是CPU負載過高:
1、使用sar或top命令確認是用戶程序的瓶頸還是系統程序的問題;
2、用ps命令查看可見進程的狀態和CPU使用時間,進一步確認問題進程;
3、確定進程后,使用strace進行跟蹤或用oprofile進行剖測;
如果是排除程序失控、磁盤、內存處於理想狀態,則需要增加服務器、改善程序邏輯和算法;
>如果是I/O負載過高:
多半是程序發出的I/O請求過多導致負載過高或者是發生頁面交換導致頻繁訪問磁盤,使用sar或vmstat確認交換區狀態;
如果是發生頁面交換引起:
1. 用ps確認是否有進程消耗了大量內存
2. 如果是程序問題消耗大量內存的,需要改進程序;
3. 如果是因為內存安裝不足,則增加內存,無法增加內存的情況,需要考慮分布式
如果不是發生頁面交換引起(可能是用於緩存的內存不足):
1.如果增加內存可以擴大緩存,則增加內存;
2.如果增加內存還是無法解決問題,則考慮分布式或增加緩存服務器;
第6課:可擴展的要點
CPU負載的擴展(較簡單)
1、增加相同結構的服務器,通過負載均衡器來分散;
2、如:web應用服務器、網絡爬蟲等;
I/O負載的擴展(較復雜)
1、借助數據庫
2、大規模數據
第7課:處理大規模數據的基礎知識
處理大規模數據的三個重點:
寫程序的技巧:
* 盡量在內存中完成,:將磁盤尋道次數降到最低;可以實現分布式,有效利用局部性;
* 使用能應對數據量增加的算法,例如:線性搜索 -->二叉樹搜索,O(n) -->O(logn)
* 有時可以利用數據壓縮和搜索的技術
處理大規模數據之前的三大前提知識:
* 操作系統的緩存
* 以分布式為前提應用RDBMS時必須要做的事情
* 大規模環境中的算法和數據結構
第9課:降低I/O負載的策略
以緩存為前提,降低I/O負載的策略:
* 如果數據規模小於物理內存,則全部緩存;
* 如果數據規模大於物理內存,可以考慮數據壓縮(使用數據壓縮,在從緩存中讀取時是否要進行解壓,這是否會增加計算負載呢?);
* 如果數據規模大於物理內存 ,可以就是擴展到多台服務器。為分散CPU負載,只需要簡單增加服務器,為分散I/O負載,需要考慮局部性;
* 考慮經濟成本的平衡性
linux頁面緩存策略:(只要可能linux就會把空閑的內存用作頁面緩存使用)
1. 從磁盤讀取數據
2. 如果數據在緩存中不存在且有空閑的內存
3. 建立新的緩存
4. 如果沒有空閑內存供緩存使用,則替換舊的緩存
5. 進程要求分配內存時,其優先級高於頁面緩存;
服務器剛啟動時,不要投入生產環境,因為建立緩存需要時間,如果在沒有緩存的情況下,大規模的訪問造成頻繁的讀寫磁盤,可能會引起宕機;啟動后要將經常使用的數據庫文件cat一遍,使其放入緩存中;
第10課:利用局部性的分布式
所謂局部性就是Locality,根據訪問模式實施分布式;
我理解是按一定的業務規則將訪問進行分流,這樣單台服務器只要保存對應規則部分的緩存數據即可,那么應用請求分配由誰來完成呢?是LVS?
常用的局部性分布式技術是:Partitioning(分區)
簡單的說就是將一個數據庫分割到不同的機器上,
* 最簡單的分割方法:以表為單位分割,比如表A、B在機器1上,表C、D在機器2上;分割原則是看表的容量和機器緩存容量的匹配上;
這樣的分割是否意味着不同機器的表之間必須是弱關系的,不能有關聯的需求?
* 有一種分割方法是從數據中間進行分割,即對一個表,比如根據ID的起始字母:a-c在機器1,d-f在機器2等;
* 還有一種特別的分割方法是根據業務用途,將數據分割成“數據島”;例如Hatena BookMark是根據HTTP請求的User-Agent和URL進行分離的,例如:一般用戶分配到島1,部分API請求分配到島2,Google bot、Yahoo!等爬蟲分配到島3;
* 使用局部性的分布式,要求應用程序做相應的修改,同時存在的問題是:如果需要改變分割粒度,需要將數據合並一次后再進行分割,比較麻煩;
第11課:正確應用索引 ----分布式MySQL應用的大前提
* 在設計大數據量的表時,盡量緊湊一些,讓記錄盡可能的小,因為表結構稍微有錯誤,數據量就會以GB的單位遞增;
* 要注意表設計過程中對冗余列的處理,如果一個表包含冗余列,會浪費存儲空間,如果將冗余列分割到另一個表,也許會節省空間(不一定,需要評估),但同時也增加了查詢的復雜度,因此在時間和空間的取舍上要進行衡量;
* MySQL中建立索引的數據結構就是B樹的變種B+樹,B樹可以通過調整節點數參數M,使得每個節點的大小在4KB,從而使得磁盤尋道次數和節點訪問次數相同;而二叉樹是固定為2個節點,因此不具備這樣的調節能力;
* 從理論上,B(+)樹的復雜度為Olog(n),而線性搜索的復雜度為O(n)
Mysql索引的規則:
* where、order by、group by中指定的列會使用索引
* 何時索引有效?明確添加的索引、主鍵,UNIQUE約束;
* 想同時應用多個列上的索引,就必須使用復合索引;
* 確認索引是否有效的命令:explain
第12課:MySQL的分布式 -- 以擴展為前提的系統設計
MySQL的Replication:
* master/slave的架構;
* 查詢發給slave,更新發給master;通過ORM來控制;
* slave前面放負載均衡器,如:LVS 、MySQL Proxy,從而將查詢分散到多台服務器上;
Master/Slave的特征:
查詢可以擴展,只需增加Slave服務器即可,但在增加前添加適當的內存;
Master無法擴展,雖然web應用90%以上是讀操作,但如果需要擴展,則需要通過對表進行分割或更換實現方法;
- 進行表分割:分散寫入操作,將數據文件分散到同一機器的不同磁盤上或不同的機器上
- 不使用RDBMS,采用key-value存儲結構,如:Tokyo Tyrant、Redis
第13課:MySQL的橫向擴展和Partitioning
以Partitioning為前提的設計:
例如表entry和表tag是一對多的關系,如果要取出包含標簽“perl”的書簽,需要使用JOIN查詢,將兩個表關聯。但是如果entry和tag表放在不同的機器上,MYSQL就無法實現JOIN(MySQL的FEDERATED表可以實現),只有通過先查找包含“perl”標簽的記錄,再到entry表中根據eid找對應的entry記錄。因此,JOIN查詢只能在保證表以后不會被分割到不同機器上的前提下才能使用。
利用where…in…來避免JOIN
select url from entry INNER JOIN bookmark on entry.eid = bookmark.eid where bookmark.uid = 169848 limit 5;
=>
select eid from bookmark where uid = 169848 limit 5;
select url from entry where eid in (0,4,5,6,7);
第14課:特殊用途索引----處理大規模數據
問題:當數據規模超過RDBMS的處理能力時怎么辦?
方法:利用批處理操作從RDBMS中提取出數據,建立索引服務器之類的,再讓WEB應用程序通過RPC等訪問索引服務器。
第30課:雲 vs 自行構建基礎設施
Amazon EC2 (Amazon Elastic Compute Cloud),是不負責儲存的,儲存由S3 (Amazon Simple Storage Service)服務負責,所以得有腳本每次重啟時從S3恢復數據庫
Amazon S3 (Amazon Simple Storage Service)
Google App Engine
Microsoft Windows Azure
第31課:層和可擴展性
一台服務器的處理能力大概為100萬~200萬PV(page views)/月左右 4核CPU,8G內存
各層可擴展性:
應用程序服務器,配置相同,不持有狀態,容易擴展
數據源(數據庫服務器、文件服務器):read的分布式容易,write 的分布式難
第33課:保證冗余性
應用程序服務器:
增加服務器數量
用負載均衡器實現失敗轉移和失敗恢復
數據庫服務器:
Multi-master:是今年Mysql服務器構建的主要方法。該架構中,服務通常是兩台,組成Active/Standby結構。其中,一台是Active,另一台是Standby,通常只向Active寫數據。一旦Active停機,Standby通過VRRP協議監視到這一情況,即把自己提升為Active,變成新的master。而停機的那台經過人工修復后變成Standby,或恢復為原來的結構。為了從外部判斷哪台是Active,需要用到虛擬IP(VIP),即Active服務器除了原有的IP地址,還會被分配一個服務用的虛擬IP地址。應用程序服務器始終訪問這個虛擬IP。切斷時將這個虛擬IP分配給新的Active。從而實現master的透明切換。
第38課:網絡的分界點
PC路由器的極限:超過1Gbps(30pps,即每秒30萬包數據,按每包300字節算,為1Gbps)
一個子網的極限:500台主機
一個數據中心無法實現全球化
CDS:(Content Delivery Network),基本原理就是在世界各地放置服務器,將媒體文件緩存后,用戶就可以從最近的服務器下載了。
如:Amazon CloudFront