PHP分布式記憶體共用(Memcache)
分布式記憶體共用。目前在PHP領域中能夠做到分布式記憶體共用的只有Memcache。
1.memcached詳細介紹。
引用
通常的網頁緩衝方式有動態緩衝和靜態緩衝等幾種,在ASP.NET中已經可以實現對頁面局部進行緩衝,而使用memcached的緩衝比 ASP.NET的局部緩衝更加靈活,可以緩衝任意的對象,不管是否在頁面上輸出。而memcached最大的優點是可以分布式的部署,這對於大規模應用來 說也是必不可少的要求。
LiveJournal.com使用了memcached在前端進行緩衝,取得了良好的效果,而像wikipedia,sourceforge等也採用了或即將採用memcached作為緩衝工具。memcached可以大規模網站應用程式發揮巨大的作用。
Memcached是什麼?
Memcached是高效能的,分布式的記憶體對象緩衝系統,用於在Live App中減少資料庫負載,提升訪問速度。
Memcached由Danga Interactive開發,用於提升LiveJournal.com訪問速度的。LJ每秒動態網頁面訪問量幾千次,使用者700萬。Memcached將資料庫負載大幅度降低,更好的分配資源,更快速存取。
如何使用memcached-Server端?
在服務端運行:
# ./memcached -d -m 2048 -l 10.0.0.40 -p 11211
這將會啟動一個佔用2G記憶體的進程,並開啟11211連接埠用於接收請求。由於32位系統只能處理4G記憶體的定址,所以在大於4G記憶體使用量PAE的32位伺服器上可以運行2-3個進程,並在不同連接埠進行監聽。
如何使用memcached-Client端?
在應用端包含一個用於描述Client的Class後,就可以直接使用,非常簡單。
PHP Example:
$options["servers"] = array("192.168.1.41:11211", "192.168.1.42:11212");
$options["debug"] = false;
$memc = new MemCachedClient($options);
$myarr = array("one","two", 3);
$memc->set("key_one", $myarr);
$val = $memc->get("key_one");
print $val[0]."\n"; // prints 'one‘
print $val[1]."\n"; // prints 'two‘
print $val[2]."\n"; // prints 3
為什麼不使用資料庫做這些?
暫且不考慮使用什麼樣的資料庫(MS-SQL, Oracle, Postgres, MysQL-InnoDB, etc..), 實現事務(ACID,Atomicity, Consistency, Isolation, and Durability )需要大量開銷,特別當使用到硬碟的時候,這就意味著查詢可能會阻塞。當使用不包含事務的資料庫(例如Mysql-MyISAM),上面的開銷不存在,但 讀線程又可能會被寫線程阻塞。
Memcached從不阻塞,速度非常快。
為什麼不使用共用記憶體?
最初的緩衝做法是線上程內對對象進行緩衝,但這樣進程間就無法共用快取,命中率非常低,導致緩衝效率極低。後來出現了共用記憶體的緩衝,多個進程或者線程共用同一塊緩衝,但畢竟還是只能局限在一台機器上,多台機器做相同的緩衝同樣是一種資源的浪費,而且命中率也比較低。
Memcached Server和Clients共同工作,實現跨伺服器分布式的全域的緩衝。並且可以與Web Server共同工作,Web Server對CPU要求高,對記憶體要求低,Memcached Server對CPU要求低,對記憶體要求高,所以可以搭配使用。
Mysql 4.x的緩衝怎麼樣?
Mysql查詢快取不是很理想,因為以下幾點:
當指定的表發生更新後,查詢快取會被清空。在一個大負載的系統上這樣的事情發生的非常頻繁,導致查詢快取效率非常低,有的情況下甚至還不如不開,因為它對cache的管理還是會有開銷。
在32位機器上,Mysql對記憶體的操作還是被限制在4G以內,但memcached可以分布開,記憶體規模理論上不受限制。
Mysql上的是查詢快取,而不是對象緩衝,如果在查詢後還需要大量其它操作,查詢快取就幫不上忙了。
如果要緩衝的資料不大,並且查詢的不是非常頻繁,這樣的情況下可以用MySQL 查詢緩衝,不然的話memcached更好。
資料庫同步怎麼樣?
這裡的資料庫同步是指的類似Mysql Master-Slave模式的靠日誌同步實現資料庫同步的機制。
你可以分布讀操作,但無法分布寫操作,但寫操作的同步需要消耗大量的資源,而且這個開銷是隨著slave伺服器的增長而不斷增長的。
下一步是要對資料庫進行水平切分,從而讓不同的資料分布到不同的資料庫伺服器組上,從而實現分布的讀寫,這需要在應用中實現根據不同的資料連線不同的資料庫。
當這一模式工作後(我們也推薦這樣做),更多的資料庫導致更多的讓人頭疼的硬體錯誤。
Memcached可以有效降低對資料庫的訪問,讓資料庫用主要的精力來做不頻繁的寫操作,而這是資料庫自己控制的,很少會自己阻塞 自己。
Memcached快嗎?
非常快,它使用libevent,可以應付任意數量開啟的串連(使用epoll,而非poll),使用非阻塞網路IO,分布式散列對象到不同的伺服器,查詢複雜度是O(1)。(於敦德)
參考資料:
Distributed Caching with Memcached | Linux Journal
http://www.danga.com/
http://www.linuxjournal.com/article/7451
2.memcached在freebsd下的安裝:
引用
步驟1:安裝memcached
代碼:
# cd /usr/ports/databases/memcached/
# make install
步驟2:啟動memcached
代碼:
#/usr/bin/memcached -d -m 128 -l 192.168.1.1 -p 11211 -u httpd
參數解釋:
-d 以精靈(daemon)方式運行 memcached;
-m 設定 memcached 可以使用的記憶體大小,單位為 M;
-l 設定監聽的 IP 位址,如果是原生話,通常可以不設定此參數;
-p 設定監聽的連接埠,預設為 11211,所以也可以不設定此參數;
-u 指定使用者,如果當前為 root 的話,需要使用此參數指定使用者。
以上以完成了memcached的安裝及啟動!
使用時按要求填上IP與連接埠既可
3.memcached 的工作原理
首先 memcached 是以精靈方式運行於一個或多個伺服器中,隨時接受用戶端的串連操作,用戶端可以由各種語言編寫,目前已知的用戶端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等用戶端在與 memcached 服務建立串連之後,接下來的事情就是存取對象了,每個被存取的對象都有一個唯一的標識符 key,存取操作均通過這個 key 進行,儲存到 memcached 中的對象實際上是放置記憶體中的,並不是儲存在 cache 檔案中的,這也是為什麼 memcached 能夠如此高效快速的原因。注意,這些對象並不是持久的,服務停止之後,裡邊的資料就會丟失。
?
?
?
?
?
?
?
4.安裝php對memcache支援模組
有兩種方法可以使 PHP 作為 memcached 用戶端,調用 memcached 的服務進行對象存取操作。
第一種,PHP 有一個叫做 memcache 的擴充,Linux 下編譯時間需要帶上 –enable-memcache[=DIR] 選項,Window 下則在 php.ini 中去掉 php_memcache.dll 前邊的注釋符,使其可用。
http://pecl.php.net/package/memcache
除此之外,還有一種方法,可以避開擴充、重新編譯所帶來的麻煩,那就是直接使用 php-memcached-client。
http://nio.infor96.com/wp-content/uploads/2006/04/memcached-client.zip
本文選用第二種方式,雖然效率會比擴充庫稍差一些,但問題不大。