Apache-2.2

在 Apache2 上的 PHP 中對多個數據庫使用 pconnect

  • March 12, 2015

我在 apache2 伺服器上的 preforked(MOD_PHP) 中執行 PHP。設置在 linux Ubuntu 10.04 上。我使用的數據庫是firebird 數據庫2.5.2。apache2 伺服器執行在一個由 8 個網路伺服器組成的網路集群中。

在某個時間點,由於對應用程序的請求激增(我們有窺視時間),我們遇到了嚴重的性能問題。瓶頸顯示為解決在很短的時間內出現的請求數量所需的數據庫連接數量。Firebird 沒有很好地處理它,請求只是超時了。

這種類型的數據庫沒有連接池,這就是為什麼我一直在 PHP 中使用 pconnect 來減輕數據庫的壓力。這會在 apache2 程序中保持數據庫連接。這是一個重大的性能提升。不利的一面是,我們必須讓 apache2 程序在輪換之前接受大量請求,並且即使沒有負載,我們也要保持大量 apache2 程序執行。每個網路伺服器執行 70 個 apache 程序。這是為了保持連接打開並準備就緒。基本上我們試圖讓 apache2 成為我們的連接池。這行得通。當使用者請求應用程序時,數據庫句柄已準備就緒,Firebird 不必擔心創建新數據庫連接的成本。

現在這是我的問題。我們現在需要有很多數據庫——小型的。但它們都將在 apache2 伺服器集群中執行。這意味著在 apache2 程序的生命週期中,它很可能會獲得與多個數據庫(可能是 80-100)的持久連接。

我擔心 apache2 將如何處理這種情況。apache2 可以處理的連接數是否有限制?它會變慢嗎..它會在記憶體中增長並完美處理所有事情嗎?

目前,數據庫分片無關緊要。我們(作為開發團隊)根本不喜歡拆分數據庫的想法。但是重寫應用程序並創建新的數據庫結構以從程式碼中獲得更多性能並沒有綠燈。就目前而言,硬體就是答案。還有一些法律問題迫使我們分成幾個數據庫來封裝數據。但這是我有點擔心 apache2 能夠處理什麼。

有人知道嗎?

首先,您應該認真考慮該設計。數據庫設計的最佳實踐是盡可能避免將數據拆分到多個數據庫中。當然,也有例外(例如,如果您需要讓客戶/應用程序修改其架構),但總的來說,在連接到多個數據庫的方向上的可擴展性很差。此外,跨數據庫查詢很難編寫、昂貴且在許多(大多數?)數據庫系統中得不到很好的支持,這迫使您做很多本可以由應用程序中的數據庫完成的工作。當數據庫和應用程序之間存在 N..N 關係時,可維護性是一場噩夢。

其次,您的解釋有點不清楚,但我想知道您如何使用您的游泳池..?通常使用 prefork 你會保留一些伺服器,以改善延遲。只要伺服器存在,​​持久連接也應該存在。pconnect 並沒有真正匯集,聽起來也不像你這樣做。你能舉一個更清楚的例子嗎?

第三,有幾種資源可以用完。文件描述符很可能會在很早的時候就出現問題,並且來自每個工作人員的許多連接會佔用 Apache 和數據庫中的記憶體。此外,即使使用連接池,建立連接也會很昂貴。如果您不能減少使用中的數據庫數量,您很可能不得不承擔使用 connect 而不是 pconnect 的成本,以減少陳舊的數據庫連接浪費的資源量。

如果有人來找我的設計需要從 Apache 工作人員連接到數百個數據庫,我會直接將它們發送回繪圖板。這樣的設計有太多的事情會出錯。合併數據庫,或者,如果不可能,則放入中間層。

編輯:好的,現在事情有點清楚了。

這部分是容量規劃問題,通常不可能提供好的答案。但是,澄清幾點。

  1. 如前所述,在嘗試建立與多個數據庫的連接時,您可能會遇到許多硬限制。文件描述符和記憶體(尤其是共享記憶體)可能是您遇到的早期限制。
  2. 您所做的並不是真正的連接池,因為持久連接永遠不會返回到池中。它只是持久連接,可以為您節省一些成本。
  3. 如果我真的必須以這種方式對數據庫進行分片(我認為這是一個非常糟糕的設計選擇),我的方法是為每個數據庫分配專用的 Apache 程序。這樣我就降低了在一個程序中積累太多持久連接的風險。據我所知,如果不安裝多個 Apache2 並根據 FQDN 拆分請求,就無法做到這一點。我會考慮的替代解決方案是消耗使用連接的成本並使用記憶體來盡量減少數據庫命中的數量,並檢查我是否不能將 Web 應用程序與數據庫混亂解耦。

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