測試 filesystem 讀寫速度
dd 只能測試寫入速度
$ dd if=/dev/zero of=/tmp/output conv=fdatasync bs=384k count=1k; rm -f /tmp/output
1024+0 records in
1024+0 records out
402653184 bytes (403 MB, 384 MiB) copied, 2.07614 s, 194 MB/s
or
$ sync ; time sh -c "dd if=/dev/zero of=/tmp/output bs=100k count=1k && sync" ; rm /tmp/output
1024+0 records in
1024+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0646765 s, 1.6 GB/s
real 0m0.296s
user 0m0.005s
sys 0m0.065s
hdparm 測試讀寫速度
$ sudo hdparm -Tt /dev/nvme0n1p1
/dev/nvme0n1p1:
Timing cached reads: 12588 MB in 2.00 seconds = 6308.45 MB/sec
Timing buffered disk reads: 514 MB in 3.01 seconds = 170.53 MB/sec
Server 效能調校
快速設定最多開啟 file 的數量
/etc/security/limits.conf
最後增加
* soft nofile 65535
* hard nofile 65535
可以再用 ulimit
指令查詢
/etc/pam.d/login
加上
session required pam_limits.so
/etc/sysctl.conf
fs.file-max = 100000
net.core.somaxconn = 2048
修改完後執行 sudo sysctl -p
使設定值生效
TCP 參數細節
/etc/sysctl.conf
# 調高系統的 IP 及 Port 限制,可以接受更多的連接 32768 61000
net.ipv4.ip_local_port_range = 32768 65000
net.ipv4.tcp_window_scaling = 1
# 調高 socket 監聽的數值
net.core.somaxconn = 65535
net.ipv4.tcp_max_tw_buckets = 1440000
# Increase TCP buffer sizes
# 調大 TCP 儲存大小
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_congestion_control = cubic
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
fs.file-max = 65000
ref : http://blog.didibird.com/2016/05/24/the-way-of-turning-the-best-performance-for-nginx/
PHPConf I/O
之前參加 PHPConf Ricky 講者發表的一個主題裡談到 I/O 架構, 然候我再以它的投影片為基礎做的一個小整理
這篇適合簡單及快速了解 I/O 架構的基本介紹, 沒辦法提供專業的教學說明。
C10K Problem
- 解決通訊問題, server 端有問題要解決, 因為要即時通知 client, server 勢必得保持大量連線
- 1990 提出, 當連線數到達 10K 時, 一些設計不良的架構會遭遇到效能問題, 無法通過提升硬體來解決, 是操作系統固有問題
- 假設 server 最高支撐 1000 個連線, 儘管硬體升級一倍也無法支援 2000 個連線
blocking I/O:
Serve one client with each thread/process
優點:
- 設計容易
- 容易實現複雜的邏輯
- CPU 資源可充份運用
缺點:
- 每個 thread / process 都得佔用一份記億體
- 當連線爆增容易拖垮效能, 並且產生阻塞(block)情形
apache 的 prefork 或 worker MPM
non-blocking I/O :
改良 blocking I/O 缺點, 使用 event-driven 讓整支程式在事件發生時才做事
Asynchronous I/O
一個 thread 處埋多個連線, 同樣具有 non-blocking 特性, 使用者不需自已檢查事件是否完成, 而是系統主動通知, 使用者收到再做動作
優點:
- 節省記憶體(不管連線數都只會佔用一份記憶體)
- 反應速度快(不用重複產生 process)
- 事件驅動
缺點:
- Blocked API 也可能導致其他連線也被 block
Nginx, memcached, node.js
要處理大量連線還是得用 Asynchronous I/O
- 實現 Asynchronous I/O 一般採用 select 及 poll 兩個系統函式
- 在處理大量連線效能會隨連線數遞減
libevent
- 非同步事件處理的函式庫, 提供 API 使某些事生發生時執行函式, 因此易於移植, 擴展性佳
- 可以用來取代網路伺服器所使用的事件循環檢查框架
優點 :
- 解決 3 個平台不能移植問題
- 反應速度快能應付大量連線
- 省資源
ref:
http://ricky.ez2.us/
OpenResty 介紹
這是在一次技術活動聽 Pahud 大神推薦的 web server 時做的筆記,
它可大幅度提升 server 的反應速度, 尤其是對 php 這種 request / per process 的語言
先介紹各 web server 的特點
Apache
- select 網路 I/O 模型, 處理大量連續的讀寫效率低
- process / perconnection
- 1~2 G Ram 同時服務幾百人
缺點 : 阻塞
Nginx
- epoll 網路 I/O 模型, 高併發下效能好
- 佔用更少的 Ram
- 請求非同步
優點 : 非阻塞
運作流程 : Master process 將 resque 丟給 worker, worker 再丟到 Task Queue 執行
- Single process / thread - 利用 coroutine 達到多工
- worker 數量 = cpu core 數量
假如 php 跑在 nginx 上, 仍會阻塞, 因為 php 是線性一個一個撈取 (拿留言版 -> 再拿心情帖 -> 再拿大頭貼)
OpenResty (ngx_openresty)
- 不是新的 web server
- 不是 nginx fork, 可跟上最新的 nginx 核心
- 打包標準 nginx 核心及常用的第三方模組
- 可處理極高並發請求的高性能 web 應用
- 無縫結合 Lua, 可在 nginx 執行 lua script
先來講 Lua 帶來的好處
- Multiple concurrent subrequests in Lua
- Shared-memory dictionary API in Lua
- The socket API is implemented atop Lua conroutines and is synchronous and non-blocking
運作流程 : 由 openresty 來伴演 Frondend API, 將每個 API request 拆成 subrequest 再並行發送到 sub API
詳細實現原理 :
每個 worker 是一個 process, 單執行緒處理多個連線, 可想像成一個 node.js
Worker 會跑 Lua VM, 使用 coroutine 方式處理連線, 一個連線就是一個 coroutine,
如果要做其他的 network I/O 等等動作, 會把控制權交給 Lua VM, 再交由其他 coroutine 去做, 做完後再把控制權交回
即使是線性的 php 也可以達到完全非阻塞
四核 16G Ram 可達到 60,000 req/s 真實流量