如果你需要建置一個可以服務幾萬個連線的Server程式,想像資料庫吧!!
資料庫config裡面,可以透過 shared memory connection 以及 socket connection ,
socket connection 資料庫僅僅只有一個 port number , 但是它可以有多個 processes 來服務多個 fd ,
他是透過 unix domain 將 listen 到的 fd pass 給處理的 process 之一 , google "pass fd through unix domain"
可以知道其原理 ...以下網頁講的也夠詳細 :
http://www.sourcexr.com/articles/2013/10/14/passing-descriptors-between-processes
假設你有十支程式 server pools ,當你的連線有一萬個,你可以透過此方式將一萬分散給這十支程式,
每一支程式服務一千個連線,這時,你可以用一千個 threads來運作,但是這其實速度,resource有風險 ,
另一個做法是,每一個 fd 都是透過 結構 來處理 , 運用 多個 threads 來追蹤每個 fd 所在的結構 ,
就可以知道 每個 fd 目前是等待甚麼 job ? 還是等待 user 的指令 ? 資料庫將這個 fd 包裝在 session 結構裡 ,
每個 session 含有 fd 以及所有該 fd 的 job , 包括 fd 來自哪個 ip , 該 fd 的 pid, 該 session 正在等甚麼 resource ?
然後資料庫可以有多個 thread pools 來服務所有 sessions , 這是資料庫做法,有彈性,速度快,且可以服務非常多的 sessions !!!
使用 libevent 可以有效地做到 non-blocking socket read/write event , 再加上使用 lock-free MPMC queue 在 thread pools,
threads 使用 Lightweight Auto-Reset Event Object 來溝通 :
http://preshing.com/20150316/semaphores-are-surprisingly-versatile/
速度不只飛快 , 架構更是簡單 !!!!
以 行情撥放 的 程式為例 , Server pools 將新行情送給訂閱的 clients , 可以利用 shared memory 將所有
行情結構建置其中 , 使用 lock-free hash object 可以在千萬分之一秒就可找到每一檔股票在該 shared memory 的位子 ,
透過 Lightweight Auto-Reset Event Object 通知 server pools 新行情異動 , server pools 程式
使用 sequential lock 方式讀取行情 , 不僅比 read/write lock 快 ,而且絲毫不會影響 write shared memory
那支程式的速度 !!!! conflict 發生機率以台股來說 , 你可能幾十萬次都遇不到一次 !!!!!
運用這些 tools , 架構 , 我想 就算有上萬個 clients , 硬體配備不錯的環境在行情變動時 千分之一內應該就能送出該新行情 ,
因為所有的動作都是 lock-free , 除了網路的頻寬 , 一支程式 處理一千個 fd 跟一個 fd 差別最大的只在於 send
system call 多寡而已 , 既然你可以很方便將 server pools 做擴充 , 那麼 硬體 resource 可以支撐的話 ,
看不出來它沒理由不能處理 十萬個連線 , 而且 收行情的速度也能很快 !!!!
重點在架構中 , server to server lock free , thread to thread lock free , 既然所有的 server/thread 溝通都是 lock free ,
那麼 它能運作很快 就是意料之中的事了 !!
留言列表