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

讓php或httpd服務來使用memcached存儲session數據

save 數組 測試 保存數據 emctl cape 包含 無法 global

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終端

[root@localhost ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is ‘^]‘.

在memcached中添加一個key

[root@nfs1 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進行安裝

[root@localhost ~]# 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命令來查看數據文件內容,內容中包含數據過期的時間戳

[root@localhost ~]# 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
[root@localhost ~]# cat data.txt 
add k2 1 1541597693 3 ? ? ? ? ? ? ? ? ?  k1值是1類型、過期時間戳、k1的數值字段長度
233
add k1 1 1541642057 6
222333

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

[root@localhost ~]# systemctl restart memcached.service
[root@localhost ~]# 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命令又生成了一個沒有過期的時間戳,來替換備份數據文件中保存的時間戳

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

再次重新導入數據
登錄到memcached輸入終端裏後可以查看到恢復的key值

[root@localhost ~]# nc 127.0.0.1 11211 < data.txt
STORED
STORED
[root@localhost ~]# 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的模塊

[root@nfs1 php-5.6.37]# cd /usr/local/src/
[root@nfs1 src]# wget http://www.biliboy.com/bbs/data/attachment/forum/memcache-2.2.3.tgz
-------------------省略----------地址可能失效,如果失效請自行尋找memcache的模塊
[root@nfs1 src]# tar zxf memcache-2.2.3.tgz 
[root@nfs1 src]# cd memcache-2.2.3
[root@nfs1 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來編譯新功能模塊

[root@nfs1 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
-------------------------------------省略
[root@nfs1 memcache-2.2.3]# make 
[root@nfs1 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區域下,方便統一格式

[root@nfs1 etc]# vim php.ini 
;extension=php_shmop.dll
extension="memcache.so"

使用php-fpm來查看已經安裝的擴展模塊

[root@nfs1 etc]# /usr/local/php-fpm/sbin/php-fpm -m | grep memcache
memcache

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

[root@nfs1 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頁面放入某個虛擬主機下,在瀏覽器中訪問同樣可以看到效果

[root@nfs1 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存儲指向的地址

[root@nfs1 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的數據存儲內容

[root@localhost~ ]# curl localhost/1.php ? ? ? ?
1541759135<>br<br>1541759135<>br<br>mjrbq0hg45dd89ttdd32bjgue9
[root@localhost~ ]# 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數據

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

讓php或httpd服務來使用memcached存儲session數據