Martin Streicher
(
mstreicher@linux-mag.com
), 主編, Linux Magazine
2007 年 5 月 15 日
“ 為 PHP 應用提速、提速、再提速! ” 系列文章探討了 XCache 和 XDebug,現在將探討 Memcache 守護程序。Memcache 守護程序 (memcached) 是一種高性能分布式對象緩存。memcached 的安裝位置介于應用程序與數據存儲之間,它將把對象保存在 RAM 中。每次緩存命中將替換到數據庫服務器的一次往返,使應用程序運行得更快。<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
本系列文章的前兩篇文章提供了為 PHP 應用程序提速的技術。 第 1 部分 介紹了 XCache,它是把 PHP 操作碼緩存到內存中的 PHP 擴展。XCache 將避免代價高昂且(嚴格來說)不必要的花費來重新編譯相同的 PHP 代碼去交付一個頁面。XCache 是免費的開源軟件,安裝費時不多卻可提供巨大回報。 第 2 部分 介紹了 XDebug,它是配置 PHP 代碼的 PHP 擴展。XDebug 是類似于軟件 x 光照片的內容:它將深入應用程序,揭露內部工作原理,并且揭示代碼如何度過其周期。擁有了 XDebug 度量之后 —— 而不是之前 —— 您可以優化代碼來調整算法、減少瓶頸并減輕過多的內存使用。
注: XCache 適于生產使用。在開發過程中使用 XDebug 最佳,因為其計算負載在活動計算機中是十分浪費的。
這一次,讓我們探究第三種尤為有效的性能增強因素。名為 memcached 的 Memcache 守護程序是一種高性能的分布式對象緩存。memcached 的安裝位置介于應用程序與數據存儲之間,它將把對象保存在 RAM 中。
Memcache PHP 擴展將為訪問緩存提供一個簡單的應用程序接口 (API)。要使用緩存,需要調用 API 來確定先前是否已緩存了對象。如果已經緩存,只需檢索該對象并繼續進行處理。否則,轉至數據庫、獲取必需的數據、將其映射到對象中并把它添加到緩存中。在那里,memcached 將最小化或消除針對您先前處理過的信息的數據庫查詢。
如果 XCache 和 XDebug 是渦輪增壓器,那么 memcached 就是噴氣發動機。請準備好點燃加力燃燒室。
通常,PHP 應用程序中最耗費時間的任務是數據檢索。實際上,用于從存儲庫(文件或數據庫服務器)中獲取信息的時間遠高于編譯并且甚至是執行 PHP 程序所需耗費的時間。連接至數據庫服務器所需的時間是一次延遲,等待查詢完成添加附加停頓,并且結果的傳輸甚至會導致更多延遲。此外,如果代碼使用對象,則有指向對象的導致負擔過重的映射平面行。
MySQL 可以使用其查詢緩存為查詢階段提速。您還可以復制數據庫(一個主數據庫,多個副本),從而在多個 CPU 之間分擔查詢處理的負擔。但是,一旦底層表改變,MySQL 查詢緩存的內容就會過時。而且,僅當一個查詢與先前查詢相同時,查詢緩存才會被命中。副本也有限制。例如,無法分布數據庫寫操作。
從根本上說,雖然查詢緩存和數據庫副本都是有目的的并且在整體工作負載管理策略中占有地位(查詢緩存將消耗一些內存,但是在其他方面卻很節省;副本將把災難停機的風險降至最低),但是連接和傳輸時間不變。
Memcache PHP 擴展將把對象緩存到 RAM 中。每次緩存命中將替換到數據庫服務器的一次往返,使應用程序運行得更快。您很可能會發現 memcached 也(間接地)提高了數據庫服務器的性能;由于 memcached 將用作替代持久性存儲,因此到達數據庫服務器的請求更少,使數據庫服務器可以更高效地響應已收到的查詢。
您可以在一臺或多臺服務器上運行 memcached,并且將在所有節點之間復制緩存的內容。如果服務器出現故障,客戶機 API 軟件將把緩存讀寫操作重新路由到正常運行的備用服務器上。
不同于 XCache,您必須修改代碼才能集成 memcached。不過,如果您已經小心地隔離了一些對象方法內的數據庫訪問代碼,則修改將很可能十分輕微且集中。
Danga Interactive 編寫的 Memcache 守護程序是由 Berkeley Software Distribution (BSD) License 的自由條款許可的免費開源軟件。守護程序應當可以輕松地構建在 UNIX? 和 Linux? 系統上,也可以構建在 Mac OS X 和 Microsoft? Windows? 上。很多 Linux 發行版都提供了 memcached 包;請查看包存儲庫。如果使用 Mac OS X 或 Windows 并且更喜歡便捷的預構建二進制,則可以通過簡單的 Google 搜索在 Web 上找到此類軟件。
![]() ![]() |
![]()
|
讓我們在 Debian Linux 上構建、安裝和部署 memcached。要加速執行過程并允許您獨立于現有 Web 服務器基礎設施來測試 memcached,請使用 XAMPP Apache 發行版作為構建的基礎。XAMPP 十分易于安裝并且包含 Apache V2、MySQL、PHP V4 和 V5、Perl、許多庫和許多 Web 應用程序(例如 phpMyAdmin)。如果從未從頭開始構建 Linux、Apache、MySQL 和 PHP (LAMP) 堆棧,或者如果需要避免與此類努力相關聯的爭辯,則以 XAMPP 開始是十分理想的。
注:
如果您以前通過源代碼構建了 PHP 并保留了文件,則只需把
--enables-memcache
選項添加到配置開關列表中,并且跳過構建 memcached 和 PHP Memcache 擴展以前所示的步驟。
要構建和部署 memcached,您需要 XAMPP 發行版,包括 XAMPP 開發文件、XAMPP 附帶的 PHP 版本的源代碼以及 memcached 的源代碼和 Memcache 的 PHP 擴展。您可以從
XAMPP
下載 XAMPP 二進制和 XAMPP 開發文件(構建附加組件的必備文件)。您還可以使用
wget
快速獲取軟件:
$ wget 'http://www.apachefriends.org/download.php?xampp-linux-1.6.tar.gz' $ wget 'http://www.apachefriends.org/download.php?xampp-linux-devel-1.6.tar.gz' |
前一個 tarball( tarball 是壓縮的 .tar 文件并且通常以后綴 .tar.gz 為結尾)包含二進制;后一個 tarball 包含針對 XAMPP 系統構建代碼所需的題頭文件。
雖然可以把 XAMPP 錨定在文件系統中的任意位置,但是請把壓縮包安裝到 /opt 中。同時把開發文件安裝到 /opt 中。使用 /opt 將使剩下的構建過程變得更輕松。對 tar 使用
-C
選項把文件直接解壓縮到 /opt 中,如下所示:
$ sudo mkdir /opt$ tar xzf xampp-linux-1.6.tar.gz -C /opt$ tar xzf xampp-linux-devel-1.6.tar.gz -C /opt$ ls -CF /opt/lamppRELEASENOTES error/ info/ logs/ phpsqliteadmin/backup/ etc/ lampp* man/ sbin/bin/ htdocs/ lib/ manual/ share/build/ icons/ libexec/ modules/ tmp/cgi-bin/ include/ licenses/ phpmyadmin/ var/ |
接下來,下載并解壓縮 XAMPP 附帶的 PHP 版本的源代碼(XAMPP V1.6 綁定了 PHP V4.4.6);從 PHP.net 下載 PHP V4.4.6 的代碼。
wget
將再次使您可以輕而易舉地完成任務:
$ wget http://us2.php.net/get/php-4.4.6.tar.bz2/from/www.php.net/mirror$ tar xjf php-4.4.6.tar.bz2$ cd php-4.4.6 |
接下來,修改 XAMPP 的 PHP 構建腳本重新構建 PHP 以啟用 Memcache。您可以在 /opt/lampp/share/lampp/configures.tar.gz 中找到原始構建腳本(和其他構建腳本)。使用以下代碼解壓縮 PHP V4 構建腳本:
$ tar xzfv /opt/lampp/share/lampp/configures.tar.gz / php/configure-php4-oswald |
打開 configure-php4-oswald 并添加
--enable-memcache
(如果系統沒有那些數據庫,您還可能發現有必要刪除選項,例如特定于 Oracle 和 PostgreSQL 的那些選項)。清單 2 展示了在測試系統上用于重新構建 PHP 的修改后的腳本。(PHP 構建過程依賴于許多實用程序和開發庫,例如 Flex、Bison、libxml 和 PCRE。您可能需要安裝附加軟件包才能準備好進行這些構建,這取決于 Linux 發行版和 PHP 配置的內容)。
清單 2. 用于重新構建 PHP 的修改后的 XAMPP 腳本
( cd /opt/lampp/bin rm phpize phpextdist php-config php rm -rf /opt/lampp/include/php)make distcleanexport PATH="/opt/lampp/bin:$PATH" export CFLAGS="-O6 -I/opt/lampp/include/libpng / -I/opt/lampp/include/ncurses / -I/opt/lampp/include -L/opt/lampp/lib" ./configure / --prefix=/opt/lampp / --with-apxs2=/opt/lampp/bin/apxs / --with-config-file-path=/opt/lampp/etc / --with-mysql=/opt/lampp / --enable-inline-optimation / --disable-debug / --enable-memcache / --enable-bcmath / --enable-calendar / --enable-ctype / --enable-dbase / --enable-discard-path / --enable-exif / --enable-filepro / --enable-force-cgi-redirect / --enable-ftp / --enable-gd-imgstrttf / --enable-gd-native-ttf / --with-ttf / --enable-magic-quotes / --enable-memory-limit / --enable-shmop / --enable-sigchild / --enable-sysvsem / --enable-sysvshm / --enable-track-vars / --enable-trans-sid / --enable-wddx / --enable-yp / --with-ftp / --with-gdbm=/opt/lampp / --with-jpeg-dir=/opt/lampp / --with-png-dir=/opt/lampp / --with-tiff-dir=/opt/lampp / --with-freetype-dir=/opt/lampp / --without-xpm / --with-zlib=yes / --with-zlib-dir=/opt/lampp / --with-openssl=/opt/lampp / --with-expat-dir=/opt/lampp / --enable-xslt / --with-xslt-sablot=/opt/lampp / --with-dom=/opt/lampp / --with-ldap=/opt/lampp / --with-ncurses=/opt/lampp / --with-gd / --with-imap-dir=/opt/lampp / --with-imap-ssl / --with-imap=/opt/lampp / --with-gettext=/opt/lampp / --with-mssql=/opt/lampp / --with-mysql-sock=/opt/lampp/var/mysql/mysql.sock / --with-mcrypt=/opt/lampp / --with-mhash=/opt/lampp / --enable-sockets / --enable-mbstring=all / --with-curl=/opt/lampp / --enable-mbregex / --enable-zend-multibyte / --enable-exif / --enable-pcntl / --with-mime-magic / --with-iconv make sudo make install exit 1 |
在腳本的末尾,您的 XAMPP 安裝將有一個新的獨立運行的能夠使用 memcache 的 PHP V4 副本。如果需要測試構建,請停止所有正在運行的 Apache 和 MySQL 副本,包括在 XAMPP 外部的那些副本,并且運行以下命令:
$ sudo /opt/lampp/lampp start |
這將啟動 XAMPP 版本的 Apache 和 MySQL,包括新的 PHP V4 模塊。如果需要使 Apache 生產服務器的運行不受干擾,則可以編輯文件 /opt/lampp/etc/httpd.conf 并把
Listen
端口參數改為
8080
(或其他可用端口)。然后您可以用以下命令單獨啟動 XAMPP 的 Apache 服務器:
sudo /opt/lampp/bin/apachectl start |
把瀏覽器指向 http://localhost,然后您應當會看到類似于圖 1 的內容。
圖 1. XAMPP for Linux 初始頁面:檢驗 XAMPP 和 PHP 是否已成功安裝
要檢驗您的 PHP 構建是否已安裝,請單擊左側的
phpinfo()
鏈接。您應當會看到類似圖 2 中所示的統計信息。PHP 的版本應當是 4.4.6,構建選項應當包括
--enable-memcache
,并且 php.ini 的工作版本應當駐留在 /opt/lampp/lib 中。
圖 2. 檢驗 PHP 的自定義構建是否替換了 XAMPP 附帶的 PHP 構建
![]() ![]() |
![]()
|
新的 PHP 就緒后,下一步是構建和安裝 PHP Memcache 擴展。該擴展將提供訪問 Memcache 守護程序的服務所需的 API。
首先將檢索 Memcache 擴展的源代碼。您可以再次使用
wget
來獲得源代碼,請使用以下命令:
$ wget http://pecl.php.net/get/memcache-2.1.0.tgz |
構建 Memcache 擴展的過程與構建其他 PHP 擴展的過程完全相同:
- 切換到源代碼的目錄
-
運行
phpize
,后接./configure
、make
和make install
。 -
確保使用新版本的
phpize
。 -
把 /opt/lampp/bin 放到 shell 的 PATH 中,位于包含其他版本的
phpize
的所有目錄之前:
$ cd memcache-2.1.0$ export PATH=/opt/lampp/bin:$PATH$ phpize$ ./configure$ make...$ sudo make installInstalling shared extensions: /opt/lampp/lib/php/extensions/no-debug-non-zts-20020429/
構建將把一個名為 memcache.so 的新文件放入擴展目錄。要加載并應用擴展,您必須編輯 php.ini。打開 XAMPP PHP 配置文件 /opt/lampp/etc/php.ini 并添加清單 3 中的代碼行。
extension=memcache.somemcache.allow_failover = 1 memcache.max_failover_attempts=20 memcache.chunk_size =8192 memcache.default_port = 11211 |
第 1 行將加載 Memcache 擴展。其他四行是用于控制擴展的參數。按順序,從頂部到底部:
memcache.allow_failover
1
(true)。
memcache.max_failover_attempts
memcache.allow_failover
為 false,則將忽略此參數。默認值為
20
。
memcache.chunk_size
8192
字節 (8 KB),但是如果設置為
32768
(32 KB),則可以獲得更好的性能。
memcache.default_port
11211
。
要確定構建現在是否能夠完全運行,請使用以下命令重新啟動 XAMPP Apache Web 服務器:
$ sudo /opt/lampp/bin/apachectl restart |
如果重新訪問 XAMPP
phpinfo()
頁面,您應當會看到類似圖 3 中的 Memcache 部分。
圖 3. 通過 phpinfo() 查看 Memcache 設置
![]() ![]() |
![]()
|
此過程(表面上有些冗長)還有一個額外的步驟:構建和部署為數據管理 RAM 緩存的 Memcache 守護程序。守護程序依賴于 libevent,因此必須構建和部署該庫,然后再編譯 memcached:
$ wget http://www.monkey.org/~provos/libevent-1.3b.tar.gz$ wget http://www.danga.com/memcached/dist/memcached-1.2.1.tar.gz |
接下來,解壓縮 tarball 來為每個包生成一個目錄:
$ tar xzf memcached-1.2.1.tar.gz $ tar xzf libevent-1.3b.tar.gz |
要繼續執行操作,請依次構建每個包,從庫開始。要使所有文件包含在 /opt 中,請在運行配置時使用
--prefix
選項。下面的指令將構建和安裝 libevent。
$ cd ../libevent-1.3b$ ./configure --prefix=/opt/lampp...$ make$ sudo make install.../usr/bin/install -c .libs/libevent.lai /opt/lampp/lib/libevent.la/usr/bin/install -c .libs/libevent.a /opt/lampp/lib/libevent.achmod 644 /opt/lampp/lib/libevent.aranlib /opt/lampp/lib/libevent.aPATH="$PATH:/sbin" ldconfig -n /opt/lampp/lib----------------------------------------------------------------------Libraries have been installed in: /opt/lampp/lib |
接下來的命令將構建和安裝 memcached 二進制。
$ cd ../memcached-1.2.1$ ./configure --prefix=/opt/lampp...$ make$ sudo make install.../usr/bin/install -c memcached /opt/lampp/bin/memcached/usr/bin/install -c memcached-debug /opt/lampp/bin/memcached-debug |
啟動 memcached 十分簡單:
./memcached -d -m 2048 -l ip-address -p 11211 |
-d
選項將把 memcached 作為一個守護程序而不是在最顯著的位置中運行。
-m
number
將把
number
兆字節分配給此過程實例。(在某些系統中,可能會要求您運行多個 memcached 實例以訪問可用于進行緩存的所有內存。有關更多信息,請參閱 Memcache 文檔)。
-l
ip-address
-p 11211
將使守護程序分別偵聽 IP 地址
ip-address
和端口
11211
。替換您的 IP 地址。如果為 memcached 選擇其他端口,請確保 php.ini 將反映該端口。
![]() ![]() |
![]()
|
安裝后,就可以讓 Memcache 運行了。
Memcache 通常用于存儲對象,但是它可以存儲可序列化的任何 PHP 變量,例如字符串。Memcache 有一個面向過程和一個面向對象的 API。不管您使用哪一個變量,您必須提供四個實參才能把變量存儲到緩存中:
0
,則該條目永遠不會在緩存中過期。使用 Memcache API
delete()
函數刪除這樣一個永久對象。
下面的代碼將使用面向對象的 Memcache 擴展 API 來創建、存儲和檢索一個簡單對象。
<?phpclass myCache extends Memcache { function getInstance() { static $instance; if ( ! isset( $instance )) { $instance = new Memcache; $instance->connect( '198.168.0.1' ); } return $instance; } function close( ) { if ( isset( $instance ) ) { $instance->close(); $instance = null; } }}class myDatum { var $values = array( 'description' => null, 'price' => null, 'weight' => null ); function myDatum( $settings ) { foreach ( $settings as $key => $value ) { if ( ! array_key_exists( $key, $this->values ) ) { die( "Unknown attribute: $key" ); } $this->values{ $key } = $value; } } function set( $key=null, $value=null ) { if ( is_null( $key ) ) { die( "Key cannot be null" ); } if ( ! array_key_exists( $key, $this->values ) ) { die( "Unknown attribute: $key" ); } if ( ! is_null( $value ) ) { $this->values{ $key } = $value; } return( $this->values{ $key } ); } function get( $key=null ) { return( $this->set( $key, null ) ); }}$datum = new myDatum( array( 'description' => 'ball', 'price' => 1.50, 'weight' => 10 ) );print $datum->get( 'description' ) . "/n";$cache = myCache::getInstance( );if ( $cache->set( $datum->get( 'description' ), $datum, false, 600 ) ) { print( 'Object added to cache' . "/n"); }$cache->close();$new_cache = myCache::getInstance( );$new_datum = $new_cache->get( $datum->get( 'description' ) );if ( $new_datum !== false ) { print( 'Object retrieved from cache' . "/n"); print $new_datum->get( 'description' ) . "/n";}print_r( $new_cache->getExtendedStats() );$new_cache->close();?> |
myCache
類是單件并提供指向緩存的單獨的開放連接。
myDatum
類代表了所有對象:它有一系列屬性(實現為散列),以及一個 getter 和一個 setter 方法。要創建
myDatum
對象,請把一個值散列傳遞給其構造函數。要設定屬性,請調用帶有屬性名的
set()
作為字符串和值。要獲得屬性,請調用帶有屬性名的
get()
。
以上代碼中的最后幾行將創建對象、把對象存儲到緩存中并檢索對象。Memcache API 的倒數第二行、部分將顯示緩存的統計信息。如果使用新的 PHP 命令行解釋程序運行清單 6,則應當會看到類似清單 7 所示的內容。
ballObject added to cacheObject retrieved from cacheballArray( [72.51.41.164:11211] => Array ( [pid] => 865 [uptime] => 3812845 [time] => 1173817644 [version] => 1.1.12 [rusage_user] => 0.043993 [rusage_system] => 0.038994 [curr_items] => 1 [total_items] => 5 [bytes] => 145 [curr_connections] => 1 [total_connections] => 8 [connection_structures] => 3 [cmd_get] => 5 [cmd_set] => 5 [get_hits] => 5 [get_misses] => 0 [bytes_read] => 683 [bytes_written] => 1098 [limit_maxbytes] => 67108864 )) |
十分簡單,不是?如果
myDatum
的構造函數是典型的,則它將很可能被給定一個 ID 并將查詢數據庫以生成特定行(例如,查找社會安全號碼為 123-45-6789 的學生)。您可以擴展構造函數以便在緩存中首先查找 ID。如果找到,則只需返回該對象。否則,構造對象,緩存并返回該對象。
如果有一組 Debian Linux 系統,則可以復制或導出(通過 NFS)/opt/lampp 并在多個系統中運行 memcached。在兩臺或多臺計算機中同時運行 memcached 將刪除單點故障并擴展緩存的容量。使用
addServer()
API 函數來構建一列可用的 memcached 服務器。
![]() ![]() |
![]()
|
使用 Memcache PHP API 十分簡單,并且 memcached 十分易于部署。可能大部分工作就是(重新)構建 PHP 本身以包括適當的擴展。的確,如果用于構造對象的方法已被良好隔離,則修改代碼以利用 Memcache 應當是小事一樁。
正如您已經看到的,一些簡單的技術和一點點時間和努力就可以提高 PHP 應用程序性能。在購買更多 RAM 或另一臺服務器之前,請先嘗試調整現有服務器。那樣做更便宜!
學習
-
您可以參閱本文在 developerWorks 全球站點上的
英文原文
。
-
閱讀本系列的
第 1 部分
和
第 2 部分
。
-
PHP.net
是面向 PHP 開發人員的資源網站。
-
查閱 “
PHP 推薦讀物列表
”。
-
瀏覽 developerWorks 上的所有
PHP 文章
和
PHP 教程
。
-
查閱 IBM developerWorks 的
PHP 項目資源
提高 PHP 技巧。
-
要收聽針對軟件開發人員的有趣訪談和討論,訪問 developerWorks 的
podcast
。
-
隨時關注 developerWorks 的
技術事件和網絡廣播
。
-
要將數據庫與 PHP 結合使用?查看
Zend Core for IBM
,它是支持 IBM DB2 9 的無縫、即用且易于安裝的 PHP 開發和生產環境。
-
查閱最近將在全球舉辦的面向 IBM 開放源碼開發人員的研討會、展覽、網絡廣播和其他
活動
。
-
訪問 developerWorks
開源軟件技術專區
,獲得豐富的 how-to 信息、工具和項目更新,幫助您用開放源碼技術進行開發,并與 IBM 產品結合使用。
獲得產品和技術
-
下載
XAMPP
。
-
獲得
Memcache 擴展的源代碼
。
-
下載
PHP 源代碼
。
-
下載
Memcache 守護程序
。
-
使用
IBM 試用軟件
構建您的下一個開發項目,這些軟件可以通過下載或從 DVD 中獲得。
討論
-
通過參與
developerWorks blog
加入 developerWorks 社區。
- 參與 developerWorks PHP 論壇:用 IBM Information Management 產品 (DB2, IDS) 開發 PHP 應用程序 。
![]() |
||
|
![]() |
Martin Streicher 是 Linux Magazine 的主編。他從普度大學獲得了計算機科學碩士學位,從 1982 年開始用 Pascal、C、Perl、Java 和(最近)Ruby 編程語言編寫類 UNIX 的系統。 |
From: http://www.ibm.com/developerworks/cn/opensource/os-php-fastapps3/index.html
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
