PHP實現共用高速記憶體資料池(非MYSQL資料庫) – 類似asp的application

來源:互聯網
上載者:User

     為什麼要實現這個共用記憶體池呢?
    因為PHP每一次請求,伺服器調用一次PHP.EXE程式進行PHP檔案的解析.之後該程式就會被關閉.所以不存在共用記憶體機制.懂asp的朋友應該知道,在asp內共用記憶體緩衝可以使用application,但是php內沒有,所以我們就研究一下讓php也具備該能力.
     這共用記憶體池有什麼用呢?
做webgame的時候,最簡單的功能聊天,這是需要所有使用者共用的資料,一般的處理方法是寫文本,或者寫資料庫,這樣的效率很低,因為PHP程式,有80%的時候是等待資料庫返回資料,對於使用者的即時性要求相對高的聊天程式,就不能去這樣佔用MYSQL的資料庫時間了,這些資料資料不需要永久儲存,但是需要緩衝,所以這個時候高速共用記憶體的作用就出來了.

php有兩套使用共用記憶體的函數,一套是System V IPC函數的封裝,另一套是shmop。
這兩個都無需安裝外部庫檔案。
前者只能在linux下使用,而且要使用它的話,在安裝php的時候要加上–enable-sysvshm選項;
而後者在linux和windows(win2k之後的系統,win98不支援)都可以使用,但在windows的時候,只有在php是ISAPI運行模式才能正常工作,在安裝php的時候要加上–enable-shmop。

這兩套函數的使用相當簡單,下面分別給出簡單的用法,更詳細的資訊可以參考php手冊。

System V的共用記憶體使用量:

$key = 12345; // 共用記憶體的key
$memsize = 100; // 共用記憶體的大小,單位byte
$perm = 0666; // 共用記憶體存取權限,參考linux的許可權
$var_key = 345; // 共用記憶體的某變數的key
$shmid = shm_attach( $key, $memsize, $perm ); // 建立一個共用記憶體
shm_put_var( $shmid, $var_key, "abc" ); // 插入一個共用記憶體變數,key為$var_key,值為"abc"
shm_detach( $shmid ); // 關閉共用記憶體

運行上面的php程式將建立一個key為12345的共用記憶體,大小為100位元組,裡面有個值為”abc”的變數。我們可以在linux命令列敲入ipcs看看我們所建立的共用記憶體:

—— Shared Memory Segments ——–
key             shmid         owner          perms         bytes         nattch        status      
0×00003039      262144        daemon          666           100              0               

0×00003039就是12345的16進位形式。
我們再寫另一個訪問這個共用記憶體並刪除這個共用記憶體的php:

$shmid = shm_attach( 12345 ); // 訪問key為12345的共用記憶體
echo shm_get_var( $shmid, 345 ); // 把共用記憶體中key為345的變數列印出來,這裡將顯示abc
shm_remove( $shmid ); // 刪除該共用記憶體

運行這個php,將顯示abc,並把共用記憶體刪除,這時候再運行ipcs就可以看到那塊共用記憶體已經不存在了。

shmop的共用記憶體使用量:

$key = 12345; // 共用記憶體的key
$memsize = 100; // 共用記憶體的大小,單位byte
$perm = 0666; // 共用記憶體存取權限,參考linux的許可權
$offset = 0; // 共用記憶體位移地址,0表示共用記憶體的起始地址
$shmid = shmop_open($key, "c", $perm, $memsize); // 建立一個共用記憶體,第二個參數c表示建立
$shm_bytes_written = shmop_write($shm_id, "abc", 0); // 把"abc"寫入共用記憶體
echo $shm_bytes_written; // 列印出寫入共用記憶體的資料長度,這裡將顯示3
shmop_close($shm_id); // 關閉共用記憶體

運行這個php將建立一個key為12345,大小為100位元組的共用記憶體,裡面寫入了”abc”這個字串。
我們在寫一個訪問這個共用記憶體的php:

