1. 程式人生 > >讓php或httpd服務來使用memcached儲存session資料

讓php或httpd服務來使用memcached儲存session資料

memcached命令列

memcached語法

<command name> <key> <flags> <exptime> <bytes>\r\n <data block>\r\n注:  \r\n在windows下是Enter鍵
<command name>可以是set, add, replace
set           表示按照相應的<key>儲存該資料,  沒有的時候增加,  有的時候覆蓋
add          表示按照相應的<key>新增該資料,但是如果該<key>已經存在則會操作失敗
replace    表示按照相應的<key>替換資料,但是如果該<key>不存在則操作失敗。
<key>客戶端需要儲存資料的key語法
<flags>是一個16位的無符號的整數(以十進位制的方式表示)。該標誌將和需要儲存的資料一起儲存,並在客戶端get資料時返回。
客戶端可以將此標誌用做特殊用途,此標誌對伺服器來說是不透明的。. <exptime>為過期的時間。
若為0表示儲存的資料永遠不過期(但可被伺服器演算法:LRU等替換)。
如果非0(unix時間或者距離此時的秒數),當過期後,伺服器可以保證使用者得不到該資料(以伺服器時間為標準)。
<bytes>需要儲存的位元組數,當用戶希望儲存空資料時<bytes>可以為0. <data block>需要儲存的內容,輸入完成後,最後客戶端需要加上\r\n(直接點選Enter) 作為結束標誌。

安裝登入memcached的telnet命令
yum install telnet
使用telnet登入memcached終端

[[email protected] ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

在memcached中新增一個key

[[email protected] src]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set key1 0 200 2
ab
STORED

值其中第一個數值一個特殊標記位的符號,用於客戶端特殊用途的使用,此標誌對伺服器來說是不透明的
第二個表示為過期時間,過了多少秒後該key值過期被伺服器釋放,若為0則表示儲存資料永不過期(但可以被伺服器演算法:LRU等替換)。如果非0(unix的時間或距離此時的秒數),當過期時間後,伺服器可以保證使用者得不到該資料(以伺服器時間為第一標準)
第三段儲存的是內容位元組,當用戶希望儲存的資料為空時可以為0,當輸入完成後,最後客戶端需要加上\r或\n表示結束標誌(直接Enter回車)

定義一個key值,並查詢其經過30秒後的值,檢視其值是否還存在

set key2 0 30 3                  建立key2值,設定為30秒過期
abc
STORED
get key2
VALUE key2 0 3                  get檢視key的值
abc
END
get key2                        經過30秒後,再次檢視key2的值,發現數據已經過期
END

更改一個存在的key值並檢視該值資料

set key2 0 0 5                  建立key2值,設定為永不過期
abcde 
STORED
get key2                        檢視key2值
VALUE key2 0 5
abcde
END
replace key2 1 200 2            變更key2的值,設定為200秒過期
22
STORED
get key2                        get檢視key值變化
VALUE key2 1 2
22
END
get key2                        經過200秒後,再次查詢key2,發現數據已經過期
END

定義一個key1的值並刪除它

set key1 0 2000 3          建立key1值,2000秒過期時間
123
STORED
get key1                   檢視key1的值
VALUE key1 0 3
123
END
delete key1                刪除key1
DELETED
get key1                   再次get key1發現沒有數值內容
END

在memcached輸入行內按ctrl+ ]  及quit來退出輸入終端
 

memcached資料匯出和匯入

記錄資料過期的時間戳
memcached匯出的資料都是帶有一個時間戳的,這個時間戳是資料過期的時間點,如果當前時間已經超過了該記錄的時間戳,那麼該條資料即使匯入到memcached中也會被過期
匯出memcached資料
首先在memcached輸入終端內建立幾個測試資料

set k1 1 48000 6       k1值過48000秒過期
222333
STORED
get k1
VALUE k1 1 6           檢視k1內容
222333
END
set k2 1 3600 3        k2值過3600秒過期
233
STORED
get k2                 檢視k2的值
VALUE k2 1 3
233
END
^]                    ctrl+]退出
telnet> quit
Connection closed.

使用memcached-tool命令檢視及匯出memcache的資料
如果沒有這個命令,則需要使用yum進行安裝

[[email protected] ~]# memcached-tool 127.0.0.1:11211 dump
Dumping memcache contents
  Number of buckets: 1
  Number of items : 2
