一、認識服務的規模linux
註冊用戶,獨立用戶web
請求數正則表達式
繁忙時流量算法
服務器臺數sql
貌似應該有不少其餘的指標,之前都據說過,可是歷來沒有認真分析過,已經上線的系統也沒有對此進行過統計和分析!數據庫
二、大規模服務中的問題有如下幾點:編程
可擴展性、負載均衡的必要性緩存
通常來講,當一臺服務器沒法承擔負載時,都會採用橫向擴展(scale out)或者縱向擴展(scale up)。橫向擴展就是經過服務器的數量來分擔負載,縱向擴展是經過提升硬件的性能來處理負載。而咱們知道,硬件的性能和價格不是成比例的,因此一般採用橫向擴展技術!採用橫向擴展也會帶來問題,如請求如何分配——負載均衡,數據如何同步,網絡通訊延遲等。服務器
保證冗餘性網絡
服務器多了後,故障率也會上升。要麼構建穩定的系統,要麼構建發生故障時能自動切換以繼續運行的系統!
低成本運維的重要性
採用自動化工具。
開發人數和開發方法的變化
如何標準化開發?
考慮下應用程序實現方案?
統一編程語言?
統一庫函數和框架?
統一代碼規範?
使用版本管理工具管理源代碼?
須要有人負責全局的推行。
團隊如何管理
應對大規模數據量
數據的流向:磁盤->內存->緩存->CPU。各層的速度差別巨大。
減少數據大小?
分散到多臺服務器上?
把數據讀取次數降到最低?
三、系統增加戰略——最小化開端、預見變化的管理和設計
服務規模小的時候,使用簡單的方法效果會更好。應該考慮某種程度上的容量規劃,以及在設計服務時儘可能減小沒必要要的數據等。
四、技術團隊體制
服務開發部:負責開發各類服務的團隊,負責平常的應用程序改進。內部按照服務分紅團隊,每隊3~4人。服務開發部也會跟蹤本身開發的服務的性能,將主要頁面的大體響應時間定量化,而後天天改進。
基礎設施部:負責運維服務器和基礎設施的團隊,負責準備服務器、運維數據中心和負載均衡等。
五、溝通方式
工做指示基本經過口頭傳達
若是口頭效率低下或者但願留下記錄,則經過工具的組合來進行交流
博客+wiki(工做內、實施維護操做方法)
IRC
服務器管理工具
六、改變系統的流程
各團隊用10分鐘開個短會:共享前一天進度和當天計劃。
會議中決定任務負責人,會議結束,當即開始任務。
實現過程儘可能書寫測試用例。
測試以後開始實現,實現完成提交版本管理。
實現完成後,請求團隊內其餘開發工程師進行代碼審查。
審查經過後,合併到產品代碼。
七、數據規模
表的大小以GB爲單位,執行select col from table,若是不加索引,由於數據量差很少有千萬級別,所以,該SQL會卡死!因此哪怕是調試,也須要避免這種sql語句,可能會引發太高的負載。
八、處理難點
沒法在內存中處理!須要讀磁盤!內存要比磁盤的I/O快10W~100W倍。
磁盤的搜索和物理結構有關,搜索時有機械物理操做,須要數毫秒,可是內存搜索與物理結構無關,只須要數微秒。
由於磁盤搜索的慢,因此操做系統作了一些加速處理:
將連續的數據放在同一處,而後讀取的時候並非逐個字節讀取,而是一次讀取4KB左右。(能夠參考着看Linux相關基礎,鳥哥私房菜裏面也提到過。)這樣就能夠將旋轉次數降到最低。
傳輸速度和總線速度的差別(上面說的是搜索!)。內存的傳輸速度大概比磁盤的快100倍。。。。。(可使用hdparm工具查看傳輸速度【Timing cached reads=內存傳輸速度】【Timing buffered disk reads=磁盤傳輸速度】)。
九、 可擴展性的要點——CPU負載和I/O負載
在web應用中,接受HTTP請求、查詢數據庫,再把數據庫返回的數據加工變成HTML後發送給客戶端,基本上只消耗CPU。相反,數據庫服務器須要較多I/O資源。
由此,對於web應用程序服務器來講,負載均衡很是簡單,只須要相同的主機作相同的工做就能夠實現了,由於不須要分散數據。可是I/O負載的負載均衡就沒有那麼簡單了,由於數據分散以後就會有數據一致性的問題。
十、處理大規模數據的三個重點——寫程序的技巧
能在內存中完成多少
在最大限度減小磁盤尋道次數的基礎上靈活運用內存
充分利用局部性的分佈式
使用能應對數據量增長的算法
例如線性搜索->二叉樹搜索
O(n)->O(log n)
有時能夠利用數據壓縮和搜索等技術
十一、處理大規模數據以前的三大前提知識——程序開發的底層基礎
操做系統的緩存
以分佈式爲前提應用RDBMS時必需要作的事
大規模環境中算法和數據結構怎樣使用
十二、在理解操做系統緩存的基礎上編寫應用程序——頁面緩存
linux上有頁面緩存(page cache)、文件緩存(file cache)、緩衝區緩存(buffer cache)機制。
虛擬內存機制:將邏輯的線性地址變換成物理的物理地址。這樣就可使進程無需考慮本身使用的內存位於什麼地方,能夠認爲好比從0x000地址開始,這樣處理就更方便。在分配內存時,以適當的大小(4KB)分配好,並傳遞給進程,而不是一個字節一個字節的訪問。這樣的內存塊就稱爲「頁面」。
頁面緩存原理:操做系統可以讓已分配的頁面一直維持在這一狀態。
進程不能訪問磁盤,只能訪問虛擬內存。
操做系統從磁盤中讀取4KB的塊,並寫入到內存中,而後將該地址變換爲虛擬地址後再告訴進程,最後進程再訪問內存。而進程讀完數據後,雖然再也不須要這塊內存,可是並不會釋放,而是保留下來,這樣其餘進程訪問同一塊磁盤時,就能夠直接使用留下來的頁面,無需再訪問磁盤。這就是頁面緩存。
頁面緩存的效果就是,一直運行的操做系統更快些。
VFS
LINUX以頁面爲單位緩存磁盤
LRU
內存空閒時就緩存——經過sar確認:sar -r 1(每秒輸出一次當前的內存狀態),kbcached即用於緩存的容量,%memused被使用的內存,包括緩存。
增長內存下降I/O負載
1三、下降I/O負載的策略
以緩存爲前提的下降I/O負載的策略
若是物理內存比數據規模還大,考慮所有緩存。
與經濟成本的平衡性。
擴展到多臺服務器——沒法所有緩存的狀況
CPU負載分散只須要簡單的增長
I/O分散要考慮局部性
1四、利用局部性的分佈式
局部性的分佈式就是根據訪問模式進行分散。
Partitioning——考慮局部性的分佈式
Partitioning就是將一個數據庫分割到多臺服務器上。分割方法不少:
最簡單的就是「以表爲單位進行分割」,這種方式須要修改程序。
從數據的中間分割,例如按照ID的起始字母進行Partitioning。問題:當改變分割粒度時,須要將數據合併一次比較麻煩。
根據訪問模式分割成「島」——考慮局部性的分佈式
好比通常用戶分配到島1,爬蟲等分配到島2
以頁面緩存爲基礎的運維基本準則
操做系統剛啓動時不要將服務器投入生產環境
性能測試要在緩存優化後進行
1五、分佈式MySQL應用的三大要點
靈活應用操做系統緩存
正確應用索引
以橫向擴展爲前提設計系統
1六、靈活應用操做系統緩存
考慮全部數據的大小,儘可能將數據量維持在物理內存量之下。
內存不足時增長內存
考慮表結構設計對數據大小的影響
當記錄數上億以後,即便增長8字節的列,數據量也會增長3GB
規範化雖然能夠減小數據量,可是會使查詢變得複雜,所以應該在速度和數據量的平衡性前提下,考慮規範化。
1七、索引
B樹
二叉樹和B樹:B樹能夠合理的設置節點大小,好比設置爲4KB,則和上面的緩存大小相一致!
B+樹
MySQL的索引採用的就是B+樹:使得搜索外部設備時可以將尋道次數最小化;搜索複雜度O(n)->O(log n)
MySQL索引的不足
使用因此的有->where、order by、group by條件中指定的列
什麼時候有效->明確的添加的索引;主鍵、UNIQUE約束。能夠經過show index確認
MySQL索引的陷阱->想同時使用多個列上的索引,就必須使用複合索引
確認索引是否有效的方法——explain命令
type和rows:type爲ALL,rows很大則索引無效,type爲ref,rows比較小則索引有效
Extra列也十分重要,若是出現Using filesort或Using temporary的查詢不能說是好查詢
1八、MySQL的的分佈式
MySQL的replication功能,即常見的主從和讀寫分離
應用程序服務器經過負載均衡去查詢slave,這樣就能夠把查詢分散到多臺服務器上了。
master/slave的特徵——對參照系進行擴展,更新類不擴展
主從的結構肯定了master是沒法實現分佈式的。
一般的應用程序,讀佔據了90%以上,所以master不會稱爲瓶頸。
須要對更新/寫入類進行擴展——表分割、key-value存儲
當master的表負載太高,則須要對錶進行分割。經過分割來分散寫入操做,若是能夠分割表文件,就能夠將其分散在同一臺機器的多塊硬盤或者分散到多臺服務器上。
或者考慮不使用RDBMS,而使用key-value,如一般的點贊。
1九、MySQL的橫向擴展策略
數據能放入內存嗎?
->yes:放入內存
->no:增長內存,沒法增長內存,則用Partitioning
分割以後,將沒法使用join
以Partitioning爲前提的設計
如若數據庫表以前耦合性很是大,則設計時不要將其分割到不一樣的服務器上。
避免join——利用where in
Partitioning的好處
下降負載
增長局部性
提升緩存的效果
缺點
運維變得複雜
故障率上升
實現冗餘須要幾臺服務器
答:4臺。1master+3slave。若是是1+2,假設slave壞掉,則在恢復數據的時候就必須停掉剩下那臺slave!
20、特殊用途索引——處理大規模數據
超過RDBMS的處理能力時,利用批處理操做從RDBMS中提取出數據,創建索引服務器之類的東西,再讓Web應用程序經過RPC等訪問索引服務器。
特殊用途索引——使用調優後的數據結構
關鍵字連接的處理
使用巨大的正則表達式,雖然比數據庫快,可是仍然很是慢
Trie+Common Prefix Search
2一、理論聯繫實踐
探尋必須的技術條件
RDBMS中不使用JOIN,這應該是「最差實踐」,教科書是絕對不會說不使用JION的,但這是從實踐中得來的經驗!
相反,使用一些教科書上的理論解決一些相應的問題,倒是十分正確的!
從計算機的角度去思考
後續是有關壓縮、算法和搜索的話題
2二、以緊湊、簡潔的方式保存整數數據
壓縮大規模數據能夠下降磁盤I/O。
2三、可變字節碼和速度的感受
可變字節碼——整數的編碼方式
對例子進行編碼實現
2四、算法的實用化
算法和算法的評測
數據規模和複雜化的差別
若是數據很小,則算法的複雜度也區分不出來,但隨着數據規模變大,算法選擇的差別性就愈來愈大!
算法的評測->複雜度
時間複雜度(執行時間、操做步驟數)、空間複雜度(內存使用量)
複雜度和常數項——評測很重要
常數項:算法實現中不依賴與輸入大小,但卻不得不執行的一類處理。
就算實現不復雜,CPU緩存是否容易生效、分支預測是否發生等計算機結構特色也會有影響,所以常數項可能會致使差距。
如一樣是O(log n)複雜度的排序算法中,快速排序是最快的,由於它使得CPU緩存容易生效。
2五、關鍵字連接
2六、文章分類
2七、全文搜索技術的應用範圍
2八、搜索系統的架構
2九、搜索引擎的內部結構
30、建立全文搜索
3一、企業軟件vs.Web服務
應用範圍上的差別
流量、增加度、可靠性、事務二者間差別較大。
Web服務的基礎設施
低成本、高效率:不該當追求100%的可靠性
重視可擴展性、響應性方面的設計
Web服務的服務規格常常會發生變化
3二、雲vs.自行構建基礎設施
雲計算特色就是價格便宜,可擴展性優秀。缺點:內存有上限和低速I/O,模糊不清的負載均衡器,時常停機
自行構建基礎設施:硬件配置能夠靈活調整;可以靈活應對服務的要求;能夠控制瓶頸。
3三、層和擴展性
一臺服務器能處理的流量極限
各層的可擴展性
web服務器可擴展比較容易,增長服務器便可
數據庫服務器和文件服務器的擴展性相比較而言沒有那麼容易。
read和write相比較,read的分佈式也比較容易實現。
最難的要數write的分佈式
3四、掌握負載進行調優
可視化的管理界面,服務器管理工具。
測量負載的指標——平均負載、內存和CPU相關信息
經驗來講,平均負載的值不超過CPU的核數就沒有問題。
根據用途進行調優
面向用戶
面向爬蟲
3五、保證冗餘性
應用程序服務器通常採用負載均衡實現失敗轉移和失敗恢復,讓故障服務器自動下線,故障恢復以後再上線。
數據庫服務器能夠採用muti-master的方式。
存儲服務器採用分佈式文件系統。
3六、系統穩定化
留出必定餘量!
系統的不穩定性
功能增長+內存泄漏:功能達不到理想的性能,致使總體負載上升,服務中止,使用的編程語言,也很難消除內存泄漏。
地雷:好比一篇文章有一萬多個評論,若是沒有考慮到這種狀況,極有可能將評論數所有讀取出來進行展現,會致使服務器性能降低甚至停機。
用戶的訪問模式:如連接被貼到著名網站,被大量用戶訪問致使系統停機。一般能夠採用緩存服務器。
數據量增長
外部關聯程序的增長
內存、硬盤故障
網卡故障
3七、系統穩定對策
維持適當餘量,能夠將70%做爲分界線
消滅不穩定因素:下降SQL負載、減小內存泄漏、發生異常時的自律控制等
發生異常時的自律控制如自動DoS判斷;自動重啓服務器;自動終止耗時查詢。
3八、提升硬件資源使用率
引入虛擬化技術
經過服務器管理工具在運營上發揮虛擬化的優點
虛擬化的額外開銷
CPU大約2%~3%
內存性能10%
網絡性能50%
I/O性能下降5%左右
3九、網絡的分界點
超過1Gbps(從路由來看應該是30萬pps)->PC路由器的極限
對策:採用多個PC路由;購買成品路由器
超越500臺主機->一個子網的極限
子網、ARP表的極限
網絡架構的層次化
一、最小的爲訪問層
二、上面的是分發層
三、最上方爲核心層或OSPF層
全球化->一個數據中心的極限
對策:採用CDN
40、應對大規模服務須知
做業隊列系統——TheSchwartz等
存儲的選擇——RDBMS、key-value等
緩存系統——Squid等
計算集羣——Hadoop等