Php

可以使用 memcache 守護程序池更有效地共享會話嗎?

  • January 27, 2015

我們正在從 1 個網路伺服器設置轉移到兩個網路伺服器設置,我需要開始在兩台負載平衡機器之間共享 PHP 會話。我們已經安裝(並啟動)了memcached,所以我很驚訝我可以通過僅更改文件中的 3 行(session.save_handlersession.save_path)來完成新伺服器之間的共享會話:php.ini

我更換了:

session.save_handler = files

和:

session.save_handler = memcache

然後在主網路伺服器上,我將其設置session.save_path為指向 localhost:

session.save_path="tcp://localhost:11211"

在從屬網路伺服器上,我將session.save_path指向主伺服器:

session.save_path="tcp://192.168.0.1:11211"

工作完成,我測試了它並且它有效。但…

顯然,使用 memcache 意味著會話在 RAM 中,如果機器重新啟動或 memcache 守護程序崩潰,會話將失去 - 我對此有點擔心,但我更擔心兩個網路伺服器之間的網路流量(尤其是我們擴大規模)因為每當有人對從屬網路伺服器進行負載平衡時,他們的會話將通過網路從主網路伺服器獲取。我想知道是否可以定義兩個save_paths,以便機器在使用網路之前查看自己的會話儲存。例如:

掌握:

session.save_path="tcp://localhost:11211, tcp://192.168.0.2:11211"

奴隸:

session.save_path="tcp://localhost:11211, tcp://192.168.0.1:11211"

*這會成功地在伺服器之間共享會話並提高性能嗎?*即節省 50% 的網路流量。還是這種技術僅適用於故障轉移(例如,當一個記憶體記憶體守護程序無法訪問時)?

注意:我並不是真的特別詢問 memcache 複製 - 更多關於 PHP memcache 客戶端是否可以在池中的每個 memcache 守護程序內達到峰值,如果找到一個會話,則返回一個會話,如果找不到,則只創建一個新會話在所有商店。當我寫這篇文章時,我想我對 PHP 的要求有點高,哈哈……

假設:沒有粘性會話、循環負載平衡、LAMP 伺服器。

免責聲明:如果沒有進行大量測試並從合格的人那裡獲得第二意見,你會很生氣 - 我是這個遊戲的新手

本題提出的效率提升構想是行不通的。我犯的主要錯誤是認為 memcached 儲存在池中的定義順序決定了某種優先級。事實並非如此。當您定義一個 memached 守護程序池(例如 using session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211")時,您不知道將使用哪個儲存。數據是均勻分佈的,這意味著一個項目可能儲存在第一個,也可能是最後一個(或者如果 memcache 客戶端配置為複制,則可能兩者都儲存 - 注意它是處理複製的客戶端,memcached 伺服器會不要自己做)。無論哪種方式都意味著使用 localhost 作為池中的第一個不會提高性能 - 有 50% 的機會訪問任一儲存。

經過一些測試和研究,我得出結論,您可以使用 memcache 在伺服器之間共享會話,但您可能不想這樣做 - 它似乎並不流行,因為它的擴展性不如使用共享它的數據庫沒有那麼健壯。我很感激對此的回饋,以便我可以了解更多…

除非您有 PHP 應用程序,否則請忽略以下內容:


提示 1:如果您想使用 memcache 在 2 個伺服器之間共享會話:

當您安裝 PHP 記憶體記憶體客戶端並在文件中添加以下內容時,確保您對“啟用記憶體記憶體會話處理程序支持? ”回答**“是**” :/etc/php.d/memcache.ini

session.save_handler = memcache

在網路伺服器 1(IP:192.168.0.1)上:

session.save_path="tcp://192.168.0.1:11211"

在網路伺服器 2(IP:192.168.0.2)上:

session.save_path="tcp://192.168.0.1:11211"

提示 2:如果您想使用 memcache 在 2 個伺服器之間共享會話並具有故障轉移支持:

將以下內容添加到您的/etc/php.d/memcache.ini文件中:

memcache.hash_strategy = consistent
memcache.allow_failover = 1

在網路伺服器 1(IP:192.168.0.1)上:

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

在網路伺服器 2(IP:192.168.0.2)上:

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

筆記:

  • 這突出了我在原始問題中犯的另一個錯誤——我沒有session.save_path在所有伺服器上使用相同的。
  • 在這種情況下,“故障轉移”意味著如果一個 memcache 守護程序失敗,PHP memcache 客戶端將開始使用另一個。即,任何在商店中的會話失敗的人都將被註銷。它不是透明的故障轉移。

提示 3:如果您想使用 memcache 共享會話並具有透明的故障轉移支持:

與技巧 2 相同,但您需要將以下內容添加到/etc/php.d/memcache.ini文件中:

memcache.session_redundancy=2

筆記:

  • 這使得 PHP memcache 客戶端將會話寫入 2 個伺服器。您獲得冗餘(如 RAID-1),以便將寫入發送到 n 個鏡像,並get's在鏡像上重試失敗。這意味著使用者不會在一個 memcache 守護程序失敗的情況下失去他們的會話。

  • 鏡像寫入是並行完成的(使用非阻塞 IO),因此速度性能不會隨著鏡像數量的增加而下降太多。但是,如果您的 memcache 鏡像分佈在不同的機器上,網路流量將會增加。例如,不再有 50% 的機會使用 localhost 並避免網路訪問。

    • 顯然,寫入複製的延遲可能會導致檢索舊數據而不是記憶體未命中。問題是這對您的應用程序是否重要?您多久編寫一次會話數據?
  • memcache.session_redundancy用於會話冗餘,但memcache.redundancy如果您希望它具有不同級別的冗餘,您的 PHP 應用程式碼也可以使用一個 ini 選項。

  • 您需要PHP 記憶體記憶體客戶端的最新版本(此時仍處於測試階段) - pecl 的 3.0.3 版本為我工作。

引用自:https://serverfault.com/questions/164350