狠狠撸

狠狠撸Share a Scribd company logo
寫出高性能的服務與應用
那些你沒想過的事!
I’m 小傑 ? COSCUP 2016
I’m 小傑
? 快出社會的研發替代役
? Synology Inc.
? 同步後端+客戶端開發
? 尋找性能的初學者
Twitter: welkineins
為什麼
我開始在意性能?
因為我們在 NAS
上開發各種不同的功能
檔案存取 ? 網頁伺服器 ? 雲端同步
影音串流 ?照片中心 ? 記事本
那有什麼問題呢
( ??ω?? )?
因為家用級 NAS
的硬體超廢
但使用者想要
的一個都不能少
檔案存取 ? 網頁伺服器 ? 雲端同步
影音串流 ?照片中心 ? 記事本
為了滿足使用者
只能好好努力
你也该注意性能!
你可以知道自己
寫的程式有多慢
或許你可以
讓使用者更開心
或許你可以
省下很多錢
或許你可以
多救幾隻北極熊
所以從今天起
開始關注性能吧!
說到性能
你想到的是什麼?
“How well is the computer
doing the work it is
supposed to do?”
- Arnold Allen
https://en.wikipedia.org/wiki/Computer_performance
簡單來說
? 性能
- 在給定的工作下
- 系统在选定的效能指标的表现
工作
? 實際上要做的事情
? 例如
- 聊天系統:大量點對點傳送訊息、群組訊息
- 售票系統:空位查詢、畫位、推不倒
- 資料庫:CRUD、Query
- Web Server:提供網頁、Web API、…
- 儲存:讀寫檔案
性能指標
? 人訂出來的期望目標
- 可同時處理 100k 人連線
- 回應時間要在 3 秒內
- 處理延遲要在 10 毫秒以下
? 系統跑出來的實際數據
- 性能測試,有數據才敢大聲說
- 結果包含硬體和軟體效能
常見性能指標
? 速度與數量
- RPS (Requests Per Second)
- QPS/TPS (Query/Transactions Per Second)
- Latency/Response Time (MS)
- b/s (Bits Per Second)
- IOPS (Input/output Operations Per Second)
? 其他:HA, Scalability, etc.
怎樣才算高性能?
? 性能
- 在給定的工作下
- 系统在选定的效能指标的表现
? 高性能
- 有效的利用系統
- 在給定的工作下
- 滿足或提供最高的效能指標表現
例如
? 效能指標比較好
- Nginx vs Apache
- MySQL vs. PostgreSQL
- Node.js vs. Ruby, PHP 5 vs. PHP 7
? 超過服務需求
? CP 值很高
- Scale down
我知道性能了
那怎麼開始呢?
把性能放心上
? 了解性能要求 (非功能性要求)
? 在開始時就要規劃 (至少放心裡)
? 實作有效率的程式
? 完成時進行效能測試
? 最佳化
高性能需要
太多領域知識了
怎麼賺錢多開機器
負載平衡
資料庫讀寫分離
資料庫分表分片
Compiler Optimization
WAL
Algorithm
B-tree
Buffer/Cache
Loop-unrolling
Multi-thread
Cloud
EXPLAIN QUERY PLAN
Scheduling
Context-switch
JIT
Interrupt
Lock Contention
NO-SQL
Sync/async
C10K
Data structure
性能Mutex/Futex
Message Queue
Index
TCP/UDPSerialization
Event Loop
Affinity
Swap/paging
Memory barrier
GC
malloc
coroutine
所以今天只講
基本到你沒想過的事
希望在你的領域
都能找發現類似的東西
你沒想過的事…
? 了解你的系统
? 让硬体同时动起来
? 善用硬体架构
? 作业系统是敌是友?
? 不要閒置資源:I/O 模型
? 不要浪費資源:Processing 模型
? 聪明的做越少越好
了解你的系统
冰山一角
http://www.bizhi360.com/fengjing/4498.html
hardware
OS
Language VM
Framework
Application / Service
Lib
了解你的系统
? 了解每一層的優點與雞肋
- 彈性 vs 性能 / 可以不要 GC 嗎?
? 符合底層的運作方法
- 硬體、OS、框架作者的抽象想法
? 使用底層提供的高性能介面
- 例如 Linux 的 sendfile(), copy_file_range()
了解硬體運作
? 硬體是最後執行地方
- CPU, Memory, Disk, NIC, etc.
? 無法突破的物理限制
- 計算、記憶體、儲存、網路頻寬
? 最後的抽象地點
- 相同的工作方式或許最佳性能?
- 神祕的特殊功能
让硬体同时动起来
The Free Lunch Is Over
? 程式不會再隨著硬
體升級而變快
? 程式開發時就要考
慮充分利用硬體
- 多核心 CPU
- 先進指令集
? 平行計算是未來
http://www.gotw.ca/publications/con
currency-ddj.htm
http://www.thepenipeople.com/home/2015/12/13/physical-architecture
? CPU
? Multi-core
? ALU、FPU
? MMU
? GPU
? Disk 控制器
? RAID 控制器
? NIC 控制器
? DMA engine
? ….
其實硬體早就在平行
让硬体同时动起来
? 重疊硬體的運作時間
- Multi-core 同時計算
- 記得 CPU 和 Disk、NIC 可以同時運作嗎?
http://minnie.tuhs.org/CompArch/Lectures/week10.html
善用硬体架构
CPU 的一個世紀
Prentice.Hall.Systems.Performance.Aug.2013
Memory Hierarchy
? 硬體提供快的輕薄的假象
? 用在
- CPU Pre-fetch
- Read ahead
- Write buffer
- …
Regs
L1 cache
L2 cache
Mainmemory
Disks
RemoteDisks
快、小、貴
慢、大、便宜
善用現有的硬體架構
? 讓資料待在的最快的地方
- 無所不在的 Cache 和 Buffer
- 加速讀取和寫入
? 雖然有時會採雷
- Cache coherence
- False sharing
- Power lost for Disk buffer
作业系统是敌是友?
作業系統是你的朋友
? 幫忙完成了很多事情
- 抽像硬體
- 調度程序(多工)
- 記憶體管理
- 檔案子系統
- 網路子系統
hardware
OS
Language VM
Framework
Application
Lib
作業系統是你的敵人!?
? 應用程式碰不到硬體
? 應用程式無法獨佔資源
? 通用架構(可能)造成效能不彰
? 多一層就有效能損失 (°?°)
- User space vs. Kernel space
- Context switch
- Data Copy
作業系統是你的朋友也是敵人 (2)
你沒想過的事…
? 了解你的系统
? 让硬体同时动起来
? 善用硬体架构
? 作业系统是敌是友?
? 不要閒置資源:I/O 模型
? 不要浪費資源:Processing 模型
? 聪明的做越少越好
不要閒置資源:
I/O 模型
不要閒置資源
? 重疊計算和 I/O 操作
? 選擇適合的 I/O 模型
- 網路傳輸、讀寫儲存裝置、IPC
? 種類
- 同步阻塞 (Blocking I/O)
- 同步非阻塞 (Non-Blocking I/O)
- 多路復用 (I/O Multiplexing)
- 異步 (Asynchronous I/O)
Blocking I/O
? 當讀寫成功後才返回
? 同時只能做一件事
- 可惜了 CPU 時間
? 簡單好用,但別再用!
http://www.ibm.com/developerworks/library/l-async/
偏要用 Blocking I/O
? 傳統應用常這麼做
- 例如 Apache
? 使用 Multi-Process、Multi-Thread
- 浪費大量資源,特別是記憶體
Non-Blocking I/O
? 讀寫若發生阻塞立即返
回錯誤,由應用程式負
責輪詢系統
? 同時可以做多件事
- 問沒有的時候就可以先處
理別的事情
? 可能會 Busy looping
- 有點煩,通常不單獨用
http://www.ibm.com/developerworks/library/l-async/
I/O Multiplexing
? 應用程式等作業系統通知可以讀寫
? 常見方式
- select
- Linux: epoll
- BSD: kqueue
- Solaris: /dev/poll
- Windows: IOCP
? 閒著沒事就 Block, 有事可以馬上處理
http://www.ibm.com/developerworks/library/l-async/
Asynchronous I/O
? 作業系統幫你讀/寫好,再通知完成了
? 常見方式
- Linux: AIO
- Win: overlapped I/O
- I/O Thread Pool
? 問題
- 不跨平台
http://www.ibm.com/developerworks/library/l-async/
I/O 模型
? 選對了可獲得不錯的 I/O 效能
- 延遲少、平行 I/O
? 選對了會多出一些 CPU 時間可以用
- 不會 block
? AIO (Thread Pool) 通常是標配
不要浪費資源:
Processing 模型
不要浪費資源
? 硬體資源有限
- 通常是記憶體不夠用。如果一個 Thread 8MB stack…
? CPU 核心數限制了真實平行數
- 超過其實只能排隊、Context-switch 可能會暴增
? 選擇適合的 Process 架構
- Single Thread/Process
- Multiple Process
- Multiple Thread, Thread Pool
- Event-Driven
Single Thread/Process
? 最基本的程式運作單位
- 線性簡單好懂,免解釋
? 只能做一件事
? 無法利用多核心
︴
Multiple Process
? 同時執行多個同構或異構的程式
? 優點
- 簡單、容錯、雷少
? 缺點
- 啟動慢
- 占用記憶體高
- Context-switch 代價較高
︴ ︴ ︴ ︴
Multiple Thread
? 在單一 Process 內執行多個 Thread
? 優點
- 較 Process 省記憶體
- 較 Process 啟動快
- 較 Process Context-switch 代價低
- 存取共用資料簡單
? 缺點
- 複雜度高、Dead Lock、Race condition
︴︴︴︴
Thread Pool
? 限制 thread 在固定數量
? 優點
- 記憶體消耗小
- 減少 Context-switch 數量
? 缺點
- 跟 multiple therad 一樣
- 多工效果較差、延遲稍高
︴︴
︴︴
Task
Event-Driven
? 常見作法
- Single Thread + I/O Multiplexing 或 AIO
? 優點
- 單執行緒、沒什麼消耗
- Context-switch 很少
? 缺點
- 無法完整利用硬體
- 一般會有 Callback hell
Event ︴
Handler
Event Loop
Processing 模型
? 選對了可以有不錯的計算效能
- 時間內能做的事情最多
? 選對了可以有不錯的容量
- 節省記憶體
? Event-Driven + Thread Pool 是目前趨勢
More and more
? 人腦就偽雙核心,Multi-Thread 真的很難
? 其他的選擇
- Worker, provider + comsumer
- Golang 的 CPS, Goroutine
- Erlang 的 Actor
- Functional Programming (非常適合平行)
- STM memory
- 包好的 Framework. 例如 Netty
聪明的做越少越好
做的事情越少越好
? 好用的東西都是犧牲 CPU cycle 做出來的
? 或許有些不必要的分層、抽象
- 不要用有 VM 的語言
- 不要用 Active Record
- 不要用 Framework
- 不要用 JSON
- 不要用 HTTP(S)
? 理性勿戰,選擇剛剛好的選項
聰明的做事情
? 設計好工作方式
- 避免當傻蛋油漆工
? 選擇適合的演算法、資料結構
- 這個不用說…大家都有學好吧!
? 請考慮空間 vs. 時間
- 時間有 O(n) 不要用 O(n2)
- 空間有 O(1) 不要用 O(n)
https://en.wikipedia.org/wiki/Road#/media/File:Making_lines_on_the_road.JPG
实例分析
nginx
? nginx is an HTTP and reverse proxy server,
a mail proxy server, and a generic
TCP/UDP proxy server
? Multi-process + 事件驅動 (libevent)
? 跟 OS 做好朋友 (sendfile, mmap)
? 自己做了 cache
? aio thread pool (>=1.7.11)
- Thread Pools in NGINX Boost Performance 9x!
nginx
http://www.aosabook.org/en/nginx.html#fig.nginx.arch
Redis
? Redis is an open source (BSD licensed),
in-memorydata structure store, used as
database, cache and message broker.
? 單執行緒存取、維護資料
? 事件驅動 (aeEventLoop)
? In-memory 儲存資料
? 客製化資料結構
? 背景執行緒,負責持久化
Node.js
? Node.js is a JavaScript runtime uses an
event-driven, non-blocking I/O model that
makes it lightweight and efficient.
? 單執行緒執行 JavaScript V8 engine
? 事件驅動 (libuv)
- Thread pool 負責 I/O, blocking call
结论
心裡記得這三點就夠了
? 了解你的系统
? 把效能放心上
? 聪明的做越少越好
Thank you ?
Q&A
Reference
? http://www.ibm.com/developerworks/library/
l-async/
? https://www.amazon.com/Systems-
Performance-Enterprise-Brendan-
Gregg/dp/0133390098
? http://www.kegel.com/c10k.html
? http://www.gotw.ca/publications/concurrenc
y-ddj.htm
? http://www.brendangregg.com/linuxperf.html
Reference
? https://nginx.org/
? http://redis.io/
? https://nodejs.org/en/
? https://www.nginx.com/blog/thread-pools-
boost-performance-9x/
? https://kernelnewbies.org/Linux_4.5
? http://docs.libuv.org/en/v1.x/
? https://en.wikipedia.org/wiki/Computer_pe
rformance

More Related Content

寫出高性能的服務與應用 那些你沒想過的事