第5課 大規模數據處理的難點 -- 內存和磁盤 node
單臺Linux服務器瓶頸分析 linux
一、查看平均負載 web
用top、uptime命令查看平均負載; 算法
一、平均負載很低,系統吞吐量沒法提高 --------->檢查軟件設置是否異常,網絡、主機是否存在故障 sql
二、平均負載很高,用sar或vmstat命令查看cpu使用率和I/O等待率 shell
二、確認CPU、I/O是否存在瓶頸; 數據庫
>若是是CPU負載太高: 緩存
一、使用sar或top命令確認是用戶程序的瓶頸仍是系統程序的問題; 服務器
二、用ps命令查看可見進程的狀態和CPU使用時間,進一步確認問題進程; 網絡
三、肯定進程後,使用strace進行跟蹤或用oprofile進行剖測;
若是是排除程序失控、磁盤、內存處於理想狀態,則須要增長服務器、改善程序邏輯和算法;
>若是是I/O負載太高:
多半是程序發出的I/O請求過多致使負載太高或者是發生頁面交換致使頻繁訪問磁盤,使用sar或vmstat確認交換區狀態;
若是是發生頁面交換引發:
1. 用ps確認是否有進程消耗了大量內存
2. 若是是程序問題消耗大量內存的,須要改進程序;
3. 若是是由於內存安裝不足,則增長內存,沒法增長內存的狀況,須要考慮分佈式
若是不是發生頁面交換引發(多是用於緩存的內存不足):
1.若是增長內存能夠擴大緩存,則增長內存;
2.若是增長內存仍是沒法解決問題,則考慮分佈式或增長緩存服務器;
第6課:可擴展的要點
CPU負載的擴展(較簡單)
一、增長相同結構的服務器,經過負載均衡器來分散;
二、如:web應用服務器、網絡爬蟲等;
I/O負載的擴展(較複雜)
一、藉助數據庫
二、大規模數據
第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