【swoole快速入門11】多程序共享資料
阿新 • • 發佈:2018-12-10
由於PHP
語言不支援多執行緒,因此Swoole
使用多程序模式。在多程序模式下存在程序記憶體隔離,在工作程序內修改global
全域性變數和超全域性變數時,在其他程序是無效的。
程序隔離
$fds = array();
$server->on('connect', function ($server, $fd){
echo "connection open: {$fd}\n";
global $fds;
$fds[] = $fd;
var_dump($fds);
});
$fds
雖然是全域性變數,但只在當前的程序內有效。Swoole
伺服器底層會建立多個Worker
var_dump($fds)
打印出來的值,只有部分連線的fd
。
對應的解決方案就是使用外部儲存服務:
- 資料庫,如:
MySQL
、MongoDB
- 快取伺服器,如:
Redis
、Memcache
- 磁碟檔案,多程序併發讀寫時需要加鎖
普通的資料庫和磁碟檔案操作,存在較多IO
等待時間。因此推薦使用:
Redis
記憶體資料庫,讀寫速度非常快/dev/shm
記憶體檔案系統,讀寫操作全部在記憶體中完成,無IO
消耗,效能極高
除了使用儲存之外,還可以使用共享記憶體來儲存資料
共享記憶體
PHP
提供了多套共享記憶體的擴充套件,但實際上真正在實際專案中可用的並不多。
shm 擴充套件
提供了shm_put_var
shm_get_var
共享記憶體讀寫方法。但其底層實現使用連結串列結構,在儲存大量數值時時間複雜度為O(N)
,效能非常差。並且讀寫資料沒有加鎖,存在資料同步問題,需要使用者自行加鎖。
不推薦使用
shmop 擴充套件
提供了shmop_read
/shmop_write
共享記憶體讀寫方法。僅提供了基礎的共享記憶體操作指令,並未提供資料結構和封裝。不適合普通開發者使用。
不推薦使用
apcu 擴充套件
提供了apc_fetch
/apc_store
可以使用Key-Value
方式訪問。APC
擴充套件總體上是可以用於實際專案的,缺點是鎖的粒度較粗,在大量併發讀寫操作時鎖的碰撞較為密集。
yac
擴充套件,不適合用於儲存資料,其設計原理導致存在一定的資料miss
率,僅作為快取,不可作為儲存
swoole_table
Swoole
官方提供的共享記憶體讀寫工具,提供了Key-Value
操作方式,使用非常簡單。底層使用自旋鎖實現,在大量併發讀寫操作時效能依然非常強勁。推薦使用。swoole_table
仍然存在一個兩個缺點,使用時需要根據實際情況來選擇。
- 提前申請記憶體,
swoole_table
在使用前就需要分配好記憶體,可能會佔用較多記憶體 - 無法動態擴容,
swoole_table
記憶體管理是靜態的,不支援動態申請新記憶體,因此一個Table
在設定為N
行之後,不能超過限制