$shm_id = shmop_open(12345, "w", 0, 0); // 開啟key為12345的共用記憶體,第二個參數w表示以讀寫方式開啟,開啟已存在的共用記憶體,第三個和第四個參數必須是0
$shm_data = shmop_read($shm_id, 0, 3); // 從共用記憶體裡面讀取3位元組的資料,第二個參數是位移地址,0表示共用記憶體的起始地址
echo $shm_data; // 列印出上個函數返回的共用記憶體資料
shmop_delete($shm_id); // 刪除共用記憶體

運行這個php將列印出abc,並把原來的共用記憶體刪除。

總結:

這兩套函數都是簡單易用的,shmop的唯一好處是可以在windows下使用,在linux下的話本人強烈推薦使用shm_*那套函數,因為那套函數在插入、更新以及讀取共用記憶體裡面的變數相當方便,而shmop需要自己來規劃共用記憶體的儲存結構,應用起來稍微複雜一點。
此外,上面的例子裡面我直接用數字12345作為共用記憶體的key,實際上,更為標準的做法是使用ftok函數來把一個路徑轉成ipc的key。具體做法可以參考php手冊。

以上兩個方案都不是很理想.好用的那個只支援LINUX.所以我們使用第三套共用記憶體.

還有一套是我們這次要用到的是分布式緩衝系統Memcached       [key-value記憶體緩衝系統]
下面來看一下介紹吧

在PHP中使用Memcached,有兩種方式,一種是安裝PHP的memcache擴充(實際上還有另外一個memcached擴充,是基於比較流行的libmemcached庫封裝的),該擴充是用c寫的,效率較高,需要在伺服器上安裝。另外一種則是直接使用用戶端的php-memcached-client類庫,但是這個我在網上找了半天也沒找到一個官方的網站。所以呢,還是裝個擴充吧。假設php安裝在/home/admin/php目錄:

wget http://pecl.php.net/get/memcache-2.2.5.tgzgzip -d memcache-2.2.5.tgztar xvf memcache-2.2.5.tarcd memcache-2.2.5/home/admin/php/bin/phpizeConfiguring for:PHP Api Version:         20041225Zend Module Api No:      20060613Zend Extension Api No:   220060519./configure --enable-memcache --with-php-config=/home/admin/php/bin/php-config --with-zlib-dirInstalling shared extensions:     /home/admin/php/lib/php/extensions/no-debug-non-zts-20060613/

注意到最後一行返回的資訊,將下面兩行添加到/home/admin/php/lib/php.ini

extension_dir = "/home/admin/php/lib/php/extensions/no-debug-non-zts-20060613/"extension=memcache.so

然後重啟web伺服器即可。如果安裝成功,則通過phpinfo()可以獲得該擴充的相關資訊:

memcache support enabled
Active persistent connections 0
Version 2.2.5
Revision $Revision: 1.111 $
Directive Local Value Master Value
memcache.allow_failover 1 1
memcache.chunk_size 8192 8192
memcache.default_port 11211 11211
memcache.default_timeout_ms 1000 1000
memcache.hash_function crc32 crc32
memcache.hash_strategy standard standard
memcache.max_failover_attempts 20 20

以上參數都可以在php.ini中進行設定。下面是一段官方網站的php測試代碼:

<?php$memcache = new Memcache;$memcache->connect('127.0.0.1', 11211) or die ("Could not connect");$version = $memcache->getVersion();echo "Server's version: ".$version."\n";$tmp_object = new stdClass;$tmp_object->str_attr = 'test';$tmp_object->int_attr = 123;$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");echo "Store data in the cache (data will expire in 10 seconds)\n";$get_result = $memcache->get('key');echo "Data from the cache:\n";var_dump($get_result);?>

運行後輸出如下:

Server's version: 1.2.6Store data in the cache (data will expire in 10 seconds)Data from the cache: object(stdClass)#3 (2){ ["str_attr"]=>  string(4) "test" ["int_attr"]=>  int(123) }
恩,這東西可以像SESSION那樣使用,這正是我們需要的高速共用記憶體池,這東西是跨平台的.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.