背景介紹
使用者在利用 PHP 搭建網站時,會把一些資訊存放在 $_SESSION 全域變數裡,可以很方便的存取。在 PHP 的 ini 設定檔裡面提供了 [Session] 相關配置,可以支援將資訊存到檔案或 memcached 伺服器裡面。由配置項 session.save_handler = memcached 決定。大多數情境,該 session 資料並不需要持久化,且為了提升網站效能,會選擇將 session 資訊緩衝到 memcached 裡面。
問題
ApsaraDB for Memcache和自建的 memcached 都實現了標準 memcached 協議,使用者一方面為了減少伺服器記憶體的佔用,一方面減少對 memcached 的維護,希望將 session 的儲存從自建的 memcached 遷移到ApsaraDB for Memcache上面,且不希望改寫代碼,切換過程中遇到了問題,因此有了這篇文章,希望能幫到大家。
ApsaraDB for Memcache和自建的 memcached 最重要的區別就是“帳號密碼鑒權”:
ApsaraDB for Memcache:分布式叢集統一對外提供服務,實現了負載平衡且無單點故障,使用者可自由動態彈性調整配置且無需重啟服務。既然是對外提供服務,就有相應的安全機制,如白名單、流控、帳號密碼鑒權。
自建 memcached:因為大多數使用者自建 memcached 是不需要設定帳號密碼的,跟ApsaraDB for Memcache比就少了 SASL 鑒權流程。那麼使用者將 session 的儲存從自建的 memcached 遷移到ApsaraDB for Memcache 上面,就需要在 php.ini 中配置帳號密碼。
解決方案
在老版本的 php memcached 擴充中無法支援,需要升級 php memcached 擴充至2.2.0版本,範例程式碼如下:
wget http://pecl.php.net/get/memcached-2.2.0.tgz tar zxvf memcached-2.2.0.tgz cd memcached-2.2.0 phpize ./configure --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached-sasl make make install
找到剛升級 memcached.so,
stat
命令確定下是否更新(注意下 modify 時間)。修改 php.ini 配置。
session段:找到[Session]段落,修改儲存引擎為:
session.save_handler = memcached**(注意是帶d擴充)**
修改儲存地址,即 Memcache 訪問地址為:
session.save_path = "be6b6b8221cc11e4.m.cnhzalicm10pub001.ocs.aliyuncs.com:11211"(注意帶d擴充,則前面不用加tcp://,不帶d的擴充需要加)
修改緩衝到 memcached 的 key 的時間:
session.gc_maxlifetime = 1440(單位是秒,強烈建議必須設定一個合理時間,以保證 OCS 始終只緩衝熱點資料)
memcached 段:在 php.ini 的全域段,建一個單獨段落[memcached],然後在空白地方加入下面配置:
[memcached] memcached.use_sasl = On memcached.sess_binary = On memcached.sess_sasl_username = "your_ocs_name" memcached.sess_sasl_password = "your_ocs_password" memcached.sess_locking = Off
安裝步驟完結。上述關於 memcached 段和 Session 段其他有用參數參考連結如下:
http://php.net/manual/en/memcached.configuration.php
http://php.net/manual/en/session.configuration.php
接下來是測試是否生效。
測試
寫測試代碼如下 session.php:
<?php
session_start();
$sn = session_id();
echo "session id:".$sn."\n";
$_SESSION["ocs_key"]="session_value";
echo "session:".$_SESSION["ocs_key"]."\n";
?>
輸出如下:
session id:ttrct9coa2q62r2sodlq4qf376
session:session_value
通過測試代碼 get.php 從 Memcache 擷取剛才 session.php 寫入的 session 資料。
<?php
$memc = new Memcached();
$memc->setOption(Memcached::OPT_COMPRESSION, false);
$memc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$memc->addServer("be6b6b8221cc11e4.m.cnhzalicm10pub001.ocs.aliyuncs.com", 11211);
$memc->setSaslAuthData("your_ocs_name", "your_ocs_password");
echo $memc->get("memc.sess.key.ttrct9coa2q62r2sodlq4qf376");
/*注意這裡的key是有首碼的,由php.ini中memcached.sess_prefix欄位決定,預設值為"memc.sess.key."。然後再拼接上面打出來的sessionid“ttrct9coa2q62r2sodlq4qf376”即可。*/
?>
該代碼輸出如下:
ocs_key|s:13:"session_value";
即 PHP SESSION 已經成功寫入 Memcache。