Dumping bucket 1 - 2 total items
add k2 1 1541597693 3
233
add k1 1 1541642057 6
222333

將memcache資料匯出到檔案中
匯出後可以使用cat命令來檢視資料檔案內容,內容中包含資料過期的時間戳

[[email protected] ~]# memcached-tool 127.0.0.1 dump > data.txt
Dumping memcache contents
  Number of buckets: 1
  Number of items : 2
Dumping bucket 1 - 2 total items
[[email protected] ~]# cat data.txt 
add k2 1 1541597693 3                    k1值是1型別、過期時間戳、k1的數值欄位長度
233
add k1 1 1541642057 6
222333

匯出資料後我們可以重啟memcached服務,來讓memcached中的資料都清空,以便讓我們把備份資料匯入進去
重啟後memcached資料為0

[[email protected] ~]# systemctl restart memcached.service
[[email protected] ~]# memcached-tool 127.0.0.1:11211 dump
Dumping memcache contents
  Number of buckets: 0
  Number of items : 

使用nc命令工具匯入資料
若該命令不存在,則需要使用yum安裝:yum install -y nc
以上使用memcached-tool查看了當前的資料都為空,那麼我們需要使用nc命令將備份資料恢復到memcached當中,如果當前系統時間已經超過了某條資料記錄的時間戳,那麼在匯入整個備份後,這條資料也會被過期
因為我備份資料時的時間戳在匯出時發生過期,這裡我使用date命令又生成了一個沒有過期的時間戳,來替換備份資料檔案中儲存的時間戳

[[email protected] ~]# date -d "+1 day" +%s
1541752940
[[email protected] ~]# vim data.txt 
add k2 1 1541752940 3
233
add k1 1 1541752940 6
222333

再次重新匯入資料
登入到memcached輸入終端裡後可以檢視到恢復的key值

