Software engineering notes

I/O

測試 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

blocking I/O:

Serve one client with each thread/process

優點:

缺點:

apache 的 prefork 或 worker MPM

non-blocking I/O :

改良 blocking I/O 缺點, 使用 event-driven 讓整支程式在事件發生時才做事

Asynchronous I/O

一個 thread 處埋多個連線, 同樣具有 non-blocking 特性, 使用者不需自已檢查事件是否完成, 而是系統主動通知, 使用者收到再做動作

優點:

缺點:

Nginx, memcached, node.js

要處理大量連線還是得用 Asynchronous I/O

libevent

優點 :

ref: http://ricky.ez2.us/

OpenResty 介紹

這是在一次技術活動聽 Pahud 大神推薦的 web server 時做的筆記,

它可大幅度提升 server 的反應速度, 尤其是對 php 這種 request / per process 的語言

先介紹各 web server 的特點

Apache

缺點 : 阻塞

Nginx

優點 : 非阻塞

運作流程 : Master process 將 resque 丟給 worker, worker 再丟到 Task Queue 執行

假如 php 跑在 nginx 上, 仍會阻塞, 因為 php 是線性一個一個撈取 (拿留言版 -> 再拿心情帖 -> 再拿大頭貼)

OpenResty (ngx_openresty)

先來講 Lua 帶來的好處

運作流程 : 由 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 真實流量