77
寫出高性能的服務與應用 那些你沒想過的事! I’m 小傑 COSCUP 2016

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

Embed Size (px)

Citation preview

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

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-switchJIT

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/concurrency-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

Main memory

Disks

Remote Disks

快、小、貴

慢、大、便宜

善用現有的硬體架構

• 讓資料待在的最快的地方

- 無所不在的 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/concurrency-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_performance