英文原文:Big List Of 20 Common Bottlenecks html
在 Zen And The Art Of Scaling - A Koan And Epigram Approach 一文中 , Russell Sullivan 提出一個頗有趣的設想:一共有20種經典的瓶頸。這聽起來就像只有20種基本的故事情節(20 basic story plots)那樣讓人懷疑。不過基於每一個人不一樣的分類方式,這個說法或許是對的,可是在現實中,衆所周知,瓶頸是無窮無盡的並且涉及方方面面。 linux
一天, 來自 Terracotta 的 Aurelien Broszniowski 給我電郵了一份他心中的瓶頸列表,咱們同時把咱們的郵件抄送給了Russell, 他也給出了他的列表。而我也有我本身的想法。 因此,下面就是這幾碗水煮成的一鍋石頭湯( http://en.wikipedia.org/wiki/Stone_soup, stone soup典故) 算法
Russell 說要是年輕的時候就知道這些該多好啊,而對我來講則能夠提供更多的思路。你的經驗越多,處理過不一樣類型的項目,你就能夠給這個列表增長更多的內容。所以當你在閱讀這個列表時,或者是在整理本身的列表時,多年的豐富經驗的積累以及遇到的一些小挫折,每個故事都值得進行總結。 數據庫
- 數據庫:
- 工做中數據大小超過可用內存 RAM
- 長短查詢混合
- 寫-寫 衝突
- 大的聯合查詢佔光內存
- 虛擬化:
- 共享 HDD 存儲,磁盤尋道掛起
- 雲平臺中的網絡 I/O 波動
- 編程:
- 線程:死鎖、相對於事件驅動來講過於重量級、調試、線程數與性能比非線性
- 事件驅動編程:回調的複雜性、函數調用中如何保存狀態(how-to-store-state-in-function-calls)
- 缺乏profile工具、缺乏trace工具、缺乏日誌工具
- 單點故障、橫向不可擴展
- 有狀態的應用
- 搓設計:一臺機器上能跑,幾個用戶也能跑,幾個月後,幾年後,尼瑪,發現扛不住了,整個架構須要重寫。
- 算法複雜度
- 依賴於諸如DNS查找等比較搞人的外部組件
- 棧空間
- 磁盤:
- 本地磁盤存取
- 隨機磁盤讀寫 -> 磁盤尋道
- 磁盤碎片化
- 寫入超過SSD容量的數據致使SSD硬盤性能下降
- 操做系統:
- 內核緩衝刷入磁盤,填充linux緩衝區緩存
- TCP緩衝區太小
- 文件描述符限制
- 功率分配
- 緩存:
- 不使用memcached
- HTTP中,header,etags,不壓縮(headers, etags, not gzipping)
- 沒有充分使用瀏覽器緩存功能
- 字節碼緩存(如PHP)
- L1/L2緩存. 這是個很大的瓶頸. 把頻繁使用的數據保持在L1/L2中. 設計到的方面不少:網絡數據壓縮後再發送,基於列壓縮的DB中不解壓直接計算等等。有TLB友好的算法。最重要的是牢固掌握如下基礎知識:多核CPU、L1/L2,共享L3,NUMA內存,CPU、內存之間的數據傳輸帶寬延遲,磁盤頁緩存,髒頁,TCP從CPU到DRAM到網卡的流程。
- CPU:
- CPU 過載
- 上下文切換 -> 一個內核上跑了太多的線程,linux調度對於應用來講很不友好, 太多的系統調用, 等等...
- IO 等待 -> 全部的CPU都掛起等待比較慢的IO
- CPU 緩存: 緩存數據是一個爲了平衡不一樣實例有不一樣的值和繁重的同步緩存數據保持一致,而精心設計的一個進程。
- 背板吞吐量
- 網絡:
- 網卡的最大輸出帶寬,IRQ達到飽和狀態,軟件中斷佔用了100%的CPU
- DNS查找
- 丟包
- 網絡路由瞎指揮
- 網絡磁盤訪問
- 共享SAN(Storage Area Network)
- 服務器失敗 -> 服務器無響應
- 過程:
- 測試時間 Testing time
- 開發時間 Development time
- 團隊人數 Team size
- 預算 Budget
- 代碼缺陷 Code debt
- 內存:
- 內存溢出 -> 殺進程,進入 swap ,愈來愈慢
- 內存溢出致使磁盤頻繁讀寫(swap相關)
- 內存庫開銷
- 內存碎片
- Java 須要垃圾收集致使程序暫停
- C 語言的 malloc 沒法分配
若是你有更多的瓶頸要添加或者建議修復,請加入。感謝 Aurelien 和 Russel。