2008-11-07 75 views
10

什麼是最好的方法來設置相對於您的池: -你如何設置連接池?

  1. 當你創建連接?
  2. 什麼時候關閉連接,你會關閉所有連接嗎?
  3. 你測試連接還是不錯的。何時以及如何?
  4. 你如何找出最大連接數的好數字?
  5. 您有什麼樣的監控來確保游泳池的用戶表現良好?你能阻止一個糟糕的代碼塊取出所有東西嗎?
  6. 您是否編寫了自己的游泳池或使用了第三方庫?

我相信這是一個不可知論的問題,但對特定數據庫/語言的「特性」的評論是值得歡迎的。例如,連接某些數據庫比其他數據庫更慢或更昂貴。

爲了澄清,我不打算從頭開始編寫一個池,這個問題更多的是關於如何配置一個現有的庫進行池化。

回答

6

我在Java中爲數據庫寫了一個連接池,它只是一個設計模式,而不是一個公共庫。現在我使用Tomcat中內置的一個。

我用了一個線程來監視池的幾個方面和幾個參數來控制其行爲......

  1. minimumInPool =「3」 ......這些前三個一經推出創建。游泳池從不允許降到三點以下。
  2. maximumIdleTimeBeforeRemoval =「60」...如果連接閒置一個小時,然後放下並創建一個新連接。空閒時間可能意味着池中只有最少三個。
  3. maximumInUseTimeBeforeRemoval =「30」...如果給定的連接已被檢出超過30分鐘,則可能是錯誤的。回想一下,並殺死連接。
  4. maximumTimeBeforeRemoval =「60」...如果超過60分鐘,請將其刪除。
  5. maximumUsageBeforeRemoval =「1000」...如果已經簽出1000次以上,請將其刪除。
  6. monitorInterval =「15」...每15分鐘檢查一次上述參數。

這給了我很多好幾年。在野外偷看期間,我見過的最高水池有151個。通常情況下,游泳池在大量使用過程中大約有十幾個,在清晨時間裏至少有三個空閒。

我使用了Oracle的JDBC瘦驅動程序並連接到Oracle數據庫。

1

爲什麼重新發明車輪?

有人已經可能解決了這個問題,而且更好。

如果您處於Java世界,您可以使用Commons DBCP

3

這是我用於最近實施的基本原理。

  1. 在連接池中有兩種連接。第一個準備就緒,意味着開放但客戶端不使用。第二個是積極的,意味着由客戶使用。

  2. 您的連接池是否保持少量的就緒連接,最少爲N,最大爲M.根據客戶端請求連接的最高速度,可以調整N。如果就緒連接的數量降至零,則需要更大的N.如果該數字一直很高(例如高於10),則需要較低的N.當客戶端想要連接時,給它們一個(準備工作),然後立即打開一個新的工作,如果現在還沒有準備好(但不要讓客戶等待這個完成,否則你將失去合併的優勢)。這確保了總是有至少N個準備就緒的連接。如果沒有人準備好當客戶想要一個,他們將不得不等待,而你創建一個新的。

  3. 當客戶端連接到活動連接時,如果M連接少於M個,則返回到就緒狀態。否則關閉它。這可以防止您有超過M個就緒連接。

  4. 定期回收準備好的連接以防止過時的連接。如果有超過N個就緒連接,請關閉最舊的連接。否則關閉它並重新打開另一個。

這具有足夠的,而不會加重服務器的連接池中的可用準備青春連接的優勢。

2

我不確定你使用你的連接的上下文是什麼,但我可以分享似乎爲我工作的內容。

我使用SQL服務器作爲我的後端,並結合使用緩存來獲得更好的性能。 我的做法是保持連接打開,只有當我真的需要它並且不要連接池以便它們立即清理時,我可以在SQL Activity監視器中看到究竟什麼是活動的,哪些不是。每個連接都會佔用內存,因此在不需要時將其保持沉悶的咆哮是很好的。

在我回答連接開放和關閉問題之前,讓我說緩存是非常重要的。從緩存中獲取對象將爲您節省大量時間。在我開發的一些asp.net應用程序中,當我在開發中進行緩存時,我發現我幾乎無法測量延遲,而使用數據庫調用可能需要15ms到45ms的任何時間來完成調用,這甚至不考慮其他延遲因素或負荷。我使用的另一種方法是用於我的數據的一種很好的對象結構,這樣我只在數據庫更新時才進行更新。我在我的對象上實現了一些方法o確保我儘可能少做IO。

話雖這麼說,我們都知道,我們需要訪問並在某些時候寫信給我們的數據庫,所以我遵循兩個原則:

  1. 保持關閉,以節省能源的門窗。一個地方的開放連接意味着它在另一個地方不可用(或者內存和其他資源更有限)。我們已經關閉了,因爲它爲我們帶來了更好的表現。

  2. 我可以在連接打開的情況下儘可能批量或一次性完成。這有點複雜,所以讓我解釋一下。

    • 我使用的一種方法是將我的連接對象向下傳遞給管道,以便所有對象都可以使用一個連接對象。這會導致一個連接打開和關閉,而不是10個或更多,具體取決於您的應用程序。一個很好的例子就是我們的採購模式之一,它利用SQL服務器的強大功能來收集統計數據並散列出複雜的排序模式。當您進行200K + DB查找或任何應用程序的查找時,繼續打開和關閉連接是沒有意義的。另一部分是,當我使用對象時,我嘗試捆綁更新以減少保持連接打開的時間。因此,對插入調用做一個scope_identity讓我來處理我的插入和查找唯一標識以在緩存之前添加到對象中。 回到剛開始開發asp應用程序的那一天,我實際上在頁面開始加載後立即打開連接,然後關閉它。我不建議再這樣做。現在每天對這些抽象和層次都有很大的好處,我會建議任何新手程序員仔細關注。

我的兩分錢:

緩存您的數據!緩存你的數據!緩存你的數據!在無法緩存並緩存數據時儘可能少地訪問數據庫!

2

的Jakarta Commons DBCP已做了你列出的所有東西:

  • 它創建連接,根據需要和管理他們在一個池
  • ,如果他們沒有被用來在一定時間內可以關閉連接的時間
  • 它可以在交出之前在連接上執行查詢,如果發生錯誤,則連接被丟棄並創建一個新連接。連接也可以在空閒時定期測試。
  • 您可以對將要創建的連接以及準備好的最小連接數量設置限制。當然,這個限制很大程度上取決於你的應用程序。
  • 我不知道如何,但DBCP知道連接沒有關閉,並關閉它,拋出一個異常,以便當你看到你的日誌時知道發生了什麼。
  • DBCP有一個非常有用的超時參數。如果正在使用池中的所有連接,則將等待該連接返回到該池的時間段,並且如果在達到限制時沒有任何可用連接,則會出現錯誤。

您可以通過播放最少的連接數,要創建的最大連接數以及超時時間來優化遊戲池。更長的超時時間將允許您具有較低的連接限制,而較短的超時時間可能需要較大的數量。這在很大程度上取決於您的應用程序的功能以及它如何使用連接。

2

我同意馬特b,我們不應該重新發明車輪。

但是,根據thisthis問題的答案,使用Commons DBCP是有爭議的。 還有更好的替代方案,如c3poproxool

或者您可以使用rdbms依賴連接池機制。