[[email protected] ~]# nc 127.0.0.1 11211 < data.txt
STORED
STORED
[[email protected] ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get k1
VALUE k1 1 6
222333
END
get k2
VALUE k2 1 3
233
END

注意:如果在memcached中定義一個key為永不過期的設定後,在備份時則會改變該設定,會將永不過期的時間戳更換為備份資料那一刻的時間戳來儲存。如果這樣的話,那我們在恢復備份的資料時那些永不過期的資料則不會從備份恢復到memcached資料庫內

php連結memcached

讓php能夠連結使用memcached,我們需要向php中編譯memcached的模組,這樣php才能夠支援向memcached中寫入資料
首先我們需要下載memcached的模組

[[email protected] php-5.6.37]# cd /usr/local/src/
[[email protected] src]# wget http://www.biliboy.com/bbs/data/attachment/forum/memcache-2.2.3.tgz
-------------------省略----------地址可能失效,如果失效請自行尋找memcache的模組
[[email protected] src]# tar zxf memcache-2.2.3.tgz 
[[email protected] src]# cd memcache-2.2.3
[[email protected] memcache-2.2.3]# /usr/local/php-fpm/bin/phpize             
Configuring for:                                          -------------使用phpize檔案來生成編譯檔案
PHP Api Version: 20160303
Zend Module Api No: 20160303
Zend Extension Api No: 320160303

生成編譯檔案後,在下載解壓的模組目錄下執行./configure來編譯新功能模組

[[email protected] memcache-2.2.3]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
checking for grep that handles long lines and -e... /usr/bin/grep
-------------------------------------省略
[[email protected] memcache-2.2.3]# make 
[[email protected] memcache-2.2.3]# make install

如果編譯中有報錯(我的php是7.0以上版本,對某些擴充套件的相容性不太友好):
如果出現以下錯誤,建議更換成php7正式穩定版,或者給php降級(安裝php5版本)

/usr/local/src/memcache-2.2.3/memcache.c:40:40: fatal error: ext/standard/php_smart_str.h: No such file or directory
 #include "ext/standard/php_smart_str.h"
                                        ^
compilation terminated.
make: *** [memcache.lo] Error 1

安裝完成後會有如下的類似提示:
memcached的擴充套件模組會儲存在該目錄下
Installing shared extensions:/usr/local/php-fpm/php/extensions/no-debug-non-zts-20131226/
然後我們需要在php.ini的檔案中新增memcached的支援,一般將新擴充套件加入extension區域下,方便統一格式

[[email protected] etc]# vim php.ini 
;extension=php_shmop.dll
extension="memcache.so"

使用php-fpm來檢視已經安裝的擴充套件模組

[[email protected] etc]# /usr/local/php-fpm/sbin/php-fpm -m | grep memcache
memcache

測試php是否能夠正常使用memcached儲存資料,這裡使用到一個php頁面來解析

[[email protected] src]# cat 1.php 
<?php
//連線Memcache Memcache
$mem = new Memcache;
$mem->connect("localhost", 11211);
//儲存資料
$mem->set('key1', 'This is first value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val ."<br>";
//替換資料
$mem->replace('key1', 'This is replace value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br>";
//儲存陣列資料
$arr = array('aaa', 'bbb', 'ccc', 'ddd');
$mem->set('key2', $arr, 0, 60);
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br>";
//刪除資料
$mem->delete('key1');
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br>";
//清除所有資料
$mem->flush();
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br>";
//關閉連線
$mem->close();
?>

執行php頁面來檢視測試效果,或者將該php頁面放入某個虛擬主機下,在瀏覽器中訪問同樣可以看到效果

[[email protected] src]# /usr/local/php-fpm/bin/php 1.php 
Get key1 value: The is first value<br>Get key1 value: This is replace value<br>Get key2 value: Arreay
(
    [0] => aaa
    [1] => bbb
    [2] => ccc
    [3] => ddd
)

如果解析出來的反饋結果跟以上相同,那麼即php能夠正確的連結memcached資料庫了

memcached中儲存session

應用場景
在一個多web伺服器的環境下,使用者訪問一個網站時是需要登入的,如果發生訪問負載分發,那麼會將使用者已登入狀態的訪問從A伺服器分發到B伺服器,結果就是使用者的登入狀態被退出了,這樣的話,使用者每點選(重新整理)一次頁面,訪問請求就會被分發到一臺新的伺服器上。這樣的話使用者就無法正常登入網站
注意一:
這裡的配置:
nginx是192.168.1.234,php192.168.1.115,memcached也是192.168.1.115。如果是實際環境中,memcached可以不和任意的其他服務部署在一起,但是php伺服器上必須安裝memcached的擴充套件,因為想要和memcached通訊的話就需要使用到這個擴充套件模組。多臺php或者web(httpd)可以指向一臺memcached來儲存session資料
注意二:
nginx可以通過設定將session儲存到memcached當中
php也可以通過設定將session存到memcached中。但是這裡的驗證出現問題
如果使用的是apache的httpd,也可以通過同樣的配置來設定

本例項是在lnmp環境下實現編輯php.ini新增兩行
但在php.ini中新增memcached快取的配置會發生無法儲存的情況,這裡放棄在php.ini中配置memcached的設定了
session.save_path是指定了memcached伺服器ip及埠的配置項

session.save_handler = memcache
session.save_path = "tcp://192.168.1.115:11211"

或者httpd.conf中對應的虛擬主機中新增

php_value_session.save_handler "memcache"
php_value_session.save_path "tcp://192.168.1.115:11211"

或者php- fpm. conf對應的pool中新增

php_value[session.save_handler] = memcache
php_value[session.save_path] = " tcp://192.168.1.115:11211 "

這裡在php的pool池中來設定的memcache儲存指向的地址

[[email protected] src]# vim /usr/local/php-fpm/etc/php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[web]
listen = 192.168.1.115:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
php_admin_value[post_max_size] = 32M
php_admin_value[max_execution_time] = 300
php_admin_value[date.timezone] = 'Asia/Shanghai'
php_value[session.save_handler] = memcache
php_value[session.save_path] = " tcp://192.168.1.115:11211 "

在nginx本地來驗證memcached的資料儲存內容

[[email protected]~ ]# curl localhost/1.php        
1541759135<>br<br>1541759135<>br<br>mjrbq0hg45dd89ttdd32bjgue9
[[email protected]~ ]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get mjrbq0hg45dd89ttdd32bjgue9
VALUE mjrbq0hg45dd89ttdd32bjgue9
TEST|i:1541759135;TEST3|i:1541759135;
END

通過解析php頁面,可以從驗證結果中的到了儲存的session資料

以上是個人學習中的見解,如有錯誤,歡迎各位請多多指教