大流量網站常見架構:「以記憶體當資料庫(Memcached 叢集)+ MySQL 主從複寫實現讀寫分離」。本文提供一套 PHP 5 實戰封裝類別,展示如何在程式碼層面落地此架構。
cn_、en_ 前綴),靈活控制資料分佈,而非依賴一致性雜湊自動分配。config.php:集中管理 Memcached 叢集與 MySQL 主從連線參數。class Memcached:封裝連線、set/get、依鍵值前綴路由到指定節點、支援長連線(pconnect)。class MySQL:封裝 mysqli,建構子自動建立 Master/Slave 連線,mquery() 寫主庫、squery()/fetArray() 讀從庫,Slave 以 Session 輪詢實現簡易負載均衡。init.php / 使用範例:示範「寫入 -> 查詢 -> 存快取」完整流程,含 SQL 產生 MD5 作為快取鍵。private function tag($ser_key) {
$tag = explode('_', $ser_key);
return $tag[0]; // 取前綴 'cn' 或 'en' 決定節點
}
public function set($ser_key, $values, $flag='', $expire='') {
$this->memConnect($this->tag($ser_key));
return $this->mem->set($ser_key, $values, $flag, $expire);
}
呼叫端:$mem->set('en_'.$key, $data); 明確指定存入 en 節點。
private function autotranscat($mysql) {
session_start();
$_SESSION['SID'] = ($_SESSION['SID'] ?? 0) + 1;
if ($_SESSION['SID'] >= count($mysql) - 1) $_SESSION['SID'] = 1;
$key = 'slave_'.$_SESSION['SID'];
return new mysqli($mysql[$key][0], $mysql[$key][1], $mysql[$key][2], $mysql[$key][3]);
}
public function mquery($sql) { return $this->mysqlmaster->query($sql); } // 寫主
public function squery($sql) { return $this->mysqlslave->query($sql); } // 讀從
$sql = "INSERT INTO mybb(pid) VALUES(200)";
$mdsql = md5($sql);
if (!$result = $mem->get('cn_'.$mdsql)) {
$sq->mquery($sql); // 1. 寫入 Master
$result = $sq->fetArray("SELECT * FROM mybb"); // 2. 從 Slave 讀取驗證
$mem->set('cn_'.$mdsql, $result); // 3. 回填 Memcached (cn 節點)
}
foreach ($result as $var) echo $var['pid'];
Seconds_Behind_Master,延遲過大則強制讀主庫或降級提示。mysqli 長連線或 Swoole/Workerman 協程池,並加入指數退避重試。